diff --git a/Data/Scripts/001_Technical/006_RPG_Sprite.rb b/Data/Scripts/001_Technical/006_RPG_Sprite.rb index 735b1de7a..200f25b4f 100644 --- a/Data/Scripts/001_Technical/006_RPG_Sprite.rb +++ b/Data/Scripts/001_Technical/006_RPG_Sprite.rb @@ -338,3 +338,34 @@ module RPG end end end + +#=============================================================================== +# A modification to class Sprite that allows its coordinates to be floats rather +# than integers. +#=============================================================================== +class Sprite + attr_accessor :float + + alias :__float__x :x + alias :__float__y :y + alias :__float__x_equals :x= + alias :__float__y_equals :y= + + def x + return (@float) ? @real_x : __float__x + end + + def y + return (@float) ? @real_y : __float__y + end + + def x=(value) + @real_x = value if @float + __float__x_equals(value) + end + + def y=(value) + @real_y = value if @float + __float__y_equals(value) + end +end diff --git a/Data/Scripts/005_Sprites/006_Spriteset_Global.rb b/Data/Scripts/005_Sprites/006_Spriteset_Global.rb index 4321676cf..20e871dde 100644 --- a/Data/Scripts/005_Sprites/006_Spriteset_Global.rb +++ b/Data/Scripts/005_Sprites/006_Spriteset_Global.rb @@ -5,8 +5,10 @@ class Spriteset_Global @@viewport2.z = 200 def initialize + @map_id = $game_map&.map_id || 0 @follower_sprites = FollowerSprites.new(Spriteset_Map.viewport) @playersprite = Sprite_Character.new(Spriteset_Map.viewport, $game_player) + @weather = RPG::Weather.new(Spriteset_Map.viewport) @picture_sprites = [] (1..100).each do |i| @picture_sprites.push(Sprite_Picture.new(@@viewport2, $game_screen.pictures[i])) @@ -20,6 +22,8 @@ class Spriteset_Global @follower_sprites = nil @playersprite.dispose @playersprite = nil + @weather.dispose + @weather = nil @picture_sprites.each { |sprite| sprite.dispose } @picture_sprites.clear @timer_sprite.dispose @@ -29,6 +33,23 @@ class Spriteset_Global def update @follower_sprites.update @playersprite.update + if @weather.type != $game_screen.weather_type + @weather.fade_in($game_screen.weather_type, $game_screen.weather_max, $game_screen.weather_duration) + end + if @map_id != $game_map.map_id + offsets = $map_factory.getRelativePos(@map_id, 0, 0, $game_map.map_id, 0, 0) + if offsets == [0, 0] + @weather.ox_offset = 0 + @weather.oy_offset = 0 + else + @weather.ox_offset += offsets[0] * Game_Map::TILE_WIDTH + @weather.oy_offset += offsets[1] * Game_Map::TILE_HEIGHT + end + @map_id = $game_map.map_id + end + @weather.ox = ($game_map.display_x / Game_Map::X_SUBPIXELS).round + @weather.oy = ($game_map.display_y / Game_Map::Y_SUBPIXELS).round + @weather.update @picture_sprites.each { |sprite| sprite.update } @timer_sprite.update end diff --git a/Data/Scripts/005_Sprites/007_Spriteset_Map.rb b/Data/Scripts/005_Sprites/007_Spriteset_Map.rb index 5972effb8..8d8cccf50 100644 --- a/Data/Scripts/005_Sprites/007_Spriteset_Map.rb +++ b/Data/Scripts/005_Sprites/007_Spriteset_Map.rb @@ -62,7 +62,6 @@ class Spriteset_Map sprite = Sprite_Character.new(@@viewport1, @map.events[i]) @character_sprites.push(sprite) end - @weather = RPG::Weather.new(@@viewport1) EventHandlers.trigger(:on_new_spriteset_map, self, @@viewport1) update end @@ -76,11 +75,9 @@ class Spriteset_Map @panorama.dispose @fog.dispose @character_sprites.each { |sprite| sprite.dispose } - @weather.dispose @panorama = nil @fog = nil @character_sprites.clear - @weather = nil end def getAnimations @@ -126,14 +123,6 @@ class Spriteset_Map @character_sprites.each do |sprite| sprite.update end - if self.map == $game_map - @weather.fade_in($game_screen.weather_type, $game_screen.weather_max, $game_screen.weather_duration) - else - @weather.fade_in(:None, 0, 20) - end - @weather.ox = tmox - @weather.oy = tmoy - @weather.update @@viewport1.tone = $game_screen.tone @@viewport3.color = $game_screen.flash_color @@viewport1.update diff --git a/Data/Scripts/012_Overworld/001_Overworld visuals/001_Overworld_Weather.rb b/Data/Scripts/012_Overworld/001_Overworld visuals/001_Overworld_Weather.rb index 5d9fb1171..d7337c96a 100644 --- a/Data/Scripts/012_Overworld/001_Overworld visuals/001_Overworld_Weather.rb +++ b/Data/Scripts/012_Overworld/001_Overworld visuals/001_Overworld_Weather.rb @@ -3,10 +3,10 @@ # bottom. module RPG class Weather - attr_reader :type - attr_reader :max - attr_reader :ox - attr_reader :oy + attr_reader :type + attr_reader :max + attr_reader :ox, :oy + attr_accessor :ox_offset, :oy_offset MAX_SPRITES = 60 FADE_OLD_TILES_START = 0 @@ -34,6 +34,8 @@ module RPG @max = 0 @ox = 0 @oy = 0 + @ox_offset = 0 + @oy_offset = 0 @tiles_wide = 0 @tiles_tall = 0 @tile_x = 0.0 @@ -128,17 +130,17 @@ module RPG def ox=(value) return if value == @ox @ox = value - @sprites.each { |sprite| sprite.ox = @ox if sprite } - @new_sprites.each { |sprite| sprite.ox = @ox if sprite } - @tiles.each { |sprite| sprite.ox = @ox if sprite } + @sprites.each { |sprite| sprite.ox = @ox + @ox_offset if sprite } + @new_sprites.each { |sprite| sprite.ox = @ox + @ox_offset if sprite } + @tiles.each { |sprite| sprite.ox = @ox + @ox_offset if sprite } end def oy=(value) return if value == @oy @oy = value - @sprites.each { |sprite| sprite.oy = @oy if sprite } - @new_sprites.each { |sprite| sprite.oy = @oy if sprite } - @tiles.each { |sprite| sprite.oy = @oy if sprite } + @sprites.each { |sprite| sprite.oy = @oy + @oy_offset if sprite } + @new_sprites.each { |sprite| sprite.oy = @oy + @oy_offset if sprite } + @tiles.each { |sprite| sprite.oy = @oy + @oy_offset if sprite } end def get_weather_tone(weather_type, maximum) @@ -163,9 +165,10 @@ module RPG MAX_SPRITES.times do |i| if !@sprites[i] sprite = Sprite.new(@origViewport) + sprite.float = true sprite.z = 1000 - sprite.ox = @ox - sprite.oy = @oy + sprite.ox = @ox + @ox_offset + sprite.oy = @oy + @oy_offset sprite.opacity = 0 @sprites[i] = sprite end @@ -178,9 +181,10 @@ module RPG MAX_SPRITES.times do |i| if !@new_sprites[i] sprite = Sprite.new(@origViewport) + sprite.float = true sprite.z = 1000 - sprite.ox = @ox - sprite.oy = @oy + sprite.ox = @ox + @ox_offset + sprite.oy = @oy + @oy_offset sprite.opacity = 0 @new_sprites[i] = sprite end @@ -195,9 +199,10 @@ module RPG (@tiles_wide * @tiles_tall).times do |i| if !@tiles[i] sprite = Sprite.new(@origViewport) + sprite.float = true sprite.z = 1000 - sprite.ox = @ox - sprite.oy = @oy + sprite.ox = @ox + @ox_offset + sprite.oy = @oy + @oy_offset sprite.opacity = 0 @tiles[i] = sprite end @@ -245,8 +250,8 @@ module RPG return end if @weatherTypes[weather_type][0].category == :Rain && index.odd? # Splash - sprite.x = @ox - sprite.bitmap.width + rand(Graphics.width + (sprite.bitmap.width * 2)) - sprite.y = @oy - sprite.bitmap.height + rand(Graphics.height + (sprite.bitmap.height * 2)) + sprite.x = @ox + @ox_offset - sprite.bitmap.width + rand(Graphics.width + (sprite.bitmap.width * 2)) + sprite.y = @oy + @oy_offset - sprite.bitmap.height + rand(Graphics.height + (sprite.bitmap.height * 2)) lifetimes[index] = (rand(30...50)) * 0.01 # 0.3-0.5 seconds else x_speed = @weatherTypes[weather_type][0].particle_delta_x @@ -254,15 +259,15 @@ module RPG gradient = x_speed.to_f / y_speed if gradient.abs >= 1 # Position sprite to the right of the screen - sprite.x = @ox + Graphics.width + rand(Graphics.width) - sprite.y = @oy + Graphics.height - rand(Graphics.height + sprite.bitmap.height - (Graphics.width / gradient)) - distance_to_cover = sprite.x - @ox - (Graphics.width / 2) + sprite.bitmap.width + rand(Graphics.width * 8 / 5) + sprite.x = @ox + @ox_offset + Graphics.width + rand(Graphics.width) + sprite.y = @oy + @oy_offset + Graphics.height - rand(Graphics.height + sprite.bitmap.height - (Graphics.width / gradient)) + distance_to_cover = sprite.x - @ox - @ox_offset - (Graphics.width / 2) + sprite.bitmap.width + rand(Graphics.width * 8 / 5) lifetimes[index] = (distance_to_cover.to_f / x_speed).abs else # Position sprite to the top of the screen - sprite.x = @ox - sprite.bitmap.width + rand(Graphics.width + sprite.bitmap.width - (gradient * Graphics.height)) - sprite.y = @oy - sprite.bitmap.height - rand(Graphics.height) - distance_to_cover = @oy - sprite.y + (Graphics.height / 2) + rand(Graphics.height * 8 / 5) + sprite.x = @ox + @ox_offset - sprite.bitmap.width + rand(Graphics.width + sprite.bitmap.width - (gradient * Graphics.height)) + sprite.y = @oy + @oy_offset - sprite.bitmap.height - rand(Graphics.height) + distance_to_cover = @oy + @oy_offset - sprite.y + (Graphics.height / 2) + rand(Graphics.height * 8 / 5) lifetimes[index] = (distance_to_cover.to_f / y_speed).abs end end @@ -291,17 +296,17 @@ module RPG sprite.x += dist_x sprite.y += dist_y if weather_type == :Snow - sprite.x += dist_x * (sprite.y - @oy) / (Graphics.height * 3) # Faster when further down screen + sprite.x += dist_x * (sprite.y - @oy - @oy_offset) / (Graphics.height * 3) # Faster when further down screen sprite.x += [2, 1, 0, -1][rand(4)] * dist_x / 8 # Random movement sprite.y += [2, 1, 1, 0, 0, -1][index % 6] * dist_y / 10 # Variety end - sprite.x -= Graphics.width if sprite.x - @ox > Graphics.width - sprite.x += Graphics.width if sprite.x - @ox < -sprite.width - sprite.y -= Graphics.height if sprite.y - @oy > Graphics.height - sprite.y += Graphics.height if sprite.y - @oy < -sprite.height + sprite.x -= Graphics.width if sprite.x - @ox - @ox_offset > Graphics.width + sprite.x += Graphics.width if sprite.x - @ox - @ox_offset < -sprite.width + sprite.y -= Graphics.height if sprite.y - @oy - @oy_offset > Graphics.height + sprite.y += Graphics.height if sprite.y - @oy - @oy_offset < -sprite.height sprite.opacity += @weatherTypes[weather_type][0].particle_delta_opacity * delta_t - x = sprite.x - @ox - y = sprite.y - @oy + x = sprite.x - @ox - @ox_offset + y = sprite.y - @oy - @oy_offset # Check if sprite is off-screen; if so, reset it if sprite.opacity < 64 || x < -sprite.bitmap.width || y > Graphics.height reset_sprite_position(sprite, index, is_new_sprite) @@ -317,16 +322,16 @@ module RPG end @tile_x += @weatherTypes[weather_type][0].tile_delta_x * delta_t @tile_y += @weatherTypes[weather_type][0].tile_delta_y * delta_t - while @tile_x < @ox - @weatherTypes[weather_type][2][0].width + while @tile_x < @ox + @ox_offset - @weatherTypes[weather_type][2][0].width @tile_x += @weatherTypes[weather_type][2][0].width end - while @tile_x > @ox + while @tile_x > @ox + @ox_offset @tile_x -= @weatherTypes[weather_type][2][0].width end - while @tile_y < @oy - @weatherTypes[weather_type][2][0].height + while @tile_y < @oy + @oy_offset - @weatherTypes[weather_type][2][0].height @tile_y += @weatherTypes[weather_type][2][0].height end - while @tile_y > @oy + while @tile_y > @oy + @oy_offset @tile_y -= @weatherTypes[weather_type][2][0].height end end @@ -335,15 +340,14 @@ module RPG return if !sprite || !sprite.bitmap || !sprite.visible sprite.x = @tile_x.round + ((index % @tiles_wide) * sprite.bitmap.width) sprite.y = @tile_y.round + ((index / @tiles_wide) * sprite.bitmap.height) - sprite.x += @tiles_wide * sprite.bitmap.width if sprite.x - @ox < -sprite.bitmap.width - sprite.y -= @tiles_tall * sprite.bitmap.height if sprite.y - @oy > Graphics.height + sprite.x += @tiles_wide * sprite.bitmap.width if sprite.x - @ox - @ox_offset < -sprite.bitmap.width + sprite.y -= @tiles_tall * sprite.bitmap.height if sprite.y - @oy - @oy_offset > Graphics.height sprite.visible = true if @fading && @type != @target_type - if @fade_time >= FADE_OLD_TILES_START && @fade_time < FADE_OLD_TILES_END - if @time_shift == 0 # There were old tiles to fade out - fraction = (@fade_time - [FADE_OLD_TILES_START - @time_shift, 0].max) / (FADE_OLD_TILES_END - FADE_OLD_TILES_START) - sprite.opacity = 255 * (1 - fraction) - end + if @fade_time >= FADE_OLD_TILES_START && @fade_time < FADE_OLD_TILES_END && + @time_shift == 0 # There were old tiles to fade out + fraction = (@fade_time - [FADE_OLD_TILES_START - @time_shift, 0].max) / (FADE_OLD_TILES_END - FADE_OLD_TILES_START) + sprite.opacity = 255 * (1 - fraction) elsif @fade_time >= [FADE_NEW_TILES_START - @time_shift, 0].max && @fade_time < [FADE_NEW_TILES_END - @time_shift, 0].max fraction = (@fade_time - [FADE_NEW_TILES_START - @time_shift, 0].max) / (FADE_NEW_TILES_END - FADE_NEW_TILES_START) @@ -513,7 +517,7 @@ module RPG @new_sprites.each { |sprite| sprite&.dispose } @new_sprites.clear end - # Update weather tiles (sandstorm/blizzard tiled overlay) + # Update weather tiles (sandstorm/blizzard/fog tiled overlay) if @tiles_wide > 0 && @tiles_tall > 0 ensureTiles recalculate_tile_positions diff --git a/Data/Scripts/012_Overworld/001_Overworld.rb b/Data/Scripts/012_Overworld/001_Overworld.rb index a996539fb..e95754925 100644 --- a/Data/Scripts/012_Overworld/001_Overworld.rb +++ b/Data/Scripts/012_Overworld/001_Overworld.rb @@ -220,24 +220,7 @@ end #=============================================================================== # Checks when moving between maps #=============================================================================== -# Clears the weather of the old map, if the old map has defined weather and the -# new map either has the same name as the old map or doesn't have defined -# weather. -EventHandlers.add(:on_leave_map, :end_weather, - proc { |new_map_id, new_map| - next if new_map_id == 0 - old_map_metadata = $game_map.metadata - next if !old_map_metadata || !old_map_metadata.weather - map_infos = pbLoadMapInfos - if $game_map.name == map_infos[new_map_id].name - new_map_metadata = GameData::MapMetadata.try_get(new_map_id) - next if new_map_metadata&.weather - end - $game_screen.weather(:None, 0, 0) - } -) - -# Set up various data related to the new map +# Set up various data related to the new map. EventHandlers.add(:on_enter_map, :setup_new_map, proc { |old_map_id| # previous map ID, is 0 if no map ID # Record new Teleport destination @@ -251,16 +234,21 @@ EventHandlers.add(:on_enter_map, :setup_new_map, $PokemonEncounters&.setup($game_map.map_id) # Record the new map as having been visited $PokemonGlobal.visitedMaps[$game_map.map_id] = true - # Set weather if new map has weather + } +) + +# Changes the overworld weather. +EventHandlers.add(:on_enter_map, :set_weather, + proc { |old_map_id| # previous map ID, is 0 if no map ID next if old_map_id == 0 || old_map_id == $game_map.map_id - next if !new_map_metadata || !new_map_metadata.weather - map_infos = pbLoadMapInfos - if $game_map.name == map_infos[old_map_id].name - old_map_metadata = GameData::MapMetadata.try_get(old_map_id) - next if old_map_metadata&.weather + old_weather = $game_screen.weather_type + new_weather = :None + new_map_metadata = $game_map.metadata + if new_map_metadata&.weather + new_weather = new_map_metadata.weather[0] if rand(100) < new_map_metadata.weather[1] end - new_weather = new_map_metadata.weather - $game_screen.weather(new_weather[0], 9, 0) if rand(100) < new_weather[1] + next if old_weather == new_weather + $game_screen.weather(new_weather, 9, 0) } )