From 68de25562a83fd144aff384422b68e602d91a648 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 28 May 2023 17:25:30 +0100 Subject: [PATCH] Removed last possible usages of Graphics.frame_rate and Graphics.frame_count, improved screen scrolling code, player now animates walking into a wall --- Data/Scripts/001_Technical/006_RPG_Sprite.rb | 85 +-- .../001_Technical/007_Interpolators.rb | 2 +- .../002_Save data/004_Game_SaveValues.rb | 17 +- .../002_Save data/005_Game_SaveConversions.rb | 12 +- .../004_Interpreter_Commands.rb | 2 +- .../004_Game classes/001_Game_Screen.rb | 45 +- Data/Scripts/004_Game classes/004_Game_Map.rb | 135 +++- ...e_MapFactory.rb => 005_Game_MapFactory.rb} | 0 .../005_Game_Map_Autoscroll.rb | 189 ----- ...ame_Character.rb => 006_Game_Character.rb} | 8 +- .../{008_Game_Event.rb => 007_Game_Event.rb} | 0 ...{009_Game_Player.rb => 008_Game_Player.rb} | 34 +- ...CommonEvent.rb => 009_Game_CommonEvent.rb} | 0 ..._Game_Follower.rb => 010_Game_Follower.rb} | 0 ...Factory.rb => 011_Game_FollowerFactory.rb} | 0 .../{013_Game_Stats.rb => 012_Game_Stats.rb} | 9 +- .../005_Sprites/004_Sprite_Reflection.rb | 3 +- .../007_Objects and windows/003_Window.rb | 2 +- .../004_SpriteWindow.rb | 2 +- .../005_SpriteWindow_text.rb | 45 +- .../007_Objects and windows/011_Messages.rb | 59 +- .../012_Overworld/004_Overworld_FieldMoves.rb | 79 +-- .../004_UI_Evolution.rb | 649 ++++-------------- .../006_UI_HallOfFame.rb | 116 ++-- Data/Scripts/016_UI/004_UI_Pokedex_Entry.rb | 8 +- Data/Scripts/016_UI/017_UI_PokemonStorage.rb | 250 ++++--- Data/Scripts/016_UI/025_UI_TextEntry.rb | 16 +- 27 files changed, 643 insertions(+), 1124 deletions(-) rename Data/Scripts/004_Game classes/{006_Game_MapFactory.rb => 005_Game_MapFactory.rb} (100%) delete mode 100644 Data/Scripts/004_Game classes/005_Game_Map_Autoscroll.rb rename Data/Scripts/004_Game classes/{007_Game_Character.rb => 006_Game_Character.rb} (99%) rename Data/Scripts/004_Game classes/{008_Game_Event.rb => 007_Game_Event.rb} (100%) rename Data/Scripts/004_Game classes/{009_Game_Player.rb => 008_Game_Player.rb} (96%) rename Data/Scripts/004_Game classes/{010_Game_CommonEvent.rb => 009_Game_CommonEvent.rb} (100%) rename Data/Scripts/004_Game classes/{011_Game_Follower.rb => 010_Game_Follower.rb} (100%) rename Data/Scripts/004_Game classes/{012_Game_FollowerFactory.rb => 011_Game_FollowerFactory.rb} (100%) rename Data/Scripts/004_Game classes/{013_Game_Stats.rb => 012_Game_Stats.rb} (95%) diff --git a/Data/Scripts/001_Technical/006_RPG_Sprite.rb b/Data/Scripts/001_Technical/006_RPG_Sprite.rb index 932b60408..3522328de 100644 --- a/Data/Scripts/001_Technical/006_RPG_Sprite.rb +++ b/Data/Scripts/001_Technical/006_RPG_Sprite.rb @@ -35,11 +35,13 @@ class SpriteAnimation @_animation_hit = hit @_animation_height = height @_animation_duration = @_animation.frame_max + @_animation_index = 0 fr = 20 if @_animation.name[/\[\s*(\d+?)\s*\]\s*$/] fr = $~[1].to_i end - @_animation_frame_skip = Graphics.frame_rate / fr + @_animation_time_per_frame = 1.0 / fr + @_animation_timer_start = System.uptime animation_name = @_animation.animation_name animation_hue = @_animation.animation_hue bitmap = pbGetAnimation(animation_name, animation_hue) @@ -66,12 +68,14 @@ class SpriteAnimation dispose_loop_animation @_loop_animation = animation return if @_loop_animation.nil? + @_loop_animation_duration = @_animation.frame_max @_loop_animation_index = 0 fr = 20 if @_animation.name[/\[\s*(\d+?)\s*\]\s*$/] fr = $~[1].to_i end - @_loop_animation_frame_skip = Graphics.frame_rate / fr + @_loop_animation_time_per_frame = 1.0 / fr + @_loop_animation_timer_start = System.uptime animation_name = @_loop_animation.animation_name animation_hue = @_loop_animation.animation_hue bitmap = pbGetAnimation(animation_name, animation_hue) @@ -100,6 +104,7 @@ class SpriteAnimation @_animation_sprites.each { |s| s.dispose } @_animation_sprites = nil @_animation = nil + @_animation_duration = 0 end def dispose_loop_animation @@ -123,30 +128,19 @@ class SpriteAnimation end def update - if @_animation - quick_update = true - if Graphics.frame_count % @_animation_frame_skip == 0 - @_animation_duration -= 1 - quick_update = false - end - update_animation(quick_update) - end - if @_loop_animation - quick_update = (Graphics.frame_count % @_loop_animation_frame_skip != 0) - update_loop_animation(quick_update) - if !quick_update - @_loop_animation_index += 1 - @_loop_animation_index %= @_loop_animation.frame_max - end - end + update_animation if @_animation + update_loop_animation if @_loop_animation end - def update_animation(quick_update = false) - if @_animation_duration <= 0 + def update_animation + new_index = ((System.uptime - @_animation_timer_start) / @_animation_time_per_frame).to_i + if new_index >= @_animation_duration dispose_animation return end - frame_index = @_animation.frame_max - @_animation_duration + quick_update = (@_animation_index == new_index) + @_animation_index = new_index + frame_index = @_animation_index cell_data = @_animation.frames[frame_index].cell_data position = @_animation.position animation_set_sprites(@_animation_sprites, cell_data, position, quick_update) @@ -158,6 +152,10 @@ class SpriteAnimation end def update_loop_animation(quick_update = false) + new_index = ((System.uptime - @_loop_animation_timer_start) / @_loop_animation_time_per_frame).to_i + new_index %= @_loop_animation_duration + quick_update = (@_loop_animation_index == new_index) + @_loop_animation_index = new_index frame_index = @_loop_animation_index cell_data = @_loop_animation.frames[frame_index].cell_data position = @_loop_animation.position @@ -268,6 +266,7 @@ module RPG @_collapse_duration = 0 @_damage_duration = 0 @_animation_duration = 0 + @_animation_frame = 0 @_blink = false @animations = [] @loopAnimations = [] @@ -387,16 +386,12 @@ module RPG end def dispose_animation - @animations.each do |a| - a&.dispose_animation - end + @animations.each { |a| a&.dispose_animation } @animations.clear end def dispose_loop_animation - @loopAnimations.each do |a| - a&.dispose_loop_animation - end + @loopAnimations.each { |a| a&.dispose_loop_animation } @loopAnimations.clear end @@ -422,9 +417,7 @@ module RPG return true if @_escape_duration > 0 return true if @_collapse_duration > 0 return true if @_damage_duration > 0 - @animations.each do |a| - return true if a.effect? - end + @animations.each { |a| return true if a.effect? } return false end @@ -461,12 +454,8 @@ module RPG @_damage_sprite.opacity = 256 - ((12 - @_damage_duration) * 32) dispose_damage if @_damage_duration == 0 end - @animations.each do |a| - a.update - end - @loopAnimations.each do |a| - a.update - end + @animations.each { |a| a.update } + @loopAnimations.each { |a| a.update } if @_blink @_blink_count = (@_blink_count + 1) % 32 if @_blink_count < 16 @@ -480,34 +469,22 @@ module RPG end def update_animation - @animations.each do |a| - a.update_animation if a&.active? - end + @animations.each { |a| a.update_animation if a&.active? } end def update_loop_animation - @loopAnimations.each do |a| - a.update_loop_animation if a&.active? - end + @loopAnimations.each { |a| a.update_loop_animation if a&.active? } end def x=(x) - @animations.each do |a| - a.x = x if a - end - @loopAnimations.each do |a| - a.x = x if a - end + @animations.each { |a| a.x = x if a } + @loopAnimations.each { |a| a.x = x if a } super end def y=(y) - @animations.each do |a| - a.y = y if a - end - @loopAnimations.each do |a| - a.y = y if a - end + @animations.each { |a| a.y = y if a } + @loopAnimations.each { |a| a.y = y if a } super end end diff --git a/Data/Scripts/001_Technical/007_Interpolators.rb b/Data/Scripts/001_Technical/007_Interpolators.rb index 7688871b0..211135634 100644 --- a/Data/Scripts/001_Technical/007_Interpolators.rb +++ b/Data/Scripts/001_Technical/007_Interpolators.rb @@ -8,7 +8,7 @@ def lerp(start_val, end_val, duration, delta, now = nil) delta = now - delta if now return start_val if delta <= 0 return end_val if delta >= duration - return start_val + (end_val - start_val) * delta / duration + return start_val + (end_val - start_val) * delta / duration.to_f end #=============================================================================== diff --git a/Data/Scripts/002_Save data/004_Game_SaveValues.rb b/Data/Scripts/002_Save data/004_Game_SaveValues.rb index 33058998a..30d41c45e 100644 --- a/Data/Scripts/002_Save data/004_Game_SaveValues.rb +++ b/Data/Scripts/002_Save data/004_Game_SaveValues.rb @@ -5,15 +5,15 @@ SaveData.register(:player) do save_value { $player } load_value { |value| $player = value } new_game_value { Player.new("Unnamed", GameData::TrainerType.keys.first) } - from_old_format { |old_format| old_format[0] } end +# @deprecated This save data is slated to be removed in v22, as its use is +# replaced by $stats.play_time. SaveData.register(:frame_count) do ensure_class :Integer save_value { Graphics.frame_count } load_value { |value| Graphics.frame_count = value } new_game_value { 0 } - from_old_format { |old_format| old_format[1] } end SaveData.register(:game_system) do @@ -22,7 +22,6 @@ SaveData.register(:game_system) do save_value { $game_system } load_value { |value| $game_system = value } new_game_value { Game_System.new } - from_old_format { |old_format| old_format[2] } end SaveData.register(:pokemon_system) do @@ -31,7 +30,6 @@ SaveData.register(:pokemon_system) do save_value { $PokemonSystem } load_value { |value| $PokemonSystem = value } new_game_value { PokemonSystem.new } - from_old_format { |old_format| old_format[3] } end SaveData.register(:switches) do @@ -39,7 +37,6 @@ SaveData.register(:switches) do save_value { $game_switches } load_value { |value| $game_switches = value } new_game_value { Game_Switches.new } - from_old_format { |old_format| old_format[5] } end SaveData.register(:variables) do @@ -47,7 +44,6 @@ SaveData.register(:variables) do save_value { $game_variables } load_value { |value| $game_variables = value } new_game_value { Game_Variables.new } - from_old_format { |old_format| old_format[6] } end SaveData.register(:self_switches) do @@ -55,7 +51,6 @@ SaveData.register(:self_switches) do save_value { $game_self_switches } load_value { |value| $game_self_switches = value } new_game_value { Game_SelfSwitches.new } - from_old_format { |old_format| old_format[7] } end SaveData.register(:game_screen) do @@ -63,14 +58,12 @@ SaveData.register(:game_screen) do save_value { $game_screen } load_value { |value| $game_screen = value } new_game_value { Game_Screen.new } - from_old_format { |old_format| old_format[8] } end SaveData.register(:map_factory) do ensure_class :PokemonMapFactory save_value { $map_factory } load_value { |value| $map_factory = value } - from_old_format { |old_format| old_format[9] } end SaveData.register(:game_player) do @@ -78,7 +71,6 @@ SaveData.register(:game_player) do save_value { $game_player } load_value { |value| $game_player = value } new_game_value { Game_Player.new } - from_old_format { |old_format| old_format[10] } end SaveData.register(:global_metadata) do @@ -86,7 +78,6 @@ SaveData.register(:global_metadata) do save_value { $PokemonGlobal } load_value { |value| $PokemonGlobal = value } new_game_value { PokemonGlobalMetadata.new } - from_old_format { |old_format| old_format[11] } end SaveData.register(:map_metadata) do @@ -94,7 +85,6 @@ SaveData.register(:map_metadata) do save_value { $PokemonMap } load_value { |value| $PokemonMap = value } new_game_value { PokemonMapMetadata.new } - from_old_format { |old_format| old_format[12] } end SaveData.register(:bag) do @@ -102,7 +92,6 @@ SaveData.register(:bag) do save_value { $bag } load_value { |value| $bag = value } new_game_value { PokemonBag.new } - from_old_format { |old_format| old_format[13] } end SaveData.register(:storage_system) do @@ -110,7 +99,6 @@ SaveData.register(:storage_system) do save_value { $PokemonStorage } load_value { |value| $PokemonStorage = value } new_game_value { PokemonStorage.new } - from_old_format { |old_format| old_format[14] } end SaveData.register(:essentials_version) do @@ -119,7 +107,6 @@ SaveData.register(:essentials_version) do save_value { Essentials::VERSION } load_value { |value| $save_engine_version = value } new_game_value { Essentials::VERSION } - from_old_format { |old_format| old_format[15] } end SaveData.register(:game_version) do diff --git a/Data/Scripts/002_Save data/005_Game_SaveConversions.rb b/Data/Scripts/002_Save data/005_Game_SaveConversions.rb index 351e8b919..c20338869 100644 --- a/Data/Scripts/002_Save data/005_Game_SaveConversions.rb +++ b/Data/Scripts/002_Save data/005_Game_SaveConversions.rb @@ -289,7 +289,7 @@ SaveData.register_conversion(:v20_add_stats) do to_all do |save_data| unless save_data.has_key?(:stats) save_data[:stats] = GameStats.new - save_data[:stats].play_time = save_data[:frame_count].to_f / Graphics.frame_rate + save_data[:stats].play_time = (save_data[:frame_count] || 0).to_f / Graphics.frame_rate save_data[:stats].play_sessions = 1 save_data[:stats].time_last_saved = save_data[:stats].play_time end @@ -404,3 +404,13 @@ SaveData.register_conversion(:v21_replace_flute_booleans) do end end end + +SaveData.register_conversion(:v21_add_bump_stat) do + essentials_version 21 + display_title "Adding a bump stat" + to_value :stats do |stats| + stats.instance_eval do + @bump_count = 0 if !@bump_count + end + end +end diff --git a/Data/Scripts/003_Game processing/004_Interpreter_Commands.rb b/Data/Scripts/003_Game processing/004_Interpreter_Commands.rb index f0e9476b6..ec84cd17e 100644 --- a/Data/Scripts/003_Game processing/004_Interpreter_Commands.rb +++ b/Data/Scripts/003_Game processing/004_Interpreter_Commands.rb @@ -913,7 +913,7 @@ class Interpreter # * Screen Shake #----------------------------------------------------------------------------- def command_225 - $game_screen.start_shake(@parameters[0], @parameters[1], @parameters[2] * Graphics.frame_rate / 20) + $game_screen.start_shake(@parameters[0], @parameters[1], @parameters[2]) return true end diff --git a/Data/Scripts/004_Game classes/001_Game_Screen.rb b/Data/Scripts/004_Game classes/001_Game_Screen.rb index 88600b9f5..cd871db49 100644 --- a/Data/Scripts/004_Game classes/001_Game_Screen.rb +++ b/Data/Scripts/004_Game classes/001_Game_Screen.rb @@ -28,7 +28,6 @@ class Game_Screen @shake_power = 0 @shake_speed = 0 @shake_duration = 0 - @shake_direction = 1 @shake = 0 @pictures = [nil] (1..100).each { |i| @pictures.push(Game_Picture.new(i)) } @@ -43,9 +42,9 @@ class Game_Screen @tone = tone.clone return end - @tone_initial = @tone.clone - @tone_target = tone.clone - @tone_duration = duration / 20.0 + @tone_initial = @tone.clone + @tone_target = tone.clone + @tone_duration = duration / 20.0 @tone_timer_start = $stats.play_time end @@ -57,16 +56,19 @@ class Game_Screen @flash_timer_start = $stats.play_time end + # duration is time in 1/20ths of a second. def start_shake(power, speed, duration) - @shake_power = power - @shake_speed = speed - @shake_duration = duration + @shake_power = power + @shake_speed = speed + @shake_duration = duration / 20.0 + @shake_timer_start = $stats.play_time end + # duration is time in 1/20ths of a second. def weather(type, power, duration) @weather_type = GameData::Weather.get(type).id @weather_max = (power + 1) * RPG::Weather::MAX_SPRITES / 10 - @weather_duration = duration # In 1/20ths of a seconds + @weather_duration = duration end def update @@ -98,16 +100,25 @@ class Game_Screen @flash_timer_start = nil end end - if @shake_duration >= 1 || @shake != 0 - delta = (@shake_power * @shake_speed * @shake_direction) / 10.0 - if @shake_duration <= 1 && @shake * (@shake + delta) < 0 - @shake = 0 + if @shake_timer_start + delta_t = now - @shake_timer_start + movement_per_second = @shake_power * @shake_speed * 4 + limit = @shake_power * 2.5 # Maximum pixel displacement + phase = (delta_t * movement_per_second / limit).to_i % 4 + if phase == 0 || phase == 2 + @shake = (movement_per_second * delta_t) % limit + @shake *= -1 if phase == 2 else - @shake += delta + @shake = limit - ((movement_per_second * delta_t) % limit) + @shake *= -1 if phase == 3 + end + if delta_t >= @shake_duration + @shake_phase = phase if !@shake_phase || phase == 1 || phase == 3 + if phase != @shake_phase || @shake < 2 + @shake_timer_start = nil + @shake = 0 + end end - @shake_direction = -1 if @shake > @shake_power * 2 - @shake_direction = 1 if @shake < -@shake_power * 2 - @shake_duration -= 1 if @shake_duration >= 1 end if $game_temp.in_battle (51..100).each { |i| @pictures[i].update } @@ -130,5 +141,5 @@ def pbFlash(color, frames) end def pbShake(power, speed, frames) - $game_screen.start_shake(power, speed, frames * Graphics.frame_rate / 20) + $game_screen.start_shake(power, speed, frames) end diff --git a/Data/Scripts/004_Game classes/004_Game_Map.rb b/Data/Scripts/004_Game classes/004_Game_Map.rb index 455733941..0c14da27c 100644 --- a/Data/Scripts/004_Game classes/004_Game_Map.rb +++ b/Data/Scripts/004_Game classes/004_Game_Map.rb @@ -68,8 +68,8 @@ class Game_Map (1...$data_common_events.size).each do |i| @common_events[i] = Game_CommonEvent.new(i) end - @scroll_direction = 2 - @scroll_rest = 0 + @scroll_distance_x = 0 + @scroll_distance_y = 0 @scroll_speed = 4 end @@ -356,18 +356,42 @@ class Game_Map self.display_x += distance end - def start_scroll(direction, distance, speed) - @scroll_direction = direction - if [2, 8].include?(direction) # down or up - @scroll_rest = distance * REAL_RES_Y - else - @scroll_rest = distance * REAL_RES_X + # speed is: + # 1: moves 1 tile in 1.6 seconds + # 2: moves 1 tile in 0.8 seconds + # 3: moves 1 tile in 0.4 seconds + # 4: moves 1 tile in 0.2 seconds + # 5: moves 1 tile in 0.1 seconds + # 6: moves 1 tile in 0.05 seconds + def start_scroll(direction, distance, speed = 4) + return if direction <= 0 || direction == 5 || direction >= 10 + if [1, 3, 4, 6, 7, 9].include(direction) # horizontal + @scroll_distance_x = distance + @scroll_distance_x *= -1 if [1, 4, 7].include?(direction) + end + if [1, 2, 3, 7, 8, 9].include?(direction) # vertical + @scroll_distance_y = distance + @scroll_distance_y *= -1 if [7, 8, 9].include?(direction) end @scroll_speed = speed + @scroll_start_x = display_x + @scroll_start_y = display_y + @scroll_timer_start = System.uptime + end + + # The two distances can be positive or negative. + def start_scroll_custom(distance_x, distance_y, speed = 4) + return if distance_x == 0 && distance_y == 0 + @scroll_distance_x = distance_x + @scroll_distance_y = distance_y + @scroll_speed = speed + @scroll_start_x = display_x + @scroll_start_y = display_y + @scroll_timer_start = System.uptime end def scrolling? - return @scroll_rest > 0 + return (@scroll_distance_x || 0) != 0 || (@scroll_distance_y || 0) != 0 end # duration is time in 1/20ths of a second. @@ -419,16 +443,17 @@ class Game_Map $map_factory.setCurrentMap end # If scrolling - if @scroll_rest > 0 - distance = (1 << @scroll_speed) * 40.0 / Graphics.frame_rate - distance = @scroll_rest if distance > @scroll_rest - case @scroll_direction - when 2 then scroll_down(distance) - when 4 then scroll_left(distance) - when 6 then scroll_right(distance) - when 8 then scroll_up(distance) - end - @scroll_rest -= distance + if (@scroll_distance_x || 0) != 0 + duration = @scroll_distance_x.abs * TILE_WIDTH.to_f / (10 * (2**@scroll_speed)) + scroll_offset = lerp(0, @scroll_distance_x, duration, @scroll_timer_start, System.uptime) + self.display_x = @scroll_start_x + scroll_offset * REAL_RES_X + @scroll_distance_x = 0 if scroll_offset == @scroll_distance_x + end + if (@scroll_distance_y || 0) != 0 + duration = @scroll_distance_y.abs * TILE_HEIGHT.to_f / (10 * (2**@scroll_speed)) + scroll_offset = lerp(0, @scroll_distance_y, duration, @scroll_timer_start, System.uptime) + self.display_y = @scroll_start_y + scroll_offset * REAL_RES_Y + @scroll_distance_y = 0 if scroll_offset == @scroll_distance_y end # Only update events that are on-screen if !$game_temp.in_menu @@ -463,26 +488,74 @@ end #=============================================================================== # #=============================================================================== -def pbScrollMap(direction, distance, speed) +# Scroll the map in the given direction by the given distance at the (optional) +# given speed. +def pbScrollMap(direction, distance, speed = 4) if speed == 0 - case direction - when 2 then $game_map.scroll_down(distance * Game_Map::REAL_RES_Y) - when 4 then $game_map.scroll_left(distance * Game_Map::REAL_RES_X) - when 6 then $game_map.scroll_right(distance * Game_Map::REAL_RES_X) - when 8 then $game_map.scroll_up(distance * Game_Map::REAL_RES_Y) + if [1, 2, 3].include?(direction) + $game_map.scroll_down(distance * Game_Map::REAL_RES_Y) + elsif [7, 8, 9].include?(direction) + $game_map.scroll_up(distance * Game_Map::REAL_RES_Y) + end + if [3, 6, 9].include?(direction) + $game_map.scroll_right(distance * Game_Map::REAL_RES_X) + elsif [1, 4, 7].include?(direction) + $game_map.scroll_left(distance * Game_Map::REAL_RES_X) end else $game_map.start_scroll(direction, distance, speed) - oldx = $game_map.display_x - oldy = $game_map.display_y loop do Graphics.update Input.update - break if !$game_map.scrolling? pbUpdateSceneMap - break if $game_map.display_x == oldx && $game_map.display_y == oldy - oldx = $game_map.display_x - oldy = $game_map.display_y + break if !$game_map.scrolling? end end end + +# Scroll the map to center on the given coordinates at the (optional) given +# speed. The scroll can happen in up to two parts, depending on where the target +# is relative to the current location: an initial diagonal movement and a +# following cardinal (vertical/horizontal) movement. +def pbScrollMapTo(x, y, speed = 4) + if !$game_map.valid?(x, y) + print "pbScrollMapTo: given x,y is invalid" + return + elsif !(0..6).include?(speed) + print "pbScrollMapTo: invalid speed (0-6 only)" + return + end + # Get tile coordinates that the screen is currently scrolled to + screen_offset_x = (Graphics.width - Game_Map::TILE_WIDTH) * Game_Map::X_SUBPIXELS / 2 + screen_offset_y = (Graphics.height - Game_Map::TILE_HEIGHT) * Game_Map::Y_SUBPIXELS / 2 + current_tile_x = ($game_map.display_x + screen_offset_x) / Game_Map::REAL_RES_X + current_tile_y = ($game_map.display_y + screen_offset_y) / Game_Map::REAL_RES_Y + offset_x = x - current_tile_x + offset_y = y - current_tile_y + return if offset_x == 0 && offset_y == 0 + if speed == 0 + if offset_y > 0 + $game_map.scroll_down(offset_y.abs * Game_Map::REAL_RES_Y) + elsif offset_y < 0 + $game_map.scroll_up(offset_y.abs * Game_Map::REAL_RES_Y) + end + if offset_x > 0 + $game_map.scroll_right(offset_x.abs * Game_Map::REAL_RES_X) + elsif offset_x < 0 + $game_map.scroll_left(offset_x.abs * Game_Map::REAL_RES_X) + end + else + $game_map.start_scroll_custom(offset_x, offset_y, speed) + loop do + Graphics.update + Input.update + pbUpdateSceneMap + break if !$game_map.scrolling? + end + end +end + +# Scroll the map to center on the player at the (optional) given speed. +def pbScrollMapToPlayer(speed = 4) + pbScrollMapTo($game_player.x, $game_player.y, speed) +end diff --git a/Data/Scripts/004_Game classes/006_Game_MapFactory.rb b/Data/Scripts/004_Game classes/005_Game_MapFactory.rb similarity index 100% rename from Data/Scripts/004_Game classes/006_Game_MapFactory.rb rename to Data/Scripts/004_Game classes/005_Game_MapFactory.rb diff --git a/Data/Scripts/004_Game classes/005_Game_Map_Autoscroll.rb b/Data/Scripts/004_Game classes/005_Game_Map_Autoscroll.rb deleted file mode 100644 index 0d89a53ad..000000000 --- a/Data/Scripts/004_Game classes/005_Game_Map_Autoscroll.rb +++ /dev/null @@ -1,189 +0,0 @@ -#=============================================================================== -# ** Map Autoscroll -#------------------------------------------------------------------------------- -# Wachunga -# Version 1.02 -# 2005-12-18 -#=============================================================================== -# -# This script supplements the built-in "Scroll Map" event command with the -# aim of simplifying cutscenes (and map scrolling in general). Whereas the -# normal event command requires a direction and number of tiles to scroll, -# Map Autoscroll scrolls the map to center on the tile whose x and y -# coordinates are given. -# -# FEATURES -# - automatic map scrolling to given x,y coordinate (or player) -# - destination is fixed, so it's possible to scroll to same place even if -# origin is variable (e.g. moving NPC) -# - variable speed (just like "Scroll Map" event command) -# - diagonal scrolling supported -# -# SETUP -# Instead of a "Scroll Map" event command, use the "Call Script" command -# and enter on the following on the first line: -# -# autoscroll(x,y) -# -# (replacing "x" and "y" with the x and y coordinates of the tile to scroll to) -# -# To specify a scroll speed other than the default (4), use: -# -# autoscroll(x,y,speed) -# -# (now also replacing "speed" with the scroll speed from 1-6) -# -# Diagonal scrolling happens automatically when the destination is diagonal -# relative to the starting point (i.e., not directly up, down, left or right). -# -# To scroll to the player, instead use the following: -# -# autoscroll_player(speed) -# -# Note: because of how the interpreter and the "Call Script" event command -# are setup, the call to autoscroll(...) can only be on the first line of -# the "Call Script" event command (and not flowing down to subsequent lines). -# -# For example, the following call may not work as expected: -# -# autoscroll($game_variables[1], -# $game_variables[2]) -# -# (since the long argument names require dropping down to a second line) -# A work-around is to setup new variables with shorter names in a preceding -# (separate) "Call Script" event command: -# -# @x = $game_variables[1] -# @y = $game_variables[2] -# -# and then use those as arguments: -# -# autoscroll(@x,@y) -# -# The renaming must be in a separate "Call Script" because otherwise -# the call to autoscroll(...) isn't on the first line. -# -# Originally requested by militantmilo80: -# http://www.rmxp.net/forums/index.php?showtopic=29519 -# -#=============================================================================== - -#=============================================================================== -# -#=============================================================================== -class Interpreter - SCROLL_SPEED_DEFAULT = 4 - # Map Autoscroll to Coordinates - # x : x coordinate to scroll to and center on - # y : y coordinate to scroll to and center on - # speed : (optional) scroll speed (from 1-6, default being 4) - def autoscroll(x, y, speed = SCROLL_SPEED_DEFAULT) - if $game_map.scrolling? - return false - elsif !$game_map.valid?(x, y) - print "Map Autoscroll: given x,y is invalid" - return command_skip - elsif !(1..6).include?(speed) - print "Map Autoscroll: invalid speed (1-6 only)" - return command_skip - end - center_x = ((Graphics.width / 2) - (Game_Map::TILE_WIDTH / 2)) * 4 # X coordinate in the center of the screen - center_y = ((Graphics.height / 2) - (Game_Map::TILE_HEIGHT / 2)) * 4 # Y coordinate in the center of the screen - max_x = ($game_map.width - (Graphics.width.to_f / Game_Map::TILE_WIDTH)) * 4 * Game_Map::TILE_WIDTH - max_y = ($game_map.height - (Graphics.height.to_f / Game_Map::TILE_HEIGHT)) * 4 * Game_Map::TILE_HEIGHT - count_x = ($game_map.display_x - [0, [(x * Game_Map::REAL_RES_X) - center_x, max_x].min].max) / Game_Map::REAL_RES_X - count_y = ($game_map.display_y - [0, [(y * Game_Map::REAL_RES_Y) - center_y, max_y].min].max) / Game_Map::REAL_RES_Y - if @diag - @diag = false - dir = nil - if count_x != 0 && count_y != 0 - return false - elsif count_x > 0 - dir = 4 - elsif count_x < 0 - dir = 6 - elsif count_y > 0 - dir = 8 - elsif count_y < 0 - dir = 2 - end - count = count_x == 0 ? count_y.abs : count_x.abs - else - @diag = true - dir = nil - if count_x > 0 - if count_y > 0 - dir = 7 - elsif count_y < 0 - dir = 1 - end - elsif count_x < 0 - if count_y > 0 - dir = 9 - elsif count_y < 0 - dir = 3 - end - end - count = [count_x.abs, count_y.abs].min - end - $game_map.start_scroll(dir, count, speed) if dir - return !@diag - end - - # Map Autoscroll (to Player) - # speed : (optional) scroll speed (from 1-6, default being 4) - def autoscroll_player(speed = SCROLL_SPEED_DEFAULT) - autoscroll($game_player.x, $game_player.y, speed) - end -end - -#=============================================================================== -# -#=============================================================================== -class Game_Map - def scroll_downright(distance) - @display_x = [@display_x + distance, - (self.width - (Graphics.width.to_f / TILE_WIDTH)) * REAL_RES_X].min - @display_y = [@display_y + distance, - (self.height - (Graphics.height.to_f / TILE_HEIGHT)) * REAL_RES_Y].min - end - - def scroll_downleft(distance) - @display_x = [@display_x - distance, 0].max - @display_y = [@display_y + distance, - (self.height - (Graphics.height.to_f / TILE_HEIGHT)) * REAL_RES_Y].min - end - - def scroll_upright(distance) - @display_x = [@display_x + distance, - (self.width - (Graphics.width.to_f / TILE_WIDTH)) * REAL_RES_X].min - @display_y = [@display_y - distance, 0].max - end - - def scroll_upleft(distance) - @display_x = [@display_x - distance, 0].max - @display_y = [@display_y - distance, 0].max - end - - def update_scrolling - # If scrolling - if @scroll_rest > 0 - # Change from scroll speed to distance in map coordinates - distance = (1 << @scroll_speed) * 40 / Graphics.frame_rate - distance = @scroll_rest if distance > @scroll_rest - # Execute scrolling - case @scroll_direction - when 1 then scroll_downleft(distance) - when 2 then scroll_down(distance) - when 3 then scroll_downright(distance) - when 4 then scroll_left(distance) - when 6 then scroll_right(distance) - when 7 then scroll_upleft(distance) - when 8 then scroll_up(distance) - when 9 then scroll_upright(distance) - end - # Subtract distance scrolled - @scroll_rest -= distance - end - end -end diff --git a/Data/Scripts/004_Game classes/007_Game_Character.rb b/Data/Scripts/004_Game classes/006_Game_Character.rb similarity index 99% rename from Data/Scripts/004_Game classes/007_Game_Character.rb rename to Data/Scripts/004_Game classes/006_Game_Character.rb index 17bc655ce..f4257d27e 100644 --- a/Data/Scripts/004_Game classes/007_Game_Character.rb +++ b/Data/Scripts/004_Game classes/006_Game_Character.rb @@ -72,6 +72,7 @@ class Game_Character @always_on_top = false @anime_count = 0 # Time since pattern was last changed @stop_count = 0 # Time since character last finished moving + @bumping = false # Used by the player only when walking into something @jump_peak = 0 # Max height while jumping @jump_distance = 0 # Total distance of jump @jump_fraction = 0 # How far through a jump we currently are (0-1) @@ -337,8 +338,7 @@ class Game_Character # Movement #============================================================================= def moving? - return @real_x != @x * Game_Map::REAL_RES_X || - @real_y != @y * Game_Map::REAL_RES_Y + return !@move_timer.nil? end def jumping? @@ -955,8 +955,10 @@ class Game_Character @real_x = @x * Game_Map::REAL_RES_X if (@real_x - (@x * Game_Map::REAL_RES_X)).abs < Game_Map::X_SUBPIXELS / 2 @real_y = @y * Game_Map::REAL_RES_Y if (@real_y - (@y * Game_Map::REAL_RES_Y)).abs < Game_Map::Y_SUBPIXELS / 2 # End of move - if !moving? + if moving? && @move_timer >= @move_time && + @real_x == @x * Game_Map::REAL_RES_X && @real_y == @y * Game_Map::REAL_RES_Y @move_timer = nil + @bumping = false end # End of jump if jumping? && @jump_fraction >= 1 diff --git a/Data/Scripts/004_Game classes/008_Game_Event.rb b/Data/Scripts/004_Game classes/007_Game_Event.rb similarity index 100% rename from Data/Scripts/004_Game classes/008_Game_Event.rb rename to Data/Scripts/004_Game classes/007_Game_Event.rb diff --git a/Data/Scripts/004_Game classes/009_Game_Player.rb b/Data/Scripts/004_Game classes/008_Game_Player.rb similarity index 96% rename from Data/Scripts/004_Game classes/009_Game_Player.rb rename to Data/Scripts/004_Game classes/008_Game_Player.rb index 634682732..00414dac3 100644 --- a/Data/Scripts/004_Game classes/009_Game_Player.rb +++ b/Data/Scripts/004_Game classes/008_Game_Player.rb @@ -6,20 +6,19 @@ # instance of this class. #=============================================================================== class Game_Player < Game_Character - attr_accessor :bump_se attr_accessor :charsetData attr_accessor :encounter_count SCREEN_CENTER_X = ((Settings::SCREEN_WIDTH / 2) - (Game_Map::TILE_WIDTH / 2)) * Game_Map::X_SUBPIXELS SCREEN_CENTER_Y = ((Settings::SCREEN_HEIGHT / 2) - (Game_Map::TILE_HEIGHT / 2)) * Game_Map::Y_SUBPIXELS - - @@bobFrameSpeed = 1.0 / 15 + # Time in seconds for one cycle of bobbing (playing 4 charset frames) while + # surfing or diving. + SURF_BOB_DURATION = 1.5 def initialize(*arg) super(*arg) @lastdir = 0 @lastdirframe = 0 - @bump_se = 0 end def map @@ -52,6 +51,7 @@ class Game_Player < Game_Character def can_run? return @move_speed > 3 if @move_route_forcing + return false if @bumping return false if $game_temp.in_menu || $game_temp.in_battle || $game_temp.message_window_showing || pbMapInterpreterRunning? return false if !$player.has_running_shoes && !$PokemonGlobal.diving && @@ -92,6 +92,7 @@ class Game_Player < Game_Character self.move_speed = 3 if !@move_route_forcing new_charset = pbGetPlayerCharset(meta.walk_charset) end + self.move_speed = 3 if @bumping @character_name = new_charset if new_charset end @@ -115,9 +116,12 @@ class Game_Player < Game_Character #----------------------------------------------------------------------------- def bump_into_object - return if @bump_se && @bump_se > 0 pbSEPlay("Player bump") if !@move_route_forcing - @bump_se = Graphics.frame_rate / 4 + $stats.bump_count += 1 + @move_initial_x = @x + @move_initial_y = @y + @move_timer = 0.0 + @bumping = true end def add_move_distance_to_stats(distance = 1) @@ -412,8 +416,6 @@ class Game_Player < Game_Character $game_temp.followers.move_followers end $game_temp.followers.update - # Count down the time between allowed bump sounds - @bump_se -= 1 if @bump_se && @bump_se > 0 update_event_triggering end @@ -425,7 +427,7 @@ class Game_Player < Game_Character !$game_temp.in_mini_update && !$game_temp.in_menu # Move player in the direction the directional button is being pressed if @moved_last_frame || - (dir > 0 && dir == @lastdir && Graphics.frame_count - @lastdirframe > Graphics.frame_rate / 20) + (dir > 0 && dir == @lastdir && System.uptime - @lastdirframe >= 0.075) case dir when 2 then move_down when 4 then move_left @@ -440,10 +442,10 @@ class Game_Player < Game_Character when 8 then turn_up end end + # Record last direction input + @lastdirframe = System.uptime if dir != @lastdir + @lastdir = dir end - # Record last direction input - @lastdirframe = Graphics.frame_count if dir != @lastdir - @lastdir = dir end def update_move @@ -501,10 +503,10 @@ class Game_Player < Game_Character def update_pattern if $PokemonGlobal&.surfing || $PokemonGlobal&.diving - p = ((Graphics.frame_count % 60) * @@bobFrameSpeed).floor - @pattern = p if !@lock_pattern - @pattern_surf = p - @bob_height = (p >= 2) ? 2 : 0 + bob_pattern = (4 * System.uptime / SURF_BOB_DURATION).to_i % 4 + @pattern = bob_pattern if !@lock_pattern + @pattern_surf = bob_pattern + @bob_height = (bob_pattern >= 2) ? 2 : 0 @anime_count = 0 else @bob_height = 0 diff --git a/Data/Scripts/004_Game classes/010_Game_CommonEvent.rb b/Data/Scripts/004_Game classes/009_Game_CommonEvent.rb similarity index 100% rename from Data/Scripts/004_Game classes/010_Game_CommonEvent.rb rename to Data/Scripts/004_Game classes/009_Game_CommonEvent.rb diff --git a/Data/Scripts/004_Game classes/011_Game_Follower.rb b/Data/Scripts/004_Game classes/010_Game_Follower.rb similarity index 100% rename from Data/Scripts/004_Game classes/011_Game_Follower.rb rename to Data/Scripts/004_Game classes/010_Game_Follower.rb diff --git a/Data/Scripts/004_Game classes/012_Game_FollowerFactory.rb b/Data/Scripts/004_Game classes/011_Game_FollowerFactory.rb similarity index 100% rename from Data/Scripts/004_Game classes/012_Game_FollowerFactory.rb rename to Data/Scripts/004_Game classes/011_Game_FollowerFactory.rb diff --git a/Data/Scripts/004_Game classes/013_Game_Stats.rb b/Data/Scripts/004_Game classes/012_Game_Stats.rb similarity index 95% rename from Data/Scripts/004_Game classes/013_Game_Stats.rb rename to Data/Scripts/004_Game classes/012_Game_Stats.rb index 935e4867f..d380a3101 100644 --- a/Data/Scripts/004_Game classes/013_Game_Stats.rb +++ b/Data/Scripts/004_Game classes/012_Game_Stats.rb @@ -5,6 +5,7 @@ class GameStats # Travel attr_accessor :distance_walked, :distance_cycled, :distance_surfed # surfed includes diving attr_accessor :distance_slid_on_ice # Also counted in distance_walked + attr_accessor :bump_count # Times the player walked into something attr_accessor :cycle_count, :surf_count, :dive_count # Field actions attr_accessor :fly_count, :cut_count, :flash_count @@ -45,7 +46,7 @@ class GameStats attr_accessor :mart_items_bought, :premier_balls_earned attr_accessor :drinks_bought, :drinks_won # From vending machines attr_accessor :coins_won, :coins_lost # Not bought, not spent - attr_accessor :battle_points_won, :battle_points_spent # Currently unused + attr_accessor :battle_points_won, :battle_points_spent attr_accessor :soot_collected # Special stats attr_accessor :gym_leader_attempts # An array of integers @@ -66,6 +67,7 @@ class GameStats @distance_cycled = 0 @distance_surfed = 0 @distance_slid_on_ice = 0 + @bump_count = 0 @cycle_count = 0 @surf_count = 0 @dive_count = 0 @@ -170,8 +172,9 @@ class GameStats def play_time if $game_temp&.last_uptime_refreshed_play_time - @play_time += System.uptime - $game_temp.last_uptime_refreshed_play_time - $game_temp.last_uptime_refreshed_play_time = System.uptime + now = System.uptime + @play_time += now - $game_temp.last_uptime_refreshed_play_time + $game_temp.last_uptime_refreshed_play_time = now end return @play_time end diff --git a/Data/Scripts/005_Sprites/004_Sprite_Reflection.rb b/Data/Scripts/005_Sprites/004_Sprite_Reflection.rb index 85255c24f..da6c0088c 100644 --- a/Data/Scripts/005_Sprites/004_Sprite_Reflection.rb +++ b/Data/Scripts/005_Sprites/004_Sprite_Reflection.rb @@ -66,9 +66,8 @@ class Sprite_Reflection @sprite.z = -50 # Still water is -100, map is 0 and above @sprite.z += 1 if event == $game_player @sprite.zoom_x = @parent_sprite.zoom_x + @sprite.zoom_x += 0.05 * @sprite.zoom_x * Math.sin(2 * Math::PI * System.uptime) @sprite.zoom_y = @parent_sprite.zoom_y - frame = (Graphics.frame_count % 40) / 10 - @sprite.zoom_x *= [1.0, 0.95, 1.0, 1.05][frame] @sprite.angle = 180.0 @sprite.mirror = true @sprite.bitmap = @parent_sprite.bitmap diff --git a/Data/Scripts/007_Objects and windows/003_Window.rb b/Data/Scripts/007_Objects and windows/003_Window.rb index 720c9deeb..c1bb080c4 100644 --- a/Data/Scripts/007_Objects and windows/003_Window.rb +++ b/Data/Scripts/007_Objects and windows/003_Window.rb @@ -315,7 +315,7 @@ class Window @cursoropacity = 128 end if @pause - @pauseframe = (Graphics.frame_count / 8) % 4 + @pauseframe = (System.uptime * 5).to_i % 4 # 4 frames, 5 frames per second @pauseopacity = [@pauseopacity + 64, 255].min mustchange = true end diff --git a/Data/Scripts/007_Objects and windows/004_SpriteWindow.rb b/Data/Scripts/007_Objects and windows/004_SpriteWindow.rb index 588f5c7c3..131469836 100644 --- a/Data/Scripts/007_Objects and windows/004_SpriteWindow.rb +++ b/Data/Scripts/007_Objects and windows/004_SpriteWindow.rb @@ -312,7 +312,7 @@ class SpriteWindow < Window if @pause oldpauseframe = @pauseframe oldpauseopacity = @pauseopacity - @pauseframe = (Graphics.frame_count / 8) % 4 + @pauseframe = (System.uptime * 5) % 4 # 4 frames, 5 frames per second @pauseopacity = [@pauseopacity + 64, 255].min mustchange = @pauseframe != oldpauseframe || @pauseopacity != oldpauseopacity end diff --git a/Data/Scripts/007_Objects and windows/005_SpriteWindow_text.rb b/Data/Scripts/007_Objects and windows/005_SpriteWindow_text.rb index b2c656cb0..aad8028c9 100644 --- a/Data/Scripts/007_Objects and windows/005_SpriteWindow_text.rb +++ b/Data/Scripts/007_Objects and windows/005_SpriteWindow_text.rb @@ -164,6 +164,7 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base def waitcount=(value) @waitcount = (value <= 0) ? 0 : value + @wait_timer_start = System.uptime if !@wait_timer_start && value > 0 end attr_reader :cursorMode @@ -282,24 +283,25 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base end def setText(value) - @waitcount = 0 - @curchar = 0 - @drawncurchar = -1 + @waitcount = 0 + @wait_timer_start = nil + @curchar = 0 + @drawncurchar = -1 @lastDrawnChar = -1 - @text = value - @textlength = unformattedTextLength(value) - @scrollstate = 0 - @scrollY = 0 - @linesdrawn = 0 - @realframes = 0 - @textchars = [] - width = 1 + @text = value + @textlength = unformattedTextLength(value) + @scrollstate = 0 + @scrollY = 0 + @linesdrawn = 0 + @realframes = 0 + @textchars = [] + width = 1 height = 1 numlines = 0 visiblelines = (self.height - self.borderY) / @lineHeight if value.length == 0 - @fmtchars = [] - @bitmapwidth = width + @fmtchars = [] + @bitmapwidth = width @bitmapheight = height @numtextchars = 0 else @@ -339,19 +341,19 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base @fmtchars.each do |ch| chx = ch[1] + ch[3] chy = ch[2] + ch[4] - width = chx if width < chx + width = chx if width < chx height = chy if height < chy @textchars.push(ch[5] ? "" : ch[0]) end end - @bitmapwidth = width + @bitmapwidth = width @bitmapheight = height @numtextchars = @textchars.length end stopPause @displaying = @letterbyletter - @needclear = true - @nodraw = @letterbyletter + @needclear = true + @nodraw = @letterbyletter refresh end @@ -573,9 +575,12 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base def update super @pausesprite.update if @pausesprite&.visible - if @waitcount > 0 - @waitcount -= 1 - return + if @wait_timer_start + if System.uptime - @wait_timer_start >= @waitcount + @wait_timer_start = nil + @waitcount = 0 + end + return if @wait_timer_start end if busy? refresh if !@frameskipChanged diff --git a/Data/Scripts/007_Objects and windows/011_Messages.rb b/Data/Scripts/007_Objects and windows/011_Messages.rb index a2e87d285..7273df6b9 100644 --- a/Data/Scripts/007_Objects and windows/011_Messages.rb +++ b/Data/Scripts/007_Objects and windows/011_Messages.rb @@ -421,7 +421,6 @@ def pbMessageDisplay(msgwindow, message, letterbyletter = true, commandProc = ni msgwindow.waitcount = 0 autoresume = false text = message.clone - msgback = nil linecount = (Graphics.height > 400) ? 3 : 2 ### Text replacement text.gsub!(/\\sign\[([^\]]*)\]/i) do # \sign[something] gets turned into @@ -508,8 +507,8 @@ def pbMessageDisplay(msgwindow, message, letterbyletter = true, commandProc = ni controls[i][2] = textlen end text = textchunks.join - signWaitCount = 0 - signWaitTime = Graphics.frame_rate / 2 + appear_timer_start = nil + appear_duration = 0.5 # In seconds haveSpecialClose = false specialCloseSE = "" startSE = nil @@ -518,7 +517,7 @@ def pbMessageDisplay(msgwindow, message, letterbyletter = true, commandProc = ni param = controls[i][1] case control when "op" - signWaitCount = signWaitTime + 1 + appear_timer_start = System.uptime when "cl" text = text.sub(/\001\z/, "") # fix: '$' can match end of line as well haveSpecialClose = true @@ -548,7 +547,7 @@ def pbMessageDisplay(msgwindow, message, letterbyletter = true, commandProc = ni end if startSE pbSEPlay(pbStringToAudioFile(startSE)) - elsif signWaitCount == 0 && letterbyletter + elsif !appear_timer_start && letterbyletter pbPlayDecisionSE end # Position message window @@ -561,15 +560,12 @@ def pbMessageDisplay(msgwindow, message, letterbyletter = true, commandProc = ni atTop = (msgwindow.y == 0) # Show text msgwindow.text = text - Graphics.frame_reset if Graphics.frame_rate > 40 loop do - if signWaitCount > 0 - signWaitCount -= 1 - if atTop - msgwindow.y = -msgwindow.height * signWaitCount / signWaitTime - else - msgwindow.y = Graphics.height - (msgwindow.height * (signWaitTime - signWaitCount) / signWaitTime) - end + if appear_timer_start + y_start = (atTop) ? -msgwindow.height : Graphics.height + y_end = (atTop) ? 0 : Graphics.height - msgwindow.height + msgwindow.y = lerp(y_start, y_end, appear_duration, appear_timer_start, System.uptime) + appear_timer_start = nil if msgwindow.y == y_end end controls.length.times do |i| next if !controls[i] @@ -599,34 +595,35 @@ def pbMessageDisplay(msgwindow, message, letterbyletter = true, commandProc = ni battlepointswindow&.dispose battlepointswindow = pbDisplayBattlePointsWindow(msgwindow) when "wu" - msgwindow.y = 0 atTop = true - msgback.y = msgwindow.y if msgback + msgwindow.y = 0 pbPositionNearMsgWindow(facewindow, msgwindow, :left) - msgwindow.y = -msgwindow.height * signWaitCount / signWaitTime + if appear_timer_start + msgwindow.y = lerp(y_start, y_end, appear_duration, appear_timer_start, System.uptime) + end when "wm" atTop = false msgwindow.y = (Graphics.height - msgwindow.height) / 2 - msgback.y = msgwindow.y if msgback pbPositionNearMsgWindow(facewindow, msgwindow, :left) when "wd" atTop = false msgwindow.y = Graphics.height - msgwindow.height - msgback.y = msgwindow.y if msgback pbPositionNearMsgWindow(facewindow, msgwindow, :left) - msgwindow.y = Graphics.height - (msgwindow.height * (signWaitTime - signWaitCount) / signWaitTime) + if appear_timer_start + msgwindow.y = lerp(y_start, y_end, appear_duration, appear_timer_start, System.uptime) + end when "ts" # Change text speed msgwindow.textspeed = (param == "") ? -999 : param.to_i when "." # Wait 0.25 seconds - msgwindow.waitcount += Graphics.frame_rate / 4 + msgwindow.waitcount += 0.25 when "|" # Wait 1 second - msgwindow.waitcount += Graphics.frame_rate + msgwindow.waitcount += 1.0 when "wt" # Wait X/20 seconds param = param.sub(/\A\s+/, "").sub(/\s+\z/, "") - msgwindow.waitcount += param.to_i * Graphics.frame_rate / 20 + msgwindow.waitcount += param.to_i / 20.0 when "wtnp" # Wait X/20 seconds, no pause param = param.sub(/\A\s+/, "").sub(/\s+\z/, "") - msgwindow.waitcount = param.to_i * Graphics.frame_rate / 20 + msgwindow.waitcount = param.to_i / 20.0 autoresume = true when "^" # Wait, no pause autoresume = true @@ -649,7 +646,7 @@ def pbMessageDisplay(msgwindow, message, letterbyletter = true, commandProc = ni if msgwindow.busy? pbPlayDecisionSE if msgwindow.pausing? msgwindow.resume - elsif signWaitCount == 0 + elsif !appear_timer_start break end end @@ -665,7 +662,6 @@ def pbMessageDisplay(msgwindow, message, letterbyletter = true, commandProc = ni $game_map.need_refresh = true if $game_map end ret = commandProc.call(msgwindow) if commandProc - msgback&.dispose goldwindow&.dispose coinwindow&.dispose battlepointswindow&.dispose @@ -673,16 +669,17 @@ def pbMessageDisplay(msgwindow, message, letterbyletter = true, commandProc = ni if haveSpecialClose pbSEPlay(pbStringToAudioFile(specialCloseSE)) atTop = (msgwindow.y == 0) - (0..signWaitTime).each do |i| - if atTop - msgwindow.y = -msgwindow.height * i / signWaitTime - else - msgwindow.y = Graphics.height - (msgwindow.height * (signWaitTime - i) / signWaitTime) - end + y_start = (atTop) ? 0 : Graphics.height - msgwindow.height + y_end = (atTop) ? -msgwindow.height : Graphics.height + disappear_duration = 0.5 # In seconds + disappear_timer_start = System.uptime + loop do + msgwindow.y = lerp(y_start, y_end, disappear_duration, disappear_timer_start, System.uptime) Graphics.update Input.update pbUpdateSceneMap msgwindow.update + break if msgwindow.y == y_end end end return ret diff --git a/Data/Scripts/012_Overworld/004_Overworld_FieldMoves.rb b/Data/Scripts/012_Overworld/004_Overworld_FieldMoves.rb index 995996016..36d6bffeb 100644 --- a/Data/Scripts/012_Overworld/004_Overworld_FieldMoves.rb +++ b/Data/Scripts/012_Overworld/004_Overworld_FieldMoves.rb @@ -68,17 +68,22 @@ end #=============================================================================== def pbHiddenMoveAnimation(pokemon) return false if !pokemon - viewport = Viewport.new(0, 0, 0, 0) + viewport = Viewport.new(0, 0, Graphics.width, 0) viewport.z = 99999 + # Set up sprites bg = Sprite.new(viewport) bg.bitmap = RPG::Cache.ui("Field move/bg") sprite = PokemonSprite.new(viewport) sprite.setOffset(PictureOrigin::CENTER) sprite.setPokemonBitmap(pokemon) + sprite.x = Graphics.width + (sprite.bitmap.width / 2) + sprite.y = bg.bitmap.height / 2 sprite.z = 1 sprite.visible = false strobebitmap = AnimatedBitmap.new("Graphics/UI/Field move/strobes") strobes = [] + strobes_start_x = [] + strobes_timers = [] 15.times do |i| strobe = BitmapSprite.new(52, 16, viewport) strobe.bitmap.blt(0, 0, strobebitmap.bitmap, Rect.new(0, (i % 2) * 16, 52, 16)) @@ -87,74 +92,54 @@ def pbHiddenMoveAnimation(pokemon) strobes.push(strobe) end strobebitmap.dispose - interp = RectInterpolator.new( - Rect.new(0, Graphics.height / 2, Graphics.width, 0), - Rect.new(0, (Graphics.height - bg.bitmap.height) / 2, Graphics.width, bg.bitmap.height), - Graphics.frame_rate / 4 - ) - ptinterp = nil + # Do the animation phase = 1 - frames = 0 - strobeSpeed = 64 * 20 / Graphics.frame_rate + timer_start = System.uptime loop do Graphics.update Input.update sprite.update case phase when 1 # Expand viewport height from zero to full - interp.update - interp.set(viewport.rect) + viewport.rect.y = lerp(Graphics.height / 2, (Graphics.height - bg.bitmap.height) / 2, + 0.25, timer_start, System.uptime) + viewport.rect.height = Graphics.height - viewport.rect.y * 2 bg.oy = (bg.bitmap.height - viewport.rect.height) / 2 - if interp.done? + if viewport.rect.y == (Graphics.height - bg.bitmap.height) / 2 phase = 2 - ptinterp = PointInterpolator.new( - Graphics.width + (sprite.bitmap.width / 2), bg.bitmap.height / 2, - Graphics.width / 2, bg.bitmap.height / 2, - Graphics.frame_rate * 4 / 10 - ) + sprite.visible = true + timer_start = System.uptime end when 2 # Slide Pokémon sprite in from right to centre - ptinterp.update - sprite.x = ptinterp.x - sprite.y = ptinterp.y - sprite.visible = true - if ptinterp.done? + sprite.x = lerp(Graphics.width + (sprite.bitmap.width / 2), Graphics.width / 2, + 0.4, timer_start, System.uptime) + if sprite.x == Graphics.width / 2 phase = 3 pokemon.play_cry - frames = 0 + timer_start = System.uptime end when 3 # Wait - frames += 1 - if frames > Graphics.frame_rate * 3 / 4 + if System.uptime - timer_start >= 0.75 phase = 4 - ptinterp = PointInterpolator.new( - Graphics.width / 2, bg.bitmap.height / 2, - -(sprite.bitmap.width / 2), bg.bitmap.height / 2, - Graphics.frame_rate * 4 / 10 - ) - frames = 0 + timer_start = System.uptime end when 4 # Slide Pokémon sprite off from centre to left - ptinterp.update - sprite.x = ptinterp.x - sprite.y = ptinterp.y - if ptinterp.done? + sprite.x = lerp(Graphics.width / 2, -(sprite.bitmap.width / 2), + 0.4, timer_start, System.uptime) + if sprite.x == -(sprite.bitmap.width / 2) phase = 5 sprite.visible = false - interp = RectInterpolator.new( - Rect.new(0, (Graphics.height - bg.bitmap.height) / 2, Graphics.width, bg.bitmap.height), - Rect.new(0, Graphics.height / 2, Graphics.width, 0), - Graphics.frame_rate / 4 - ) + timer_start = System.uptime end when 5 # Shrink viewport height from full to zero - interp.update - interp.set(viewport.rect) + viewport.rect.y = lerp((Graphics.height - bg.bitmap.height) / 2, Graphics.height / 2, + 0.25, timer_start, System.uptime) + viewport.rect.height = Graphics.height - viewport.rect.y * 2 bg.oy = (bg.bitmap.height - viewport.rect.height) / 2 - phase = 6 if interp.done? + phase = 6 if viewport.rect.y == Graphics.height / 2 end # Constantly stream the strobes across the screen - strobes.each do |strobe| + strobes.each_with_index do |strobe, i| strobe.ox = strobe.viewport.rect.x strobe.oy = strobe.viewport.rect.y if !strobe.visible # Initial placement of strobes @@ -162,12 +147,16 @@ def pbHiddenMoveAnimation(pokemon) strobe.y = randomY + ((Graphics.height - bg.bitmap.height) / 2) strobe.x = rand(Graphics.width) strobe.visible = true + strobes_start_x[i] = strobe.x + strobes_timers[i] = System.uptime elsif strobe.x < Graphics.width # Move strobe right - strobe.x += strobeSpeed + strobe.x = strobes_start_x[i] + lerp(0, Graphics.width * 2, 0.8, strobes_timers[i], System.uptime) else # Strobe is off the screen, reposition it to the left of the screen randomY = 16 * (1 + rand((bg.bitmap.height / 16) - 2)) strobe.y = randomY + ((Graphics.height - bg.bitmap.height) / 2) strobe.x = -strobe.bitmap.width - rand(Graphics.width / 4) + strobes_start_x[i] = strobe.x + strobes_timers[i] = System.uptime end end pbUpdateSceneMap diff --git a/Data/Scripts/016_UI/001_Non-interactive UI/004_UI_Evolution.rb b/Data/Scripts/016_UI/001_Non-interactive UI/004_UI_Evolution.rb index 7d1ed60ff..d9a28da33 100644 --- a/Data/Scripts/016_UI/001_Non-interactive UI/004_UI_Evolution.rb +++ b/Data/Scripts/016_UI/001_Non-interactive UI/004_UI_Evolution.rb @@ -1,483 +1,22 @@ -#=============================================================================== -# Evolution animation metafiles and related methods -#=============================================================================== -class SpriteMetafile - VIEWPORT = 0 - TONE = 1 - SRC_RECT = 2 - VISIBLE = 3 - X = 4 - Y = 5 - Z = 6 - OX = 7 - OY = 8 - ZOOM_X = 9 - ZOOM_Y = 10 - ANGLE = 11 - MIRROR = 12 - BUSH_DEPTH = 13 - OPACITY = 14 - BLEND_TYPE = 15 - COLOR = 16 - FLASHCOLOR = 17 - FLASHDURATION = 18 - BITMAP = 19 - - def initialize(viewport = nil) - @metafile = [] - @values = [ - viewport, - Tone.new(0, 0, 0, 0), Rect.new(0, 0, 0, 0), - true, - 0, 0, 0, 0, 0, 100, 100, - 0, false, 0, 255, 0, - Color.new(0, 0, 0, 0), Color.new(0, 0, 0, 0), - 0 - ] - end - - def dispose; end - - def disposed? - return false - end - - def [](i) - return @metafile[i] - end - - def length - return @metafile.length - end - - def flash(color, duration) - if duration > 0 - @values[FLASHCOLOR] = color.clone - @values[FLASHDURATION] = duration - @metafile.push([FLASHCOLOR, color]) - @metafile.push([FLASHDURATION, duration]) - end - end - - def x - return @values[X] - end - - def x=(value) - @values[X] = value - @metafile.push([X, value]) - end - - def y - return @values[Y] - end - - def y=(value) - @values[Y] = value - @metafile.push([Y, value]) - end - - def bitmap - return nil - end - - def bitmap=(value) - if value && !value.disposed? - @values[SRC_RECT].set(0, 0, value.width, value.height) - @metafile.push([SRC_RECT, @values[SRC_RECT].clone]) - end - end - - def src_rect - return @values[SRC_RECT] - end - - def src_rect=(value) - @values[SRC_RECT] = value - @metafile.push([SRC_RECT, value]) - end - - def visible - return @values[VISIBLE] - end - - def visible=(value) - @values[VISIBLE] = value - @metafile.push([VISIBLE, value]) - end - - def z - return @values[Z] - end - - def z=(value) - @values[Z] = value - @metafile.push([Z, value]) - end - - def ox - return @values[OX] - end - - def ox=(value) - @values[OX] = value - @metafile.push([OX, value]) - end - - def oy - return @values[OY] - end - - def oy=(value) - @values[OY] = value - @metafile.push([OY, value]) - end - - def zoom_x - return @values[ZOOM_X] - end - - def zoom_x=(value) - @values[ZOOM_X] = value - @metafile.push([ZOOM_X, value]) - end - - def zoom_y - return @values[ZOOM_Y] - end - - def zoom_y=(value) - @values[ZOOM_Y] = value - @metafile.push([ZOOM_Y, value]) - end - - def zoom=(value) - @values[ZOOM_X] = value - @metafile.push([ZOOM_X, value]) - @values[ZOOM_Y] = value - @metafile.push([ZOOM_Y, value]) - end - - def angle - return @values[ANGLE] - end - - def angle=(value) - @values[ANGLE] = value - @metafile.push([ANGLE, value]) - end - - def mirror - return @values[MIRROR] - end - - def mirror=(value) - @values[MIRROR] = value - @metafile.push([MIRROR, value]) - end - - def bush_depth - return @values[BUSH_DEPTH] - end - - def bush_depth=(value) - @values[BUSH_DEPTH] = value - @metafile.push([BUSH_DEPTH, value]) - end - - def opacity - return @values[OPACITY] - end - - def opacity=(value) - @values[OPACITY] = value - @metafile.push([OPACITY, value]) - end - - def blend_type - return @values[BLEND_TYPE] - end - - def blend_type=(value) - @values[BLEND_TYPE] = value - @metafile.push([BLEND_TYPE, value]) - end - - def color - return @values[COLOR] - end - - def color=(value) - @values[COLOR] = value.clone - @metafile.push([COLOR, @values[COLOR]]) - end - - def tone - return @values[TONE] - end - - def tone=(value) - @values[TONE] = value.clone - @metafile.push([TONE, @values[TONE]]) - end - - def update - @metafile.push([-1, nil]) - end -end - -#=============================================================================== -# -#=============================================================================== -class SpriteMetafilePlayer - def initialize(metafile, sprite = nil) - @metafile = metafile - @sprites = [] - @playing = false - @index = 0 - @sprites.push(sprite) if sprite - end - - def add(sprite) - @sprites.push(sprite) - end - - def playing? - return @playing - end - - def play - @playing = true - @index = 0 - end - - def update - return if !@playing - (@index...@metafile.length).each do |j| - @index = j + 1 - break if @metafile[j][0] < 0 - code = @metafile[j][0] - value = @metafile[j][1] - @sprites.each do |sprite| - case code - when SpriteMetafile::X then sprite.x = value - when SpriteMetafile::Y then sprite.y = value - when SpriteMetafile::OX then sprite.ox = value - when SpriteMetafile::OY then sprite.oy = value - when SpriteMetafile::ZOOM_X then sprite.zoom_x = value - when SpriteMetafile::ZOOM_Y then sprite.zoom_y = value - when SpriteMetafile::SRC_RECT then sprite.src_rect = value - when SpriteMetafile::VISIBLE then sprite.visible = value - when SpriteMetafile::Z then sprite.z = value # prevent crashes - when SpriteMetafile::ANGLE then sprite.angle = (value == 180) ? 179.9 : value - when SpriteMetafile::MIRROR then sprite.mirror = value - when SpriteMetafile::BUSH_DEPTH then sprite.bush_depth = value - when SpriteMetafile::OPACITY then sprite.opacity = value - when SpriteMetafile::BLEND_TYPE then sprite.blend_type = value - when SpriteMetafile::COLOR then sprite.color = value - when SpriteMetafile::TONE then sprite.tone = value - end - end - end - @playing = false if @index == @metafile.length - end -end - -#=============================================================================== -# -#=============================================================================== -def pbSaveSpriteState(sprite) - state = [] - return state if !sprite || sprite.disposed? - state[SpriteMetafile::BITMAP] = sprite.x - state[SpriteMetafile::X] = sprite.x - state[SpriteMetafile::Y] = sprite.y - state[SpriteMetafile::SRC_RECT] = sprite.src_rect.clone - state[SpriteMetafile::VISIBLE] = sprite.visible - state[SpriteMetafile::Z] = sprite.z - state[SpriteMetafile::OX] = sprite.ox - state[SpriteMetafile::OY] = sprite.oy - state[SpriteMetafile::ZOOM_X] = sprite.zoom_x - state[SpriteMetafile::ZOOM_Y] = sprite.zoom_y - state[SpriteMetafile::ANGLE] = sprite.angle - state[SpriteMetafile::MIRROR] = sprite.mirror - state[SpriteMetafile::BUSH_DEPTH] = sprite.bush_depth - state[SpriteMetafile::OPACITY] = sprite.opacity - state[SpriteMetafile::BLEND_TYPE] = sprite.blend_type - state[SpriteMetafile::COLOR] = sprite.color.clone - state[SpriteMetafile::TONE] = sprite.tone.clone - return state -end - -def pbRestoreSpriteState(sprite, state) - return if !state || !sprite || sprite.disposed? - sprite.x = state[SpriteMetafile::X] - sprite.y = state[SpriteMetafile::Y] - sprite.src_rect = state[SpriteMetafile::SRC_RECT] - sprite.visible = state[SpriteMetafile::VISIBLE] - sprite.z = state[SpriteMetafile::Z] - sprite.ox = state[SpriteMetafile::OX] - sprite.oy = state[SpriteMetafile::OY] - sprite.zoom_x = state[SpriteMetafile::ZOOM_X] - sprite.zoom_y = state[SpriteMetafile::ZOOM_Y] - sprite.angle = state[SpriteMetafile::ANGLE] - sprite.mirror = state[SpriteMetafile::MIRROR] - sprite.bush_depth = state[SpriteMetafile::BUSH_DEPTH] - sprite.opacity = state[SpriteMetafile::OPACITY] - sprite.blend_type = state[SpriteMetafile::BLEND_TYPE] - sprite.color = state[SpriteMetafile::COLOR] - sprite.tone = state[SpriteMetafile::TONE] -end - -def pbSaveSpriteStateAndBitmap(sprite) - return [] if !sprite || sprite.disposed? - state = pbSaveSpriteState(sprite) - state[SpriteMetafile::BITMAP] = sprite.bitmap - return state -end - -def pbRestoreSpriteStateAndBitmap(sprite, state) - return if !state || !sprite || sprite.disposed? - sprite.bitmap = state[SpriteMetafile::BITMAP] - pbRestoreSpriteState(sprite, state) - return state -end - #=============================================================================== # Evolution screen #=============================================================================== class PokemonEvolutionScene - private - - def pbGenerateMetafiles(s1x, s1y, s2x, s2y) - sprite = SpriteMetafile.new - sprite.ox = s1x - sprite.oy = s1y - sprite.opacity = 255 - sprite2 = SpriteMetafile.new - sprite2.ox = s2x - sprite2.oy = s2y - sprite2.zoom = 0.0 - sprite2.opacity = 255 - alpha = 0 - alphaDiff = 10 * 20 / Graphics.frame_rate - loop do - sprite.color.red = 255 - sprite.color.green = 255 - sprite.color.blue = 255 - sprite.color.alpha = alpha - sprite.color = sprite.color - sprite2.color = sprite.color - sprite2.color.alpha = 255 - sprite.update - sprite2.update - break if alpha >= 255 - alpha += alphaDiff - end - totaltempo = 0 - currenttempo = 25 - maxtempo = 7 * Graphics.frame_rate - while totaltempo < maxtempo - currenttempo.times do |j| - if alpha < 255 - sprite.color.red = 255 - sprite.color.green = 255 - sprite.color.blue = 255 - sprite.color.alpha = alpha - sprite.color = sprite.color - alpha += 10 - end - sprite.zoom = [1.1 * (currenttempo - j - 1) / currenttempo, 1.0].min - sprite2.zoom = [1.1 * (j + 1) / currenttempo, 1.0].min - sprite.update - sprite2.update - end - totaltempo += currenttempo - if totaltempo + currenttempo < maxtempo - currenttempo.times do |j| - sprite.zoom = [1.1 * (j + 1) / currenttempo, 1.0].min - sprite2.zoom = [1.1 * (currenttempo - j - 1) / currenttempo, 1.0].min - sprite.update - sprite2.update - end - end - totaltempo += currenttempo - currenttempo = [(currenttempo / 1.5).floor, 5].max - end - @metafile1 = sprite - @metafile2 = sprite2 - end - - public - - def pbUpdate(animating = false) - if animating # Pokémon shouldn't animate during the evolution animation - @sprites["background"].update - @sprites["msgwindow"].update - else - pbUpdateSpriteHash(@sprites) - end - end - - def pbUpdateNarrowScreen(timer_start) - return if @bgviewport.rect.y >= 80 - buffer = 80 - @bgviewport.rect.height = Graphics.height - lerp(0, 64 + (buffer * 2), 0.7, timer_start, System.uptime).to_i - @bgviewport.rect.y = lerp(0, buffer, 0.5, timer_start + 0.2, System.uptime).to_i - @sprites["background"].oy = @bgviewport.rect.y - end - - def pbUpdateExpandScreen(timer_start) - return if @bgviewport.rect.height >= Graphics.height - buffer = 80 - @bgviewport.rect.height = Graphics.height - lerp(64 + (buffer * 2), 0, 0.7, timer_start, System.uptime).to_i - @bgviewport.rect.y = lerp(buffer, 0, 0.5, timer_start, System.uptime).to_i - @sprites["background"].oy = @bgviewport.rect.y - end - - def pbFlashInOut(canceled, oldstate, oldstate2) - timer_start = System.uptime - loop do - Graphics.update - pbUpdate(true) - pbUpdateExpandScreen(timer_start) - tone = lerp(0, 255, 0.7, timer_start, System.uptime) - @viewport.tone.set(tone, tone, tone, 0) - break if tone >= 255 - end - @bgviewport.rect.y = 0 - @bgviewport.rect.height = Graphics.height - @sprites["background"].oy = 0 - if canceled - pbRestoreSpriteState(@sprites["rsprite1"], oldstate) - pbRestoreSpriteState(@sprites["rsprite2"], oldstate2) - @sprites["rsprite1"].zoom_x = 1.0 - @sprites["rsprite1"].zoom_y = 1.0 - @sprites["rsprite1"].color.alpha = 0 - @sprites["rsprite1"].visible = true - @sprites["rsprite2"].visible = false - else - @sprites["rsprite1"].visible = false - @sprites["rsprite2"].visible = true - @sprites["rsprite2"].zoom_x = 1.0 - @sprites["rsprite2"].zoom_y = 1.0 - @sprites["rsprite2"].color.alpha = 0 - end - timer_start = System.uptime - loop do - Graphics.update - pbUpdate(true) - break if System.uptime - timer_start >= 0.25 - end - timer_start = System.uptime - loop do - Graphics.update - pbUpdate - pbUpdateExpandScreen(timer_start) - tone = lerp(255, 0, 0.4, timer_start, System.uptime) - @viewport.tone.set(tone, tone, tone, 0) - break if tone <= 0 - end + def self.pbDuplicatePokemon(pkmn, new_species) + new_pkmn = pkmn.clone + new_pkmn.species = new_species + new_pkmn.name = nil + new_pkmn.markings = [] + new_pkmn.poke_ball = :POKEBALL + new_pkmn.item = nil + new_pkmn.clearAllRibbons + new_pkmn.calc_stats + new_pkmn.heal + # Add duplicate Pokémon to party + $player.party.push(new_pkmn) + # See and own duplicate Pokémon + $player.pokedex.register(new_pkmn) + $player.pokedex.set_owned(new_species) end def pbStartScreen(pokemon, newspecies) @@ -502,32 +41,47 @@ class PokemonEvolutionScene rsprite2.setPokemonBitmapSpecies(@pokemon, @newspecies, false) rsprite2.x = rsprite1.x rsprite2.y = rsprite1.y - rsprite2.opacity = 0 + rsprite2.visible = false @sprites["rsprite1"] = rsprite1 @sprites["rsprite2"] = rsprite2 - pbGenerateMetafiles(rsprite1.ox, rsprite1.oy, rsprite2.ox, rsprite2.oy) @sprites["msgwindow"] = pbCreateMessageWindow(@msgviewport) + set_up_animation pbFadeInAndShow(@sprites) { pbUpdate } end - # Closes the evolution screen. - def pbEndScreen(need_fade_out = true) - pbDisposeMessageWindow(@sprites["msgwindow"]) if @sprites["msgwindow"] - if need_fade_out - pbFadeOutAndHide(@sprites) { pbUpdate } + def set_up_animation + sprite = PictureEx.new(0) + sprite.setVisible(0, true) + sprite.setColor(0, Color.new(255, 255, 255, 0)) + sprite2 = PictureEx.new(0) + sprite2.setVisible(0, true) + sprite2.setZoom(0, 0.0) + sprite2.setColor(0, Color.new(255, 255, 255, 255)) + # Make sprite turn white + sprite.moveColor(0, 25, Color.new(255, 255, 255, 255)) + total_duration = 9 * 20 # 9 seconds + duration = 25 + 15 + zoom_duration = 12 + loop do + # Shrink prevo sprite, enlarge evo sprite + sprite.moveZoom(duration, zoom_duration, 0) + sprite2.moveZoom(duration, zoom_duration, 110) + duration += zoom_duration + # If animation has played for long enough, end it now while the evo sprite is large + break if duration >= total_duration + # Enlarge prevo sprite, shrink evo sprite + sprite.moveZoom(duration, zoom_duration, 110) + sprite2.moveZoom(duration, zoom_duration, 0) + duration += zoom_duration + # Shorten the duration of zoom changes for the next cycle + zoom_duration = [(zoom_duration / 1.2).round, 2].max end - pbDisposeSpriteHash(@sprites) - @viewport.dispose - @bgviewport.dispose - @msgviewport.dispose + @picture1 = sprite + @picture2 = sprite2 end # Opens the evolution screen def pbEvolution(cancancel = true) - metaplayer1 = SpriteMetafilePlayer.new(@metafile1, @sprites["rsprite1"]) - metaplayer2 = SpriteMetafilePlayer.new(@metafile2, @sprites["rsprite2"]) - metaplayer1.play - metaplayer2.play pbBGMStop pbMessageDisplay(@sprites["msgwindow"], "\\se[]" + _INTL("What?") + "\1") { pbUpdate } pbPlayDecisionSE @@ -540,16 +94,24 @@ class PokemonEvolutionScene pbUpdate break if System.uptime - timer_start >= 1 end - oldstate = pbSaveSpriteState(@sprites["rsprite1"]) - oldstate2 = pbSaveSpriteState(@sprites["rsprite2"]) pbMEPlay("Evolution start") pbBGMPlay("Evolution") canceled = false timer_start = System.uptime loop do pbUpdateNarrowScreen(timer_start) - metaplayer1.update - metaplayer2.update + @picture1.update + setPictureSprite(@sprites["rsprite1"], @picture1) + if @sprites["rsprite1"].zoom_x > 1.0 + @sprites["rsprite1"].zoom_x = 1.0 + @sprites["rsprite1"].zoom_y = 1.0 + end + @picture2.update + setPictureSprite(@sprites["rsprite2"], @picture2) + if @sprites["rsprite2"].zoom_x > 1.0 + @sprites["rsprite2"].zoom_x = 1.0 + @sprites["rsprite2"].zoom_y = 1.0 + end Graphics.update Input.update pbUpdate(true) @@ -559,9 +121,9 @@ class PokemonEvolutionScene canceled = true break end - break unless metaplayer1.playing? && metaplayer2.playing? + break if !@picture1.running? && !@picture2.running? end - pbFlashInOut(canceled, oldstate, oldstate2) + pbFlashInOut(canceled) if canceled $stats.evolutions_cancelled += 1 pbMessageDisplay(@sprites["msgwindow"], @@ -571,6 +133,65 @@ class PokemonEvolutionScene end end + def pbUpdateNarrowScreen(timer_start) + return if @bgviewport.rect.y >= 80 + buffer = 80 + @bgviewport.rect.height = Graphics.height - lerp(0, 64 + (buffer * 2), 0.7, timer_start, System.uptime).to_i + @bgviewport.rect.y = lerp(0, buffer, 0.5, timer_start + 0.2, System.uptime).to_i + @sprites["background"].oy = @bgviewport.rect.y + end + + def pbUpdateExpandScreen(timer_start) + return if @bgviewport.rect.height >= Graphics.height + buffer = 80 + @bgviewport.rect.height = Graphics.height - lerp(64 + (buffer * 2), 0, 0.7, timer_start, System.uptime).to_i + @bgviewport.rect.y = lerp(buffer, 0, 0.5, timer_start, System.uptime).to_i + @sprites["background"].oy = @bgviewport.rect.y + end + + def pbFlashInOut(canceled) + timer_start = System.uptime + loop do + Graphics.update + pbUpdate(true) + pbUpdateExpandScreen(timer_start) + tone = lerp(0, 255, 0.7, timer_start, System.uptime) + @viewport.tone.set(tone, tone, tone, 0) + break if tone >= 255 + end + @bgviewport.rect.y = 0 + @bgviewport.rect.height = Graphics.height + @sprites["background"].oy = 0 + if canceled + @sprites["rsprite1"].visible = true + @sprites["rsprite1"].zoom_x = 1.0 + @sprites["rsprite1"].zoom_y = 1.0 + @sprites["rsprite1"].color.alpha = 0 + @sprites["rsprite2"].visible = false + else + @sprites["rsprite1"].visible = false + @sprites["rsprite2"].visible = true + @sprites["rsprite2"].zoom_x = 1.0 + @sprites["rsprite2"].zoom_y = 1.0 + @sprites["rsprite2"].color.alpha = 0 + end + timer_start = System.uptime + loop do + Graphics.update + pbUpdate(true) + break if System.uptime - timer_start >= 0.25 + end + timer_start = System.uptime + loop do + Graphics.update + pbUpdate + pbUpdateExpandScreen(timer_start) + tone = lerp(255, 0, 0.4, timer_start, System.uptime) + @viewport.tone.set(tone, tone, tone, 0) + break if tone <= 0 + end + end + def pbEvolutionSuccess $stats.evolution_count += 1 # Play cry of evolved species @@ -631,20 +252,24 @@ class PokemonEvolutionScene @pokemon.action_after_evolution(@newspecies) end - def self.pbDuplicatePokemon(pkmn, new_species) - new_pkmn = pkmn.clone - new_pkmn.species = new_species - new_pkmn.name = nil - new_pkmn.markings = [] - new_pkmn.poke_ball = :POKEBALL - new_pkmn.item = nil - new_pkmn.clearAllRibbons - new_pkmn.calc_stats - new_pkmn.heal - # Add duplicate Pokémon to party - $player.party.push(new_pkmn) - # See and own duplicate Pokémon - $player.pokedex.register(new_pkmn) - $player.pokedex.set_owned(new_species) + def pbUpdate(animating = false) + if animating # Pokémon shouldn't animate during the evolution animation + @sprites["background"].update + @sprites["msgwindow"].update + else + pbUpdateSpriteHash(@sprites) + end + end + + # Closes the evolution screen. + def pbEndScreen(need_fade_out = true) + pbDisposeMessageWindow(@sprites["msgwindow"]) if @sprites["msgwindow"] + if need_fade_out + pbFadeOutAndHide(@sprites) { pbUpdate } + end + pbDisposeSpriteHash(@sprites) + @viewport.dispose + @bgviewport.dispose + @msgviewport.dispose end end diff --git a/Data/Scripts/016_UI/001_Non-interactive UI/006_UI_HallOfFame.rb b/Data/Scripts/016_UI/001_Non-interactive UI/006_UI_HallOfFame.rb index cb80f12b1..941298428 100644 --- a/Data/Scripts/016_UI/001_Non-interactive UI/006_UI_HallOfFame.rb +++ b/Data/Scripts/016_UI/001_Non-interactive UI/006_UI_HallOfFame.rb @@ -17,30 +17,31 @@ class HallOfFame_Scene # When true, all pokémon will be in one line # When false, all pokémon will be in two lines - SINGLEROW = false + SINGLE_ROW_OF_POKEMON = false # Make the pokémon movement ON in hall entry ANIMATION = true # Speed in pokémon movement in hall entry. Don't use less than 2! ANIMATIONSPEED = 32 - # Entry wait time (in 1/20 seconds) between showing each Pokémon (and trainer) - ENTRYWAITTIME = 64 + # Entry wait time (in seconds) between showing each Pokémon (and trainer). + # Waits for twice this tme when showing "Welcome to the Hall of Fame!". + ENTRY_WAIT_TIME = 3.0 # Maximum number limit of simultaneous hall entries saved. # 0 = Doesn't save any hall. -1 = no limit # Prefer to use larger numbers (like 500 and 1000) than don't put a limit # If a player exceed this limit, the first one will be removed - HALLLIMIT = 50 + HALL_ENTRIES_LIMIT = 50 # The entry music name. Put "" to doesn't play anything - ENTRYMUSIC = "Hall of Fame" + HALL_OF_FAME_BGM = "Hall of Fame" # Allow eggs to be show and saved in hall - ALLOWEGGS = true + ALLOW_EGGS = true # Remove the hallbars when the trainer sprite appears - REMOVEBARS = true + REMOVE_BARS_WHEN_SHOWING_TRAINER = true # The final fade speed on entry - FINALFADESPEED = 16 - # Sprites opacity value when them aren't selected + FINAL_FADE_DURATION = 1.0 + # Sprite's opacity value when it isn't selected OPACITY = 64 - BASECOLOR = Color.new(248, 248, 248) - SHADOWCOLOR = Color.new(0, 0, 0) + TEXT_BASE_COLOR = Color.new(248, 248, 248) + TEXT_SHADOW_COLOR = Color.new(0, 0, 0) # Placement for pokemon icons def pbStartScene @@ -64,8 +65,8 @@ class HallOfFame_Scene def pbStartSceneEntry pbStartScene - @useMusic = (ENTRYMUSIC && ENTRYMUSIC != "") - pbBGMPlay(ENTRYMUSIC) if @useMusic + @useMusic = (HALL_OF_FAME_BGM && HALL_OF_FAME_BGM != "") + pbBGMPlay(HALL_OF_FAME_BGM) if @useMusic saveHallEntry @xmovement = [] @ymovement = [] @@ -90,22 +91,15 @@ class HallOfFame_Scene @viewport.dispose end - def slowFadeOut(sprites, exponent) # 2 exponent - # To handle values above 8 - extraWaitExponent = exponent - 9 - exponent = 8 if exponent > 8 - max = 2**exponent - speed = (2**8) / max - (0..max).each do |j| - if extraWaitExponent > -1 - (2**extraWaitExponent).times do - Graphics.update - Input.update - pbUpdate - end - end - pbSetSpritesToColor(sprites, Color.new(0, 0, 0, j * speed)) - block_given? ? yield : pbUpdateSpriteHash(sprites) + def slowFadeOut(duration) + timer_start = System.uptime + loop do + alpha = lerp(255, 0, duration, timer_start, System.uptime) + pbSetSpritesToColor(@sprites, Color.new(0, 0, 0, alpha)) + Graphics.update + Input.update + pbUpdate + break if alpha == 0 end end @@ -125,20 +119,21 @@ class HallOfFame_Scene def saveHallEntry $player.party.each do |pkmn| # Clones every pokémon object - @hallEntry.push(pkmn.clone) if !pkmn.egg? || ALLOWEGGS + @hallEntry.push(pkmn.clone) if !pkmn.egg? || ALLOW_EGGS end # Update the global variables $PokemonGlobal.hallOfFame.push(@hallEntry) $PokemonGlobal.hallOfFameLastNumber += 1 - $PokemonGlobal.hallOfFame.delete_at(0) if HALLLIMIT > -1 && - $PokemonGlobal.hallOfFame.size > HALLLIMIT + if HALL_ENTRIES_LIMIT >= 0 && $PokemonGlobal.hallOfFame.size > HALL_ENTRIES_LIMIT + $PokemonGlobal.hallOfFame.delete_at(0) + end end # Return the x/y point position in screen for battler index number # Don't use odd numbers! def xpointformula(battlernumber) ret = 0 - if SINGLEROW + if SINGLE_ROW_OF_POKEMON ret = ((60 * (battlernumber / 2)) + 48) * (xpositionformula(battlernumber) - 1) ret += (Graphics.width / 2) - 56 else @@ -149,7 +144,7 @@ class HallOfFame_Scene def ypointformula(battlernumber) ret = 0 - if SINGLEROW + if SINGLE_ROW_OF_POKEMON ret = 96 - (8 * (battlernumber / 2)) else ret = 32 + (128 * ypositionformula(battlernumber) / 2) @@ -160,7 +155,7 @@ class HallOfFame_Scene # Returns 0, 1 or 2 as the x/y column value def xpositionformula(battlernumber) ret = 0 - if SINGLEROW + if SINGLE_ROW_OF_POKEMON ret = (battlernumber % 2) * 2 else ret = (battlernumber / 3).even? ? (19 - battlernumber) % 3 : (19 + battlernumber) % 3 @@ -170,7 +165,7 @@ class HallOfFame_Scene def ypositionformula(battlernumber) ret = 0 - if SINGLEROW + if SINGLE_ROW_OF_POKEMON ret = 1 else ret = ((battlernumber / 3) % 2) * 2 @@ -219,7 +214,7 @@ class HallOfFame_Scene @sprites["pokemon#{i}"].x += (128 - @sprites["pokemon#{i}"].bitmap.width) / 2 @sprites["pokemon#{i}"].y += (128 - @sprites["pokemon#{i}"].bitmap.height) / 2 end - @sprites["pokemon#{i}"].z = 7 - i if SINGLEROW + @sprites["pokemon#{i}"].z = 7 - i if SINGLE_ROW_OF_POKEMON next if !hide # Animation distance calculation horizontal = 1 - xpositionformula(i) @@ -244,7 +239,7 @@ class HallOfFame_Scene def createTrainerBattler @sprites["trainer"] = IconSprite.new(@viewport) @sprites["trainer"].setBitmap(GameData::TrainerType.front_sprite_filename($player.trainer_type)) - if SINGLEROW + if SINGLE_ROW_OF_POKEMON @sprites["trainer"].x = Graphics.width / 2 @sprites["trainer"].y = 178 else @@ -254,22 +249,24 @@ class HallOfFame_Scene @sprites["trainer"].z = 9 @sprites["trainer"].ox = @sprites["trainer"].bitmap.width / 2 @sprites["trainer"].oy = @sprites["trainer"].bitmap.height / 2 - if REMOVEBARS + if REMOVE_BARS_WHEN_SHOWING_TRAINER @sprites["overlay"].bitmap.clear @sprites["hallbars"].visible = false end @xmovement[@battlerIndex] = 0 @ymovement[@battlerIndex] = 0 - if ANIMATION && !SINGLEROW # Trainer Animation + if ANIMATION && !SINGLE_ROW_OF_POKEMON # Trainer Animation startpoint = Graphics.width / 2 # 2 is the trainer speed @xmovement[@battlerIndex] = (startpoint - @sprites["trainer"].x) / 2 @sprites["trainer"].x = startpoint else - ENTRYWAITTIME.times do + timer_start = System.uptime + loop do Graphics.update Input.update pbUpdate + break if System.uptime - timer_start >= ENTRY_WAIT_TIME end end end @@ -319,16 +316,16 @@ class HallOfFame_Scene dexnumber = _ISPRINTF("No. {1:03d}", number) end textPositions = [ - [dexnumber, 32, Graphics.height - 74, :left, BASECOLOR, SHADOWCOLOR], - [pokename, Graphics.width - 192, Graphics.height - 74, :center, BASECOLOR, SHADOWCOLOR], + [dexnumber, 32, Graphics.height - 74, :left, TEXT_BASE_COLOR, TEXT_SHADOW_COLOR], + [pokename, Graphics.width - 192, Graphics.height - 74, :center, TEXT_BASE_COLOR, TEXT_SHADOW_COLOR], [_INTL("Lv. {1}", pokemon.egg? ? "?" : pokemon.level), - 64, Graphics.height - 42, :left, BASECOLOR, SHADOWCOLOR], + 64, Graphics.height - 42, :left, TEXT_BASE_COLOR, TEXT_SHADOW_COLOR], [_INTL("ID No. {1}", pokemon.egg? ? "?????" : idno), - Graphics.width - 192, Graphics.height - 42, :center, BASECOLOR, SHADOWCOLOR] + Graphics.width - 192, Graphics.height - 42, :center, TEXT_BASE_COLOR, TEXT_SHADOW_COLOR] ] if hallNumber > -1 - textPositions.push([_INTL("Hall of Fame No."), (Graphics.width / 2) - 104, 6, :left, BASECOLOR, SHADOWCOLOR]) - textPositions.push([hallNumber.to_s, (Graphics.width / 2) + 104, 6, :right, BASECOLOR, SHADOWCOLOR]) + textPositions.push([_INTL("Hall of Fame No."), (Graphics.width / 2) - 104, 6, :left, TEXT_BASE_COLOR, TEXT_SHADOW_COLOR]) + textPositions.push([hallNumber.to_s, (Graphics.width / 2) + 104, 6, :right, TEXT_BASE_COLOR, TEXT_SHADOW_COLOR]) end pbDrawTextPositions(overlay, textPositions) end @@ -337,7 +334,7 @@ class HallOfFame_Scene overlay = @sprites["overlay"].bitmap overlay.clear pbDrawTextPositions(overlay, [[_INTL("Welcome to the Hall of Fame!"), - Graphics.width / 2, Graphics.height - 68, :center, BASECOLOR, SHADOWCOLOR]]) + Graphics.width / 2, Graphics.height - 68, :center, TEXT_BASE_COLOR, TEXT_SHADOW_COLOR]]) end def pbAnimationLoop @@ -386,26 +383,30 @@ class HallOfFame_Scene @battlerIndex += 1 if @battlerIndex <= @hallEntry.size # If it is a pokémon, write the pokémon text, wait the - # ENTRYWAITTIME and goes to the next battler + # ENTRY_WAIT_TIME and goes to the next battler @hallEntry[@battlerIndex - 1].play_cry writePokemonData(@hallEntry[@battlerIndex - 1]) - (ENTRYWAITTIME * Graphics.frame_rate / 20).times do + timer_start = System.uptime + loop do Graphics.update Input.update pbUpdate + break if System.uptime - timer_start >= ENTRY_WAIT_TIME end if @battlerIndex < @hallEntry.size # Preparates the next battler setPokemonSpritesOpacity(@battlerIndex, OPACITY) @sprites["overlay"].bitmap.clear - else # Show the welcome message and preparates the trainer + else # Show the welcome message and prepares the trainer setPokemonSpritesOpacity(-1) writeWelcome - (ENTRYWAITTIME * 2 * Graphics.frame_rate / 20).times do + timer_start = System.uptime + loop do Graphics.update Input.update pbUpdate + break if System.uptime - timer_start >= ENTRY_WAIT_TIME * 2 end - setPokemonSpritesOpacity(-1, OPACITY) if !SINGLEROW + setPokemonSpritesOpacity(-1, OPACITY) if !SINGLE_ROW_OF_POKEMON createTrainerBattler end end @@ -413,14 +414,15 @@ class HallOfFame_Scene elsif @battlerIndex > @hallEntry.size # Write the trainer data and fade writeTrainerData - (ENTRYWAITTIME * Graphics.frame_rate / 20).times do + timer_start = System.uptime + loop do Graphics.update Input.update pbUpdate + break if System.uptime - timer_start >= ENTRY_WAIT_TIME end - fadeSpeed = ((Math.log(2**12) - Math.log(FINALFADESPEED)) / Math.log(2)).floor - pbBGMFade((2**fadeSpeed).to_f / 20) if @useMusic - slowFadeOut(@sprites, fadeSpeed) { pbUpdate } + pbBGMFade(FINAL_FADE_DURATION) if @useMusic + slowFadeOut(FINAL_FADE_DURATION) @alreadyFadedInEnd = true @battlerIndex += 1 end diff --git a/Data/Scripts/016_UI/004_UI_Pokedex_Entry.rb b/Data/Scripts/016_UI/004_UI_Pokedex_Entry.rb index 5751c2009..5482942db 100644 --- a/Data/Scripts/016_UI/004_UI_Pokedex_Entry.rb +++ b/Data/Scripts/016_UI/004_UI_Pokedex_Entry.rb @@ -124,8 +124,12 @@ class PokemonPokedexInfo_Scene def pbUpdate if @page == 2 - intensity = (Graphics.frame_count % 40) * 12 - intensity = 480 - intensity if intensity > 240 + intensity_time = System.uptime % 1.0 # 1 second per glow + if intensity_time >= 0.5 + intensity = lerp(64, 256 + 64, 0.5, intensity_time - 0.5) + else + intensity = lerp(256 + 64, 64, 0.5, intensity_time) + end @sprites["areahighlight"].opacity = intensity end pbUpdateSpriteHash(@sprites) diff --git a/Data/Scripts/016_UI/017_UI_PokemonStorage.rb b/Data/Scripts/016_UI/017_UI_PokemonStorage.rb index d3ef4b291..170a22293 100644 --- a/Data/Scripts/016_UI/017_UI_PokemonStorage.rb +++ b/Data/Scripts/016_UI/017_UI_PokemonStorage.rb @@ -108,9 +108,32 @@ end # #=============================================================================== class AutoMosaicPokemonSprite < MosaicPokemonSprite + INITIAL_MOSAIC = 10 # Pixellation factor + + def mosaic=(value) + @mosaic = value + @mosaic = 0 if @mosaic < 0 + @start_mosaic = @mosaic if !@start_mosaic + end + + def mosaic_duration=(val) + @mosaic_duration = val + @mosaic_duration = 0 if @mosaic_duration < 0 + @mosaic_timer_start = System.uptime if @mosaic_duration > 0 + end + def update super - self.mosaic -= 1 + if @mosaic_timer_start + @start_mosaic = INITIAL_MOSAIC if !@start_mosaic || @start_mosaic == 0 + new_mosaic = lerp(@start_mosaic, 0, @mosaic_duration, @mosaic_timer_start, System.uptime).to_i + self.mosaic = new_mosaic + mosaicRefresh(@oldbitmap) + if new_mosaic == 0 + @mosaic_timer_start = nil + @start_mosaic = nil + end + end end end @@ -120,16 +143,17 @@ end class PokemonBoxArrow < Sprite attr_accessor :quickswap + # Time in seconds for the cursor to move down and back up to grab/drop a + # Pokémon. + GRAB_TIME = 0.4 + def initialize(viewport = nil) super(viewport) - @frame = 0 - @holding = false - @updating = false - @quickswap = false - @grabbingState = 0 - @placingState = 0 - @heldpkmn = nil - @handsprite = ChangelingSprite.new(0, 0, viewport) + @holding = false + @updating = false + @quickswap = false + @heldpkmn = nil + @handsprite = ChangelingSprite.new(0, 0, viewport) @handsprite.addBitmap("point1", "Graphics/UI/Storage/cursor_point_1") @handsprite.addBitmap("point2", "Graphics/UI/Storage/cursor_point_2") @handsprite.addBitmap("grab", "Graphics/UI/Storage/cursor_grab") @@ -149,38 +173,6 @@ class PokemonBoxArrow < Sprite super end - def heldPokemon - @heldpkmn = nil if @heldpkmn&.disposed? - @holding = false if !@heldpkmn - return @heldpkmn - end - - def visible=(value) - super - @handsprite.visible = value - sprite = heldPokemon - sprite.visible = value if sprite - end - - def color=(value) - super - @handsprite.color = value - sprite = heldPokemon - sprite.color = value if sprite - end - - def holding? - return self.heldPokemon && @holding - end - - def grabbing? - return @grabbingState > 0 - end - - def placing? - return @placingState > 0 - end - def x=(value) super @handsprite.x = self.x @@ -200,6 +192,38 @@ class PokemonBoxArrow < Sprite @handsprite.z = value end + def visible=(value) + super + @handsprite.visible = value + sprite = heldPokemon + sprite.visible = value if sprite + end + + def color=(value) + super + @handsprite.color = value + sprite = heldPokemon + sprite.color = value if sprite + end + + def heldPokemon + @heldpkmn = nil if @heldpkmn&.disposed? + @holding = false if !@heldpkmn + return @heldpkmn + end + + def holding? + return self.heldPokemon && @holding + end + + def grabbing? + return !@grabbing_timer_start.nil? + end + + def placing? + return !@placing_timer_start.nil? + end + def setSprite(sprite) if holding? @heldpkmn = sprite @@ -219,7 +243,7 @@ class PokemonBoxArrow < Sprite end def grab(sprite) - @grabbingState = 1 + @grabbing_timer_start = System.uptime @heldpkmn = sprite @heldpkmn.viewport = self.viewport @heldpkmn.z = 1 @@ -227,7 +251,7 @@ class PokemonBoxArrow < Sprite end def place - @placingState = 1 + @placing_timer_start = System.uptime end def release @@ -241,46 +265,40 @@ class PokemonBoxArrow < Sprite heldpkmn&.update @handsprite.update @holding = false if !heldpkmn - if @grabbingState > 0 - if @grabbingState <= 4 * Graphics.frame_rate / 20 + if @grabbing_timer_start + if System.uptime - @grabbing_timer_start <= GRAB_TIME / 2 @handsprite.changeBitmap((@quickswap) ? "grabq" : "grab") - self.y = @spriteY + (4.0 * @grabbingState * 20 / Graphics.frame_rate) - @grabbingState += 1 - elsif @grabbingState <= 8 * Graphics.frame_rate / 20 + self.y = @spriteY + lerp(0, 16, GRAB_TIME / 2, @grabbing_timer_start, System.uptime) + else @holding = true @handsprite.changeBitmap((@quickswap) ? "fistq" : "fist") - self.y = @spriteY + (4 * ((8 * Graphics.frame_rate / 20) - @grabbingState) * 20 / Graphics.frame_rate) - @grabbingState += 1 - else - @grabbingState = 0 + delta_y = lerp(16, 0, GRAB_TIME / 2, @grabbing_timer_start + (GRAB_TIME / 2), System.uptime) + self.y = @spriteY + delta_y + @grabbing_timer_start = nil if delta_y == 0 end - elsif @placingState > 0 - if @placingState <= 4 * Graphics.frame_rate / 20 + elsif @placing_timer_start + if System.uptime - @placing_timer_start <= GRAB_TIME / 2 @handsprite.changeBitmap((@quickswap) ? "fistq" : "fist") - self.y = @spriteY + (4.0 * @placingState * 20 / Graphics.frame_rate) - @placingState += 1 - elsif @placingState <= 8 * Graphics.frame_rate / 20 + self.y = @spriteY + lerp(0, 16, GRAB_TIME / 2, @placing_timer_start, System.uptime) + else @holding = false @heldpkmn = nil @handsprite.changeBitmap((@quickswap) ? "grabq" : "grab") - self.y = @spriteY + (4 * ((8 * Graphics.frame_rate / 20) - @placingState) * 20 / Graphics.frame_rate) - @placingState += 1 - else - @placingState = 0 + delta_y = lerp(16, 0, GRAB_TIME / 2, @placing_timer_start + (GRAB_TIME / 2), System.uptime) + self.y = @spriteY + delta_y + @placing_timer_start = nil if delta_y == 0 end elsif holding? @handsprite.changeBitmap((@quickswap) ? "fistq" : "fist") - else + else # Idling self.x = @spriteX self.y = @spriteY - if @frame < Graphics.frame_rate / 2 + if (System.uptime / 0.5).to_i.even? # Changes every 0.5 seconds @handsprite.changeBitmap((@quickswap) ? "point1q" : "point1") else @handsprite.changeBitmap((@quickswap) ? "point2q" : "point2") end end - @frame += 1 - @frame = 0 if @frame >= Graphics.frame_rate @updating = false end end @@ -902,7 +920,7 @@ class PokemonStorageScene ret = pbSelectPartyInternal(party, false) if ret < 0 pbHidePartyTab - @selection = 0 + @selection = -2 @choseFromParty = false else @choseFromParty = true @@ -997,44 +1015,38 @@ class PokemonStorageScene Input.update end - def pbSwitchBoxToRight(newbox) - newbox = PokemonBoxSprite.new(@storage, newbox, @boxviewport) - newbox.x = 520 - Graphics.frame_reset - distancePerFrame = 64 * 20 / Graphics.frame_rate + def pbSwitchBoxToRight(new_box_number) + start_x = @sprites["box"].x + newbox = PokemonBoxSprite.new(@storage, new_box_number, @boxviewport) + newbox.x = start_x + 336 + timer_start = System.uptime loop do - Graphics.update - Input.update - @sprites["box"].x -= distancePerFrame - newbox.x -= distancePerFrame + @sprites["box"].x = lerp(start_x, start_x - 336, 0.25, timer_start, System.uptime) + newbox.x = @sprites["box"].x + 336 self.update - break if newbox.x <= 184 + Graphics.update + break if newbox.x == start_x end - diff = newbox.x - 184 - newbox.x = 184 - @sprites["box"].x -= diff @sprites["box"].dispose @sprites["box"] = newbox + Input.update end - def pbSwitchBoxToLeft(newbox) - newbox = PokemonBoxSprite.new(@storage, newbox, @boxviewport) - newbox.x = -152 - Graphics.frame_reset - distancePerFrame = 64 * 20 / Graphics.frame_rate + def pbSwitchBoxToLeft(new_box_number) + start_x = @sprites["box"].x + newbox = PokemonBoxSprite.new(@storage, new_box_number, @boxviewport) + newbox.x = start_x - 336 + timer_start = System.uptime loop do - Graphics.update - Input.update - @sprites["box"].x += distancePerFrame - newbox.x += distancePerFrame + @sprites["box"].x = lerp(start_x, start_x + 336, 0.25, timer_start, System.uptime) + newbox.x = @sprites["box"].x - 336 self.update - break if newbox.x >= 184 + Graphics.update + break if newbox.x == start_x end - diff = newbox.x - 184 - newbox.x = 184 - @sprites["box"].x -= diff @sprites["box"].dispose @sprites["box"] = newbox + Input.update end def pbJumpToBox(newbox) @@ -1050,7 +1062,7 @@ class PokemonStorageScene def pbSetMosaic(selection) return if @screen.pbHeldPokemon return if @boxForMosaic == @storage.currentBox && @selectionForMosaic == selection - @sprites["pokemon"].mosaic = Graphics.frame_rate / 4 + @sprites["pokemon"].mosaic_duration = 0.25 # In seconds @boxForMosaic = @storage.currentBox @selectionForMosaic = selection end @@ -1061,29 +1073,43 @@ class PokemonStorageScene end def pbShowPartyTab - pbSEPlay("GUI storage show party panel") - distancePerFrame = 48 * 20 / Graphics.frame_rate - loop do - Graphics.update - Input.update - @sprites["boxparty"].y -= distancePerFrame - self.update - break if @sprites["boxparty"].y <= Graphics.height - 352 + @sprites["arrow"].visible = false + if !@screen.pbHeldPokemon + pbUpdateOverlay(-1) + pbSetMosaic(-1) end - @sprites["boxparty"].y = Graphics.height - 352 + pbSEPlay("GUI storage show party panel") + start_y = @sprites["boxparty"].y # Graphics.height + timer_start = System.uptime + loop do + @sprites["boxparty"].y = lerp(start_y, start_y - @sprites["boxparty"].height, + 0.4, timer_start, System.uptime) + self.update + Graphics.update + break if @sprites["boxparty"].y == start_y - @sprites["boxparty"].height + end + Input.update + @sprites["arrow"].visible = true end def pbHidePartyTab - pbSEPlay("GUI storage hide party panel") - distancePerFrame = 48 * 20 / Graphics.frame_rate - loop do - Graphics.update - Input.update - @sprites["boxparty"].y += distancePerFrame - self.update - break if @sprites["boxparty"].y >= Graphics.height + @sprites["arrow"].visible = false + if !@screen.pbHeldPokemon + pbUpdateOverlay(-1) + pbSetMosaic(-1) end - @sprites["boxparty"].y = Graphics.height + pbSEPlay("GUI storage hide party panel") + start_y = @sprites["boxparty"].y # Graphics.height - @sprites["boxparty"].height + timer_start = System.uptime + loop do + @sprites["boxparty"].y = lerp(start_y, start_y + @sprites["boxparty"].height, + 0.4, timer_start, System.uptime) + self.update + Graphics.update + break if @sprites["boxparty"].y == start_y + @sprites["boxparty"].height + end + Input.update + @sprites["arrow"].visible = true end def pbHold(selected) @@ -1115,7 +1141,7 @@ class PokemonStorageScene @sprites["box"].setPokemon(selected[1], heldpokesprite) end @sprites["arrow"].setSprite(boxpokesprite) - @sprites["pokemon"].mosaic = 10 + @sprites["pokemon"].mosaic_duration = 0.25 # In seconds @boxForMosaic = @storage.currentBox @selectionForMosaic = selected[1] end diff --git a/Data/Scripts/016_UI/025_UI_TextEntry.rb b/Data/Scripts/016_UI/025_UI_TextEntry.rb index d0b05d741..81afad451 100644 --- a/Data/Scripts/016_UI/025_UI_TextEntry.rb +++ b/Data/Scripts/016_UI/025_UI_TextEntry.rb @@ -479,7 +479,6 @@ class PokemonEntryScene2 @sprites["controls"].x = 16 @sprites["controls"].y = 96 @sprites["controls"].setBitmap(_INTL("Graphics/UI/Naming/overlay_controls")) - @init = true @sprites["overlay"] = BitmapSprite.new(Graphics.width, Graphics.height, @viewport) pbDoUpdateOverlay2 @sprites["cursor"] = NameEntryCursor.new(@viewport) @@ -556,15 +555,12 @@ class PokemonEntryScene2 @@Characters.length.times do |i| @bitmaps[i].update end - if @init || Graphics.frame_count % 5 == 0 - @init = false - cursorpos = @helper.cursor - cursorpos = @maxlength - 1 if cursorpos >= @maxlength - cursorpos = 0 if cursorpos < 0 - @maxlength.times do |i| - @blanks[i] = (i == cursorpos) ? 1 : 0 - @sprites["blank#{i}"].y = [78, 82][@blanks[i]] - end + # Update which inputted text's character's underline is lowered to indicate + # which character is selected + cursorpos = @helper.cursor.clamp(0, @maxlength - 1) + @maxlength.times do |i| + @blanks[i] = (i == cursorpos) ? 1 : 0 + @sprites["blank#{i}"].y = [78, 82][@blanks[i]] end pbDoUpdateOverlay pbUpdateSpriteHash(@sprites)