Fixed overworld weather fading out/in when walking between maps with the same weather, added support for Sprite coordinates being floats

This commit is contained in:
Maruno17
2023-07-30 20:32:39 +01:00
parent 4f14108772
commit 4c25ade184
5 changed files with 113 additions and 80 deletions

View File

@@ -338,3 +338,34 @@ module RPG
end end
end 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

View File

@@ -5,8 +5,10 @@ class Spriteset_Global
@@viewport2.z = 200 @@viewport2.z = 200
def initialize def initialize
@map_id = $game_map&.map_id || 0
@follower_sprites = FollowerSprites.new(Spriteset_Map.viewport) @follower_sprites = FollowerSprites.new(Spriteset_Map.viewport)
@playersprite = Sprite_Character.new(Spriteset_Map.viewport, $game_player) @playersprite = Sprite_Character.new(Spriteset_Map.viewport, $game_player)
@weather = RPG::Weather.new(Spriteset_Map.viewport)
@picture_sprites = [] @picture_sprites = []
(1..100).each do |i| (1..100).each do |i|
@picture_sprites.push(Sprite_Picture.new(@@viewport2, $game_screen.pictures[i])) @picture_sprites.push(Sprite_Picture.new(@@viewport2, $game_screen.pictures[i]))
@@ -20,6 +22,8 @@ class Spriteset_Global
@follower_sprites = nil @follower_sprites = nil
@playersprite.dispose @playersprite.dispose
@playersprite = nil @playersprite = nil
@weather.dispose
@weather = nil
@picture_sprites.each { |sprite| sprite.dispose } @picture_sprites.each { |sprite| sprite.dispose }
@picture_sprites.clear @picture_sprites.clear
@timer_sprite.dispose @timer_sprite.dispose
@@ -29,6 +33,23 @@ class Spriteset_Global
def update def update
@follower_sprites.update @follower_sprites.update
@playersprite.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 } @picture_sprites.each { |sprite| sprite.update }
@timer_sprite.update @timer_sprite.update
end end

View File

@@ -62,7 +62,6 @@ class Spriteset_Map
sprite = Sprite_Character.new(@@viewport1, @map.events[i]) sprite = Sprite_Character.new(@@viewport1, @map.events[i])
@character_sprites.push(sprite) @character_sprites.push(sprite)
end end
@weather = RPG::Weather.new(@@viewport1)
EventHandlers.trigger(:on_new_spriteset_map, self, @@viewport1) EventHandlers.trigger(:on_new_spriteset_map, self, @@viewport1)
update update
end end
@@ -76,11 +75,9 @@ class Spriteset_Map
@panorama.dispose @panorama.dispose
@fog.dispose @fog.dispose
@character_sprites.each { |sprite| sprite.dispose } @character_sprites.each { |sprite| sprite.dispose }
@weather.dispose
@panorama = nil @panorama = nil
@fog = nil @fog = nil
@character_sprites.clear @character_sprites.clear
@weather = nil
end end
def getAnimations def getAnimations
@@ -126,14 +123,6 @@ class Spriteset_Map
@character_sprites.each do |sprite| @character_sprites.each do |sprite|
sprite.update sprite.update
end 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 @@viewport1.tone = $game_screen.tone
@@viewport3.color = $game_screen.flash_color @@viewport3.color = $game_screen.flash_color
@@viewport1.update @@viewport1.update

View File

@@ -3,10 +3,10 @@
# bottom. # bottom.
module RPG module RPG
class Weather class Weather
attr_reader :type attr_reader :type
attr_reader :max attr_reader :max
attr_reader :ox attr_reader :ox, :oy
attr_reader :oy attr_accessor :ox_offset, :oy_offset
MAX_SPRITES = 60 MAX_SPRITES = 60
FADE_OLD_TILES_START = 0 FADE_OLD_TILES_START = 0
@@ -34,6 +34,8 @@ module RPG
@max = 0 @max = 0
@ox = 0 @ox = 0
@oy = 0 @oy = 0
@ox_offset = 0
@oy_offset = 0
@tiles_wide = 0 @tiles_wide = 0
@tiles_tall = 0 @tiles_tall = 0
@tile_x = 0.0 @tile_x = 0.0
@@ -128,17 +130,17 @@ module RPG
def ox=(value) def ox=(value)
return if value == @ox return if value == @ox
@ox = value @ox = value
@sprites.each { |sprite| sprite.ox = @ox if sprite } @sprites.each { |sprite| sprite.ox = @ox + @ox_offset if sprite }
@new_sprites.each { |sprite| sprite.ox = @ox if sprite } @new_sprites.each { |sprite| sprite.ox = @ox + @ox_offset if sprite }
@tiles.each { |sprite| sprite.ox = @ox if sprite } @tiles.each { |sprite| sprite.ox = @ox + @ox_offset if sprite }
end end
def oy=(value) def oy=(value)
return if value == @oy return if value == @oy
@oy = value @oy = value
@sprites.each { |sprite| sprite.oy = @oy if sprite } @sprites.each { |sprite| sprite.oy = @oy + @oy_offset if sprite }
@new_sprites.each { |sprite| sprite.oy = @oy if sprite } @new_sprites.each { |sprite| sprite.oy = @oy + @oy_offset if sprite }
@tiles.each { |sprite| sprite.oy = @oy if sprite } @tiles.each { |sprite| sprite.oy = @oy + @oy_offset if sprite }
end end
def get_weather_tone(weather_type, maximum) def get_weather_tone(weather_type, maximum)
@@ -163,9 +165,10 @@ module RPG
MAX_SPRITES.times do |i| MAX_SPRITES.times do |i|
if !@sprites[i] if !@sprites[i]
sprite = Sprite.new(@origViewport) sprite = Sprite.new(@origViewport)
sprite.float = true
sprite.z = 1000 sprite.z = 1000
sprite.ox = @ox sprite.ox = @ox + @ox_offset
sprite.oy = @oy sprite.oy = @oy + @oy_offset
sprite.opacity = 0 sprite.opacity = 0
@sprites[i] = sprite @sprites[i] = sprite
end end
@@ -178,9 +181,10 @@ module RPG
MAX_SPRITES.times do |i| MAX_SPRITES.times do |i|
if !@new_sprites[i] if !@new_sprites[i]
sprite = Sprite.new(@origViewport) sprite = Sprite.new(@origViewport)
sprite.float = true
sprite.z = 1000 sprite.z = 1000
sprite.ox = @ox sprite.ox = @ox + @ox_offset
sprite.oy = @oy sprite.oy = @oy + @oy_offset
sprite.opacity = 0 sprite.opacity = 0
@new_sprites[i] = sprite @new_sprites[i] = sprite
end end
@@ -195,9 +199,10 @@ module RPG
(@tiles_wide * @tiles_tall).times do |i| (@tiles_wide * @tiles_tall).times do |i|
if !@tiles[i] if !@tiles[i]
sprite = Sprite.new(@origViewport) sprite = Sprite.new(@origViewport)
sprite.float = true
sprite.z = 1000 sprite.z = 1000
sprite.ox = @ox sprite.ox = @ox + @ox_offset
sprite.oy = @oy sprite.oy = @oy + @oy_offset
sprite.opacity = 0 sprite.opacity = 0
@tiles[i] = sprite @tiles[i] = sprite
end end
@@ -245,8 +250,8 @@ module RPG
return return
end end
if @weatherTypes[weather_type][0].category == :Rain && index.odd? # Splash if @weatherTypes[weather_type][0].category == :Rain && index.odd? # Splash
sprite.x = @ox - sprite.bitmap.width + rand(Graphics.width + (sprite.bitmap.width * 2)) sprite.x = @ox + @ox_offset - sprite.bitmap.width + rand(Graphics.width + (sprite.bitmap.width * 2))
sprite.y = @oy - sprite.bitmap.height + rand(Graphics.height + (sprite.bitmap.height * 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 lifetimes[index] = (rand(30...50)) * 0.01 # 0.3-0.5 seconds
else else
x_speed = @weatherTypes[weather_type][0].particle_delta_x x_speed = @weatherTypes[weather_type][0].particle_delta_x
@@ -254,15 +259,15 @@ module RPG
gradient = x_speed.to_f / y_speed gradient = x_speed.to_f / y_speed
if gradient.abs >= 1 if gradient.abs >= 1
# Position sprite to the right of the screen # Position sprite to the right of the screen
sprite.x = @ox + Graphics.width + rand(Graphics.width) sprite.x = @ox + @ox_offset + Graphics.width + rand(Graphics.width)
sprite.y = @oy + Graphics.height - rand(Graphics.height + sprite.bitmap.height - (Graphics.width / gradient)) sprite.y = @oy + @oy_offset + 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) 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 lifetimes[index] = (distance_to_cover.to_f / x_speed).abs
else else
# Position sprite to the top of the screen # Position sprite to the top of the screen
sprite.x = @ox - sprite.bitmap.width + rand(Graphics.width + sprite.bitmap.width - (gradient * Graphics.height)) sprite.x = @ox + @ox_offset - sprite.bitmap.width + rand(Graphics.width + sprite.bitmap.width - (gradient * Graphics.height))
sprite.y = @oy - sprite.bitmap.height - rand(Graphics.height) sprite.y = @oy + @oy_offset - sprite.bitmap.height - rand(Graphics.height)
distance_to_cover = @oy - sprite.y + (Graphics.height / 2) + rand(Graphics.height * 8 / 5) 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 lifetimes[index] = (distance_to_cover.to_f / y_speed).abs
end end
end end
@@ -291,17 +296,17 @@ module RPG
sprite.x += dist_x sprite.x += dist_x
sprite.y += dist_y sprite.y += dist_y
if weather_type == :Snow 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.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 sprite.y += [2, 1, 1, 0, 0, -1][index % 6] * dist_y / 10 # Variety
end end
sprite.x -= Graphics.width if sprite.x - @ox > Graphics.width sprite.x -= Graphics.width if sprite.x - @ox - @ox_offset > Graphics.width
sprite.x += Graphics.width if sprite.x - @ox < -sprite.width sprite.x += Graphics.width if sprite.x - @ox - @ox_offset < -sprite.width
sprite.y -= Graphics.height if sprite.y - @oy > Graphics.height sprite.y -= Graphics.height if sprite.y - @oy - @oy_offset > Graphics.height
sprite.y += Graphics.height if sprite.y - @oy < -sprite.height sprite.y += Graphics.height if sprite.y - @oy - @oy_offset < -sprite.height
sprite.opacity += @weatherTypes[weather_type][0].particle_delta_opacity * delta_t sprite.opacity += @weatherTypes[weather_type][0].particle_delta_opacity * delta_t
x = sprite.x - @ox x = sprite.x - @ox - @ox_offset
y = sprite.y - @oy y = sprite.y - @oy - @oy_offset
# Check if sprite is off-screen; if so, reset it # Check if sprite is off-screen; if so, reset it
if sprite.opacity < 64 || x < -sprite.bitmap.width || y > Graphics.height if sprite.opacity < 64 || x < -sprite.bitmap.width || y > Graphics.height
reset_sprite_position(sprite, index, is_new_sprite) reset_sprite_position(sprite, index, is_new_sprite)
@@ -317,16 +322,16 @@ module RPG
end end
@tile_x += @weatherTypes[weather_type][0].tile_delta_x * delta_t @tile_x += @weatherTypes[weather_type][0].tile_delta_x * delta_t
@tile_y += @weatherTypes[weather_type][0].tile_delta_y * 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 @tile_x += @weatherTypes[weather_type][2][0].width
end end
while @tile_x > @ox while @tile_x > @ox + @ox_offset
@tile_x -= @weatherTypes[weather_type][2][0].width @tile_x -= @weatherTypes[weather_type][2][0].width
end 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 @tile_y += @weatherTypes[weather_type][2][0].height
end end
while @tile_y > @oy while @tile_y > @oy + @oy_offset
@tile_y -= @weatherTypes[weather_type][2][0].height @tile_y -= @weatherTypes[weather_type][2][0].height
end end
end end
@@ -335,15 +340,14 @@ module RPG
return if !sprite || !sprite.bitmap || !sprite.visible return if !sprite || !sprite.bitmap || !sprite.visible
sprite.x = @tile_x.round + ((index % @tiles_wide) * sprite.bitmap.width) sprite.x = @tile_x.round + ((index % @tiles_wide) * sprite.bitmap.width)
sprite.y = @tile_y.round + ((index / @tiles_wide) * sprite.bitmap.height) 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.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 > Graphics.height sprite.y -= @tiles_tall * sprite.bitmap.height if sprite.y - @oy - @oy_offset > Graphics.height
sprite.visible = true sprite.visible = true
if @fading && @type != @target_type if @fading && @type != @target_type
if @fade_time >= FADE_OLD_TILES_START && @fade_time < FADE_OLD_TILES_END if @fade_time >= FADE_OLD_TILES_START && @fade_time < FADE_OLD_TILES_END &&
if @time_shift == 0 # There were old tiles to fade out @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) fraction = (@fade_time - [FADE_OLD_TILES_START - @time_shift, 0].max) / (FADE_OLD_TILES_END - FADE_OLD_TILES_START)
sprite.opacity = 255 * (1 - fraction) sprite.opacity = 255 * (1 - fraction)
end
elsif @fade_time >= [FADE_NEW_TILES_START - @time_shift, 0].max && elsif @fade_time >= [FADE_NEW_TILES_START - @time_shift, 0].max &&
@fade_time < [FADE_NEW_TILES_END - @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) 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.each { |sprite| sprite&.dispose }
@new_sprites.clear @new_sprites.clear
end end
# Update weather tiles (sandstorm/blizzard tiled overlay) # Update weather tiles (sandstorm/blizzard/fog tiled overlay)
if @tiles_wide > 0 && @tiles_tall > 0 if @tiles_wide > 0 && @tiles_tall > 0
ensureTiles ensureTiles
recalculate_tile_positions recalculate_tile_positions

View File

@@ -220,24 +220,7 @@ end
#=============================================================================== #===============================================================================
# Checks when moving between maps # Checks when moving between maps
#=============================================================================== #===============================================================================
# Clears the weather of the old map, if the old map has defined weather and the # Set up various data related to the new map.
# 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
EventHandlers.add(:on_enter_map, :setup_new_map, EventHandlers.add(:on_enter_map, :setup_new_map,
proc { |old_map_id| # previous map ID, is 0 if no map ID proc { |old_map_id| # previous map ID, is 0 if no map ID
# Record new Teleport destination # Record new Teleport destination
@@ -251,16 +234,21 @@ EventHandlers.add(:on_enter_map, :setup_new_map,
$PokemonEncounters&.setup($game_map.map_id) $PokemonEncounters&.setup($game_map.map_id)
# Record the new map as having been visited # Record the new map as having been visited
$PokemonGlobal.visitedMaps[$game_map.map_id] = true $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 old_map_id == 0 || old_map_id == $game_map.map_id
next if !new_map_metadata || !new_map_metadata.weather old_weather = $game_screen.weather_type
map_infos = pbLoadMapInfos new_weather = :None
if $game_map.name == map_infos[old_map_id].name new_map_metadata = $game_map.metadata
old_map_metadata = GameData::MapMetadata.try_get(old_map_id) if new_map_metadata&.weather
next if old_map_metadata&.weather new_weather = new_map_metadata.weather[0] if rand(100) < new_map_metadata.weather[1]
end end
new_weather = new_map_metadata.weather next if old_weather == new_weather
$game_screen.weather(new_weather[0], 9, 0) if rand(100) < new_weather[1] $game_screen.weather(new_weather, 9, 0)
} }
) )