More FPS agnosticism, fixed pause after finishing an event's repeating move route

This commit is contained in:
Maruno17
2023-05-24 21:20:20 +01:00
parent 167155c67d
commit c756e2647a
30 changed files with 947 additions and 847 deletions

View File

@@ -15,37 +15,46 @@ class Game_Screen
attr_accessor :weather_duration # ticks in which the weather should fade in
def initialize
@brightness = 255
@fadeout_duration = 0
@fadein_duration = 0
@tone = Tone.new(0, 0, 0, 0)
@tone_target = Tone.new(0, 0, 0, 0)
@tone_duration = 0
@flash_color = Color.new(0, 0, 0, 0)
@flash_duration = 0
@shake_power = 0
@shake_speed = 0
@shake_duration = 0
@shake_direction = 1
@shake = 0
@pictures = [nil]
(1..100).each do |i|
@pictures.push(Game_Picture.new(i))
end
@weather_type = :None
@weather_max = 0.0
@weather_duration = 0
@brightness = 255
@fadeout_duration = 0
@fadein_duration = 0
@tone = Tone.new(0, 0, 0, 0)
@tone_target = Tone.new(0, 0, 0, 0)
@tone_duration = 0
@tone_timer_start = nil
@flash_color = Color.new(0, 0, 0, 0)
@flash_duration = 0
@flash_timer_start = nil
@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)) }
@weather_type = :None
@weather_max = 0.0
@weather_duration = 0
end
# duration is time in 1/20ths of a second.
def start_tone_change(tone, duration)
@tone_target = tone.clone
@tone_duration = duration
@tone = @tone_target.clone if @tone_duration == 0
if duration == 0
@tone = tone.clone
return
end
@tone_initial = @tone.clone
@tone_target = tone.clone
@tone_duration = duration / 20.0
@tone_timer_start = $stats.play_time
end
# duration is time in 1/20ths of a second.
def start_flash(color, duration)
@flash_color = color.clone
@flash_duration = duration
@flash_color = color.clone
@flash_initial_alpha = @flash_color.alpha
@flash_duration = duration / 20.0
@flash_timer_start = $stats.play_time
end
def start_shake(power, speed, duration)
@@ -71,18 +80,23 @@ class Game_Screen
@brightness = ((@brightness * (d - 1)) + 255) / d
@fadein_duration -= 1
end
if @tone_duration >= 1
d = @tone_duration
@tone.red = ((@tone.red * (d - 1)) + @tone_target.red) / d
@tone.green = ((@tone.green * (d - 1)) + @tone_target.green) / d
@tone.blue = ((@tone.blue * (d - 1)) + @tone_target.blue) / d
@tone.gray = ((@tone.gray * (d - 1)) + @tone_target.gray) / d
@tone_duration -= 1
now = $stats.play_time
if @tone_timer_start
@tone.red = lerp(@tone_initial.red, @tone_target.red, @tone_duration, @tone_timer_start, now)
@tone.green = lerp(@tone_initial.green, @tone_target.green, @tone_duration, @tone_timer_start, now)
@tone.blue = lerp(@tone_initial.blue, @tone_target.blue, @tone_duration, @tone_timer_start, now)
@tone.gray = lerp(@tone_initial.gray, @tone_target.gray, @tone_duration, @tone_timer_start, now)
if now - @tone_timer_start >= @tone_duration
@tone_initial = nil
@tone_timer_start = nil
end
end
if @flash_duration >= 1
d = @flash_duration
@flash_color.alpha = @flash_color.alpha * (d - 1) / d
@flash_duration -= 1
if @flash_timer_start
@flash_color.alpha = lerp(@flash_initial_alpha, 0, @flash_duration, @flash_timer_start, now)
if now - @flash_timer_start >= @flash_duration
@flash_initial_alpha = nil
@flash_timer_start = nil
end
end
if @shake_duration >= 1 || @shake != 0
delta = (@shake_power * @shake_speed * @shake_direction) / 10.0
@@ -96,13 +110,9 @@ class Game_Screen
@shake_duration -= 1 if @shake_duration >= 1
end
if $game_temp.in_battle
(51..100).each do |i|
@pictures[i].update
end
(51..100).each { |i| @pictures[i].update }
else
(1..50).each do |i|
@pictures[i].update
end
(1..50).each { |i| @pictures[i].update }
end
end
end
@@ -111,16 +121,14 @@ end
#
#===============================================================================
def pbToneChangeAll(tone, duration)
$game_screen.start_tone_change(tone, duration * Graphics.frame_rate / 20)
$game_screen.pictures.each do |picture|
picture&.start_tone_change(tone, duration * Graphics.frame_rate / 20)
end
$game_screen.start_tone_change(tone, duration)
$game_screen.pictures.each { |picture| picture&.start_tone_change(tone, duration) }
end
def pbFlash(color, frames)
$game_screen.start_flash(color, frames)
end
def pbShake(power, speed, frames)
$game_screen.start_shake(power, speed, frames * Graphics.frame_rate / 20)
end
def pbFlash(color, frames)
$game_screen.start_flash(color, frames * Graphics.frame_rate / 20)
end

View File

@@ -8,8 +8,8 @@
class Game_System
attr_reader :map_interpreter # map event interpreter
attr_reader :battle_interpreter # battle event interpreter
attr_accessor :timer # timer
attr_accessor :timer_working # timer working flag
attr_accessor :timer_start # $stats.play_time when timer was started, or nil
attr_accessor :timer_duration # Time (in seconds) the timer is initially set to
attr_accessor :save_disabled # save forbidden
attr_accessor :menu_disabled # menu forbidden
attr_accessor :encounter_disabled # encounter forbidden
@@ -24,8 +24,8 @@ class Game_System
def initialize
@map_interpreter = Interpreter.new(0, true)
@battle_interpreter = Interpreter.new(0, false)
@timer = 0
@timer_working = false
@timer_start = nil
@timer_duration = 0
@save_disabled = false
@menu_disabled = false
@encounter_disabled = false
@@ -265,17 +265,18 @@ class Game_System
#-----------------------------------------------------------------------------
def windowskin_name
if @windowskin_name.nil?
return $data_system.windowskin_name
else
return @windowskin_name
end
return $data_system.windowskin_name if @windowskin_name.nil?
return @windowskin_name
end
attr_writer :windowskin_name
def timer
return 0 if !@timer_start || !$stats
return @timer_duration - $stats.play_time + @timer_start
end
def update
@timer -= 1 if @timer_working && @timer > 0
if Input.trigger?(Input::SPECIAL) && pbCurrentEventCommentInput(1, "Cut Scene")
event = @map_interpreter.get_self
@map_interpreter.pbSetSelfSwitch(event.id, "A", true)

View File

@@ -28,6 +28,7 @@ class Game_Picture
@opacity = 255.0
@blend_type = 1
@duration = 0
@move_timer_start = nil
@target_x = @x
@target_y = @y
@target_zoom_x = @zoom_x
@@ -36,6 +37,7 @@ class Game_Picture
@tone = Tone.new(0, 0, 0, 0)
@tone_target = Tone.new(0, 0, 0, 0)
@tone_duration = 0
@tone_timer_start = nil
@angle = 0
@rotate_speed = 0
end
@@ -67,12 +69,13 @@ class Game_Picture
@tone = Tone.new(0, 0, 0, 0)
@tone_target = Tone.new(0, 0, 0, 0)
@tone_duration = 0
@tone_timer_start = nil
@angle = 0
@rotate_speed = 0
end
# Move Picture
# duration : time
# duration : time in 1/20ths of a second
# origin : starting point
# x : x-coordinate
# y : y-coordinate
@@ -81,57 +84,79 @@ class Game_Picture
# opacity : opacity level
# blend_type : blend method
def move(duration, origin, x, y, zoom_x, zoom_y, opacity, blend_type)
@duration = duration
@origin = origin
@target_x = x.to_f
@target_y = y.to_f
@target_zoom_x = zoom_x.to_f
@target_zoom_y = zoom_y.to_f
@target_opacity = opacity.to_f
@blend_type = blend_type || 0
@duration = duration / 20.0
@origin = origin
@initial_x = @x
@initial_y = @y
@target_x = x.to_f
@target_y = y.to_f
@initial_zoom_x = @zoom_x
@initial_zoom_y = @zoom_y
@target_zoom_x = zoom_x.to_f
@target_zoom_y = zoom_y.to_f
@initial_opacity = @opacity
@target_opacity = opacity.to_f
@blend_type = blend_type || 0
@move_timer_start = $stats.play_time
end
# Change Rotation Speed
# speed : rotation speed
# speed : rotation speed (degrees to change per 1/20th of a second)
def rotate(speed)
@rotate_timer = (speed == 0) ? nil : System.uptime # Time since last frame
@rotate_speed = speed
end
# Start Change of Color Tone
# tone : color tone
# duration : time
# duration : time in 1/20ths of a second
def start_tone_change(tone, duration)
if duration == 0
@tone = tone.clone
return
end
@tone_initial = @tone.clone
@tone_target = tone.clone
@tone_duration = duration
@tone = @tone_target.clone if @tone_duration == 0
@tone_duration = duration / 20.0
@tone_timer_start = $stats.play_time
end
# Erase Picture
def erase
@name = ""
end
# Frame Update
def update
if @duration >= 1
d = @duration
@x = ((@x * (d - 1)) + @target_x) / d
@y = ((@y * (d - 1)) + @target_y) / d
@zoom_x = ((@zoom_x * (d - 1)) + @target_zoom_x) / d
@zoom_y = ((@zoom_y * (d - 1)) + @target_zoom_y) / d
@opacity = ((@opacity * (d - 1)) + @target_opacity) / d
@duration -= 1
return if @name == ""
now = $stats.play_time
if @move_timer_start
@x = lerp(@initial_x, @target_x, @duration, @move_timer_start, now)
@y = lerp(@initial_y, @target_y, @duration, @move_timer_start, now)
@zoom_x = lerp(@initial_zoom_x, @target_zoom_x, @duration, @move_timer_start, now)
@zoom_y = lerp(@initial_zoom_y, @target_zoom_y, @duration, @move_timer_start, now)
@opacity = lerp(@initial_opacity, @target_opacity, @duration, @move_timer_start, now)
if now - @move_timer_start >= @duration
@initial_x = nil
@initial_y = nil
@initial_zoom_x = nil
@initial_zoom_y = nil
@initial_opacity = nil
@move_timer_start = nil
end
end
if @tone_duration >= 1
d = @tone_duration
@tone.red = ((@tone.red * (d - 1)) + @tone_target.red) / d
@tone.green = ((@tone.green * (d - 1)) + @tone_target.green) / d
@tone.blue = ((@tone.blue * (d - 1)) + @tone_target.blue) / d
@tone.gray = ((@tone.gray * (d - 1)) + @tone_target.gray) / d
@tone_duration -= 1
if @tone_timer_start
@tone.red = lerp(@tone_initial.red, @tone_target.red, @tone_duration, @tone_timer_start, now)
@tone.green = lerp(@tone_initial.green, @tone_target.green, @tone_duration, @tone_timer_start, now)
@tone.blue = lerp(@tone_initial.blue, @tone_target.blue, @tone_duration, @tone_timer_start, now)
@tone.gray = lerp(@tone_initial.gray, @tone_target.gray, @tone_duration, @tone_timer_start, now)
if now - @tone_timer_start >= @tone_duration
@tone_initial = nil
@tone_timer_start = nil
end
end
if @rotate_speed != 0
@angle += @rotate_speed / 2.0
@rotate_timer = System.uptime if !@rotate_timer
@angle += @rotate_speed * (System.uptime - @rotate_timer) * 20.0
@rotate_timer = System.uptime
while @angle < 0
@angle += 360
end

View File

@@ -47,28 +47,30 @@ class Game_Map
@map = load_data(sprintf("Data/Map%03d.rxdata", map_id))
tileset = $data_tilesets[@map.tileset_id]
updateTileset
@fog_ox = 0
@fog_oy = 0
@fog_tone = Tone.new(0, 0, 0, 0)
@fog_tone_target = Tone.new(0, 0, 0, 0)
@fog_tone_duration = 0
@fog_opacity_duration = 0
@fog_opacity_target = 0
self.display_x = 0
self.display_y = 0
@need_refresh = false
@fog_ox = 0
@fog_oy = 0
@fog_tone = Tone.new(0, 0, 0, 0)
@fog_tone_target = Tone.new(0, 0, 0, 0)
@fog_tone_duration = 0
@fog_tone_timer_start = nil
@fog_opacity_duration = 0
@fog_opacity_target = 0
@fog_opacity_timer_start = nil
self.display_x = 0
self.display_y = 0
@need_refresh = false
EventHandlers.trigger(:on_game_map_setup, map_id, @map, tileset)
@events = {}
@events = {}
@map.events.each_key do |i|
@events[i] = Game_Event.new(@map_id, @map.events[i], self)
@events[i] = Game_Event.new(@map_id, @map.events[i], self)
end
@common_events = {}
@common_events = {}
(1...$data_common_events.size).each do |i|
@common_events[i] = Game_CommonEvent.new(i)
@common_events[i] = Game_CommonEvent.new(i)
end
@scroll_direction = 2
@scroll_rest = 0
@scroll_speed = 4
@scroll_direction = 2
@scroll_rest = 0
@scroll_speed = 4
end
def updateTileset
@@ -368,16 +370,28 @@ class Game_Map
return @scroll_rest > 0
end
# duration is time in 1/20ths of a second.
def start_fog_tone_change(tone, duration)
if duration == 0
@fog_tone = tone.clone
return
end
@fog_tone_initial = @fog_tone.clone
@fog_tone_target = tone.clone
@fog_tone_duration = duration
@fog_tone = @fog_tone_target.clone if @fog_tone_duration == 0
@fog_tone_duration = duration / 20.0
@fog_tone_timer_start = $stats.play_time
end
# duration is time in 1/20ths of a second.
def start_fog_opacity_change(opacity, duration)
if duration == 0
@fog_opacity = opacity.to_f
return
end
@fog_opacity_initial = @fog_opacity
@fog_opacity_target = opacity.to_f
@fog_opacity_duration = duration
@fog_opacity = @fog_opacity_target if @fog_opacity_duration == 0
@fog_opacity_duration = duration / 20.0
@fog_opacity_timer_start = $stats.play_time
end
def set_tile(x, y, layer, id = 0)
@@ -399,11 +413,9 @@ class Game_Map
end
def update
# refresh maps if necessary
# Refresh maps if necessary
if $map_factory
$map_factory.maps.each do |i|
i.refresh if i.need_refresh
end
$map_factory.maps.each { |i| i.refresh if i.need_refresh }
$map_factory.setCurrentMap
end
# If scrolling
@@ -419,29 +431,31 @@ class Game_Map
@scroll_rest -= distance
end
# Only update events that are on-screen
@events.each_value do |event|
event.update
if !$game_temp.in_menu
@events.each_value { |event| event.update }
end
# Update common events
@common_events.each_value do |common_event|
common_event.update
end
@common_events.each_value { |common_event| common_event.update }
# Update fog
now = $stats.play_time
@fog_ox -= @fog_sx / 8.0
@fog_oy -= @fog_sy / 8.0
if @fog_tone_duration >= 1
d = @fog_tone_duration
target = @fog_tone_target
@fog_tone.red = ((@fog_tone.red * (d - 1)) + target.red) / d
@fog_tone.green = ((@fog_tone.green * (d - 1)) + target.green) / d
@fog_tone.blue = ((@fog_tone.blue * (d - 1)) + target.blue) / d
@fog_tone.gray = ((@fog_tone.gray * (d - 1)) + target.gray) / d
@fog_tone_duration -= 1
if @fog_tone_timer_start
@fog_tone.red = lerp(@fog_tone_initial.red, @fog_tone_target.red, @fog_tone_duration, @fog_tone_timer_start, now)
@fog_tone.green = lerp(@fog_tone_initial.green, @fog_tone_target.green, @fog_tone_duration, @fog_tone_timer_start, now)
@fog_tone.blue = lerp(@fog_tone_initial.blue, @fog_tone_target.blue, @fog_tone_duration, @fog_tone_timer_start, now)
@fog_tone.gray = lerp(@fog_tone_initial.gray, @fog_tone_target.gray, @fog_tone_duration, @fog_tone_timer_start, now)
if now - @fog_tone_timer_start >= @fog_tone_duration
@fog_tone_initial = nil
@fog_tone_timer_start = nil
end
end
if @fog_opacity_duration >= 1
d = @fog_opacity_duration
@fog_opacity = ((@fog_opacity * (d - 1)) + @fog_opacity_target) / d
@fog_opacity_duration -= 1
if @fog_opacity_timer_start
@fog_opacity = lerp(@fog_opacity_initial, @fog_opacity_target, @fog_opacity_duration, @fog_opacity_timer_start, now)
if now - @fog_opacity_timer_start >= @fog_opacity_duration
@fog_opacity_initial = nil
@fog_opacity_timer_start = nil
end
end
end
end

View File

@@ -25,6 +25,7 @@ class Game_Character
attr_accessor :animation_id
attr_accessor :transparent
attr_reader :move_speed
attr_accessor :jump_speed
attr_accessor :walk_anime
attr_writer :bob_height
@@ -60,6 +61,7 @@ class Game_Character
@move_type = 0
self.move_speed = 3
self.move_frequency = 6
self.jump_speed = 3
@move_route = nil
@move_route_index = 0
@original_move_route = nil
@@ -68,12 +70,12 @@ class Game_Character
@step_anime = false # Whether character should animate while still
@direction_fix = false
@always_on_top = false
@anime_count = 0
@stop_count = 0
@anime_count = 0 # Time since pattern was last changed
@stop_count = 0 # Time since character last finished moving
@jump_peak = 0 # Max height while jumping
@jump_distance = 0 # Total distance of jump
@jump_distance_left = 0 # Distance left to travel
@jump_count = 0 # Frames left in a stationary jump
@jump_fraction = 0 # How far through a jump we currently are (0-1)
@jumping_on_spot = false
@bob_height = 0
@wait_count = 0
@wait_start = nil
@@ -105,62 +107,45 @@ class Game_Character
end
def move_speed=(val)
return if val == @move_speed
@move_speed = val
# @move_speed_real is the number of quarter-pixels to move each frame. There
# are 128 quarter-pixels per tile. By default, it is calculated from
# @move_speed and has these values (assuming 40 fps):
# 1 => 3.2 # 40 frames per tile
# 2 => 6.4 # 20 frames per tile
# 3 => 12.8 # 10 frames per tile - walking speed
# 4 => 25.6 # 5 frames per tile - running speed (2x walking speed)
# 5 => 32 # 4 frames per tile - cycling speed (1.25x running speed)
# 6 => 64 # 2 frames per tile
self.move_speed_real = (val == 6) ? 64 : (val == 5) ? 32 : (2**(val + 1)) * 0.8
# Time taken to traverse one tile (in seconds) for each speed:
# 1 => 1.0
# 2 => 0.5
# 3 => 0.25 # Walking speed
# 4 => 0.125 # Running speed (2x walking speed)
# 5 => 0.1 # Cycling speed (1.25x running speed)
# 6 => 0.05
@move_time = (val == 6) ? 0.05 : (val == 5) ? 0.1 : 2.0 / (2**val)
end
def move_speed_real
self.move_speed = @move_speed if !@move_speed_real
return @move_speed_real
# Takes the same values as move_speed above.
def jump_speed=(val)
@jump_speed = val
@jump_time = (val == 6) ? 0.05 : (val == 5) ? 0.1 : 2.0 / (2**val)
end
def move_speed_real=(val)
@move_speed_real = val * 40.0 / Graphics.frame_rate
end
def jump_speed_real
self.jump_speed_real = (2**(3 + 1)) * 0.8 if !@jump_speed_real # 3 is walking speed
return @jump_speed_real
end
def jump_speed_real=(val)
@jump_speed_real = val * 40.0 / Graphics.frame_rate
# Returns time in seconds for one full cycle (4 frames) of an animating
# charset to show. Two frames are shown per movement across one tile.
def pattern_update_speed
return @jump_time * 2 if jumping?
ret = @move_time * 2
ret *= 2 if @move_speed >= 5 # Cycling speed or faster; slower animation
return ret
end
def move_frequency=(val)
return if val == @move_frequency
@move_frequency = val
# @move_frequency_real is the number of frames to wait between each action
# in a move route (not forced). Specifically, this is the number of frames
# to wait after the character stops moving because of the previous action.
# By default, it is calculated from @move_frequency and has these values
# (assuming 40 fps):
# 1 => 190 # 4.75 seconds
# 2 => 144 # 3.6 seconds
# 3 => 102 # 2.55 seconds
# 4 => 64 # 1.6 seconds
# 5 => 30 # 0.75 seconds
# 6 => 0 # 0 seconds, i.e. continuous movement
self.move_frequency_real = (40 - (val * 2)) * (6 - val)
end
def move_frequency_real
self.move_frequency = @move_frequency if !@move_frequency_real
return @move_frequency_real
end
def move_frequency_real=(val)
@move_frequency_real = val * Graphics.frame_rate / 40.0
# Time in seconds to wait between each action in a move route (not forced).
# Specifically, this is the time to wait after the character stops moving
# because of the previous action.
# 1 => 4.75 seconds
# 2 => 3.6 seconds
# 3 => 2.55 seconds
# 4 => 1.6 seconds
# 5 => 0.75 seconds
# 6 => 0 seconds, i.e. continuous movement
@command_delay = (40 - (val * 2)) * (6 - val) / 40.0
end
def bob_height
@@ -327,12 +312,8 @@ class Game_Character
def screen_y
ret = screen_y_ground
if jumping?
if @jump_count > 0
jump_fraction = ((@jump_count * jump_speed_real / Game_Map::REAL_RES_X) - 0.5).abs # 0.5 to 0 to 0.5
else
jump_fraction = ((@jump_distance_left / @jump_distance) - 0.5).abs # 0.5 to 0 to 0.5
end
ret += @jump_peak * ((4 * (jump_fraction**2)) - 1)
jump_progress = (@jump_fraction - 0.5).abs # 0.5 to 0 to 0.5
ret += @jump_peak * ((4 * (jump_progress**2)) - 1)
end
ret += self.y_offset
return ret
@@ -361,7 +342,7 @@ class Game_Character
end
def jumping?
return (@jump_distance_left || 0) > 0 || @jump_count > 0
return !@jump_timer.nil?
end
def straighten
@@ -437,11 +418,17 @@ class Game_Character
def move_type_custom
return if jumping? || moving?
return if @move_route.list.size <= 1 # Empty move route
start_index = @move_route_index
done_one_command = false
while @move_route_index < @move_route.list.size
return if @move_route_index == start_index && done_one_command
done_one_command = true
command = @move_route.list[@move_route_index]
if command.code == 0
if @move_route.repeat
@move_route_index = 0
command = @move_route.list[@move_route_index]
else
if @move_route_forcing
@move_route_forcing = false
@@ -450,9 +437,11 @@ class Game_Character
@original_move_route = nil
end
@stop_count = 0
return
end
return
end
# The below move route commands wait for a frame (i.e. return) after
# executing them
if command.code <= 14
case command.code
when 1 then move_down
@@ -473,14 +462,13 @@ class Game_Character
@move_route_index += 1 if @move_route.skippable || moving? || jumping?
return
end
if command.code == 15 # Wait
@wait_count = command.parameters[0] / 20.0
@wait_start = System.uptime
@move_route_index += 1
return
end
if command.code >= 16 && command.code <= 26
# The below move route commands wait for a frame (i.e. return) after
# executing them
if command.code >= 15 && command.code <= 26
case command.code
when 15 # Wait
@wait_count = command.parameters[0] / 20.0
@wait_start = System.uptime
when 16 then turn_down
when 17 then turn_left
when 18 then turn_right
@@ -496,6 +484,8 @@ class Game_Character
@move_route_index += 1
return
end
# The below move route commands don't wait for a frame (i.e. return) after
# executing them
if command.code >= 27
case command.code
when 27
@@ -551,8 +541,11 @@ class Game_Character
turn_generic(dir) if turn_enabled
if can_move_in_direction?(dir)
turn_generic(dir)
@move_initial_x = @x
@move_initial_y = @y
@x += (dir == 4) ? -1 : (dir == 6) ? 1 : 0
@y += (dir == 8) ? -1 : (dir == 2) ? 1 : 0
@move_timer = 0.0
increase_steps
else
check_event_trigger_touch(dir)
@@ -580,8 +573,11 @@ class Game_Character
@direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction)
end
if can_move_in_direction?(7)
@move_initial_x = @x
@move_initial_y = @y
@x -= 1
@y -= 1
@move_timer = 0.0
increase_steps
end
end
@@ -591,8 +587,11 @@ class Game_Character
@direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction)
end
if can_move_in_direction?(9)
@move_initial_x = @x
@move_initial_y = @y
@x += 1
@y -= 1
@move_timer = 0.0
increase_steps
end
end
@@ -602,8 +601,11 @@ class Game_Character
@direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction)
end
if can_move_in_direction?(1)
@move_initial_x = @x
@move_initial_y = @y
@x -= 1
@y += 1
@move_timer = 0.0
increase_steps
end
end
@@ -613,8 +615,11 @@ class Game_Character
@direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction)
end
if can_move_in_direction?(3)
@move_initial_x = @x
@move_initial_y = @y
@x += 1
@y += 1
@move_timer = 0.0
increase_steps
end
end
@@ -753,19 +758,16 @@ class Game_Character
end
each_occupied_tile { |i, j| return if !passable?(i + x_plus, j + y_plus, 0) }
end
@jump_initial_x = @x
@jump_initial_y = @y
@x = @x + x_plus
@y = @y + y_plus
real_distance = Math.sqrt((x_plus * x_plus) + (y_plus * y_plus))
@jump_timer = 0.0
real_distance = Math.sqrt(x_plus**2 + y_plus**2)
distance = [1, real_distance].max
@jump_peak = distance * Game_Map::TILE_HEIGHT * 3 / 8 # 3/4 of tile for ledge jumping
@jump_distance = [x_plus.abs * Game_Map::REAL_RES_X, y_plus.abs * Game_Map::REAL_RES_Y].max
@jump_distance_left = 1 # Just needs to be non-zero
if real_distance > 0 # Jumping to somewhere else
@jump_count = 0
else # Jumping on the spot
@jump_speed_real = nil # Reset jump speed
@jump_count = Game_Map::REAL_RES_X / jump_speed_real # Number of frames to jump one tile
end
@jumping_on_spot = (real_distance == 0)
increase_steps
end
@@ -874,16 +876,20 @@ class Game_Character
# Updating
#=============================================================================
def update
return if $game_temp.in_menu
time_now = System.uptime
@last_update_time = time_now if !@last_update_time || @last_update_time > time_now
@delta_t = time_now - @last_update_time
@last_update_time = time_now
return if @delta_t > 0.25 # Was in a menu; delay movement
@moved_last_frame = @moved_this_frame
@stopped_last_frame = @stopped_this_frame
@moved_this_frame = false
@stopped_this_frame = false
if !$game_temp.in_menu
# Update command
update_command
# Update movement
(moving? || jumping?) ? update_move : update_stop
end
# Update command
update_command
# Update movement
(moving? || jumping?) ? update_move : update_stop
# Update animation
update_pattern
end
@@ -902,15 +908,7 @@ class Game_Character
end
def update_command_new
# @stop_count is the number of frames since the last movement finished.
# @move_frequency has these values:
# 1 => @stop_count > 190 # 4.75 seconds
# 2 => @stop_count > 144 # 3.6 seconds
# 3 => @stop_count > 102 # 2.55 seconds
# 4 => @stop_count > 64 # 1.6 seconds
# 5 => @stop_count > 30 # 0.75 seconds
# 6 => @stop_count > 0 # 0 seconds
if @stop_count >= self.move_frequency_real
if @stop_count >= @command_delay
case @move_type
when 1 then move_type_random
when 2 then move_type_toward_player
@@ -920,29 +918,48 @@ class Game_Character
end
def update_move
# Move the character (the 0.1 catches rounding errors)
distance = (jumping?) ? jump_speed_real : move_speed_real
dest_x = @x * Game_Map::REAL_RES_X
dest_y = @y * Game_Map::REAL_RES_Y
if @real_x < dest_x
@real_x += distance
@real_x = dest_x if @real_x > dest_x - 0.1
else
@real_x -= distance
@real_x = dest_x if @real_x < dest_x + 0.1
if @move_timer
@move_timer += @delta_t
# Move horizontally
if @x != @move_initial_x
dist = (@move_initial_x - @x).abs
@real_x = lerp(@move_initial_x, @x, @move_time * dist, @move_timer) * Game_Map::REAL_RES_X
end
# Move vertically
if @y != @move_initial_y
dist = (@move_initial_y - @y).abs
@real_y = lerp(@move_initial_y, @y, @move_time * dist, @move_timer) * Game_Map::REAL_RES_Y
end
elsif @jump_timer
self.jump_speed = 3 if !@jump_time
@jump_timer += @delta_t
dist = [(@x - @jump_initial_x).abs, (@y - @jump_initial_y).abs].max
dist = 1 if dist == 0 # Jumping on spot
# Move horizontally
if @x != @jump_initial_x
@real_x = lerp(@jump_initial_x, @x, @jump_time * dist, @jump_timer) * Game_Map::REAL_RES_X
end
# Move vertically
if @y != @jump_initial_y
@real_y = lerp(@jump_initial_y, @y, @jump_time * dist, @jump_timer) * Game_Map::REAL_RES_Y
end
# Calculate how far through the jump we are (from 0 to 1)
@jump_fraction = @jump_timer / (@jump_time * dist)
end
if @real_y < dest_y
@real_y += distance
@real_y = dest_y if @real_y > dest_y - 0.1
else
@real_y -= distance
@real_y = dest_y if @real_y < dest_y + 0.1
# Snap to end position if close enough
@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?
@move_timer = nil
end
# Refresh how far is left to travel in a jump
was_jumping = jumping?
if was_jumping
@jump_count -= 1 if @jump_count > 0 # For stationary jumps only
@jump_distance_left = [(dest_x - @real_x).abs, (dest_y - @real_y).abs].max
# End of jump
if jumping? && @jump_fraction >= 1
@jump_timer = nil
@jump_peak = 0
@jump_distance = 0
@jump_fraction = 0
@jumping_on_spot = false
end
# End of a step, so perform events that happen at this time
if !jumping? && !moving?
@@ -953,18 +970,18 @@ class Game_Character
calculate_bush_depth
end
# Increment animation counter
@anime_count += 1 if @walk_anime || @step_anime
@anime_count += @delta_t if @walk_anime || @step_anime
@moved_this_frame = true
end
def update_stop
@anime_count += 1 if @step_anime
@stop_count += 1 if !@starting && !lock?
@anime_count += @delta_t if @step_anime
@stop_count += @delta_t if !@starting && !lock?
end
def update_pattern
return if @lock_pattern
# return if @jump_count > 0 # Don't animate if jumping on the spot
# return if @jumping_on_spot # Don't animate if jumping on the spot
# Character has stopped moving, return to original pattern
if @moved_last_frame && !@moved_this_frame && !@step_anime
@pattern = @original_pattern
@@ -980,12 +997,10 @@ class Game_Character
# Calculate how many frames each pattern should display for, i.e. the time
# it takes to move half a tile (or a whole tile if cycling). We assume the
# game uses square tiles.
real_speed = (jumping?) ? jump_speed_real : move_speed_real
frames_per_pattern = Game_Map::REAL_RES_X / (real_speed * 2.0)
frames_per_pattern *= 2 if move_speed >= 5 # Cycling speed or faster
return if @anime_count < frames_per_pattern
pattern_time = pattern_update_speed / 4 # 4 frames per cycle in a charset
return if @anime_count < pattern_time
# Advance to the next animation frame
@pattern = (@pattern + 1) % 4
@anime_count -= frames_per_pattern
@anime_count -= pattern_time
end
end

View File

@@ -48,6 +48,8 @@ class Game_Player < Game_Character
return $PokemonGlobal.followers.length == 0
end
#-----------------------------------------------------------------------------
def can_run?
return @move_speed > 3 if @move_route_forcing
return false if $game_temp.in_menu || $game_temp.in_battle ||
@@ -110,6 +112,8 @@ class Game_Player < Game_Character
@character_name = new_charset if new_charset
end
#-----------------------------------------------------------------------------
def bump_into_object
return if @bump_se && @bump_se > 0
pbSEPlay("Player bump") if !@move_route_forcing
@@ -146,8 +150,11 @@ class Game_Player < Game_Character
# General movement
turn_generic(dir, true)
if !$game_temp.encounter_triggered
@move_initial_x = @x
@move_initial_y = @y
@x += x_offset
@y += y_offset
@move_timer = 0.0
add_move_distance_to_stats(x_offset.abs + y_offset.abs)
increase_steps
end
@@ -174,49 +181,7 @@ class Game_Player < Game_Character
add_move_distance_to_stats(x_plus.abs + y_plus.abs) if @x != old_x || @y != old_y
end
def pbTriggeredTrainerEvents(triggers, checkIfRunning = true, trainer_only = false)
result = []
# If event is running
return result if checkIfRunning && $game_system.map_interpreter.running?
# All event loops
$game_map.events.each_value do |event|
next if !triggers.include?(event.trigger)
next if !event.name[/trainer\((\d+)\)/i] && (trainer_only || !event.name[/sight\((\d+)\)/i])
distance = $~[1].to_i
next if !pbEventCanReachPlayer?(event, self, distance)
next if event.jumping? || event.over_trigger?
result.push(event)
end
return result
end
def pbTriggeredCounterEvents(triggers, checkIfRunning = true)
result = []
# If event is running
return result if checkIfRunning && $game_system.map_interpreter.running?
# All event loops
$game_map.events.each_value do |event|
next if !triggers.include?(event.trigger)
next if !event.name[/counter\((\d+)\)/i]
distance = $~[1].to_i
next if !pbEventFacesPlayer?(event, self, distance)
next if event.jumping? || event.over_trigger?
result.push(event)
end
return result
end
def pbCheckEventTriggerAfterTurning; end
def pbCheckEventTriggerFromDistance(triggers)
ret = pbTriggeredTrainerEvents(triggers)
ret.concat(pbTriggeredCounterEvents(triggers))
return false if ret.length == 0
ret.each do |event|
event.start
end
return true
end
#-----------------------------------------------------------------------------
def pbTerrainTag(countBridge = false)
return $map_factory.getTerrainTagFromCoords(self.map.map_id, @x, @y, countBridge) if $map_factory
@@ -303,6 +268,52 @@ class Game_Player < Game_Character
@blend_type = 0
end
#-----------------------------------------------------------------------------
def pbTriggeredTrainerEvents(triggers, checkIfRunning = true, trainer_only = false)
result = []
# If event is running
return result if checkIfRunning && $game_system.map_interpreter.running?
# All event loops
$game_map.events.each_value do |event|
next if !triggers.include?(event.trigger)
next if !event.name[/trainer\((\d+)\)/i] && (trainer_only || !event.name[/sight\((\d+)\)/i])
distance = $~[1].to_i
next if !pbEventCanReachPlayer?(event, self, distance)
next if event.jumping? || event.over_trigger?
result.push(event)
end
return result
end
def pbTriggeredCounterEvents(triggers, checkIfRunning = true)
result = []
# If event is running
return result if checkIfRunning && $game_system.map_interpreter.running?
# All event loops
$game_map.events.each_value do |event|
next if !triggers.include?(event.trigger)
next if !event.name[/counter\((\d+)\)/i]
distance = $~[1].to_i
next if !pbEventFacesPlayer?(event, self, distance)
next if event.jumping? || event.over_trigger?
result.push(event)
end
return result
end
def pbCheckEventTriggerAfterTurning; end
def pbCheckEventTriggerFromDistance(triggers)
ret = pbTriggeredTrainerEvents(triggers)
ret.concat(pbTriggeredCounterEvents(triggers))
return false if ret.length == 0
ret.each do |event|
event.start
end
return true
end
# Trigger event(s) at the same coordinates as self with the appropriate
# trigger(s) that can be triggered
def check_event_trigger_here(triggers)
@@ -387,6 +398,8 @@ class Game_Player < Game_Character
return result
end
#-----------------------------------------------------------------------------
def update
last_real_x = @real_x
last_real_y = @real_y

View File

@@ -68,11 +68,12 @@ class Game_Follower < Game_Event
# Can't walk over the middle tile, but can walk over the end tile; jump over
if location_passable?(self.x, self.y, direction)
if leader.jumping?
@jump_speed_real = leader.jump_speed_real
self.jump_speed = leader.jump_speed || 3
else
# This is doubled because self has to jump 2 tiles in the time it
# takes the leader to move one tile.
@jump_speed_real = leader.move_speed_real * 2
self.jump_speed = leader.move_speed || 3
# This is halved because self has to jump 2 tiles in the time it takes
# the leader to move one tile
@jump_time /= 2
end
jump(delta_x, delta_y)
else
@@ -105,6 +106,21 @@ class Game_Follower < Game_Event
end
end
# Ceases all movement immediately. Used when the leader wants to move another
# tile but self hasn't quite finished its previous movement yet.
def end_movement
@x = x % self.map.width
@y = y % self.map.height
@real_x = @x * Game_Map::REAL_RES_X
@real_y = @y * Game_Map::REAL_RES_Y
@move_timer = nil
@jump_timer = nil
@jump_peak = 0
@jump_distance = 0
@jump_fraction = 0
@jumping_on_spot = false
end
#-----------------------------------------------------------------------------
def turn_towards_leader(leader)
@@ -113,6 +129,7 @@ class Game_Follower < Game_Event
def follow_leader(leader, instant = false, leaderIsTrueLeader = true)
return if @move_route_forcing
end_movement
maps_connected = $map_factory.areConnected?(leader.map.map_id, self.map.map_id)
target = nil
# Get the target tile that self wants to move to

View File

@@ -240,6 +240,7 @@ class Game_FollowerFactory
#-----------------------------------------------------------------------------
def update
return if $game_temp.in_menu
followers = $PokemonGlobal.followers
return if followers.length == 0
# Update all followers