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
#===============================================================================
# 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
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

View File

@@ -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

View File

@@ -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

View File

@@ -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)
}
)