Files
infinitefusion-e18/Data/Scripts/004_Game classes/006_Game_Character.rb

1034 lines
30 KiB
Ruby

class Game_Character
attr_reader :id
attr_reader :original_x
attr_reader :original_y
attr_reader :x
attr_reader :y
attr_reader :real_x
attr_reader :real_y
attr_writer :x_offset # In pixels, positive shifts sprite to the right
attr_writer :y_offset # In pixels, positive shifts sprite down
attr_accessor :width
attr_accessor :height
attr_accessor :sprite_size
attr_reader :tile_id
attr_accessor :character_name
attr_accessor :character_hue
attr_accessor :opacity
attr_reader :blend_type
attr_accessor :direction
attr_accessor :pattern
attr_accessor :pattern_surf
attr_accessor :lock_pattern
attr_reader :move_route_forcing
attr_accessor :through
attr_reader :animation_id
attr_accessor :animation_height
attr_accessor :animation_regular_tone
attr_accessor :transparent
attr_reader :move_speed
attr_reader :jump_speed
attr_accessor :walk_anime
attr_writer :bob_height
def initialize(map = nil)
@map = map
@id = 0
@original_x = 0
@original_y = 0
@x = 0
@y = 0
@real_x = 0
@real_y = 0
@x_offset = 0
@y_offset = 0
@width = 1
@height = 1
@sprite_size = [Game_Map::TILE_WIDTH, Game_Map::TILE_HEIGHT]
@tile_id = 0
@character_name = ""
@character_hue = 0
@opacity = 255
@blend_type = 0
@direction = 2
@pattern = 0
@pattern_surf = 0
@lock_pattern = false
@move_route_forcing = false
@through = false
animation_id = 0
@transparent = false
@original_direction = 2
@original_pattern = 0
@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
@original_move_route_index = 0
@walk_anime = true # Whether character should animate while moving
@step_anime = false # Whether character should animate while still
@direction_fix = false
@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)
@jumping_on_spot = false
@bob_height = 0
@wait_count = 0
@wait_start = nil
@moved_this_frame = false
@moveto_happened = false
@locked = false
@prelock_direction = 0
end
def animation_id=(value)
@animation_id = value
if value == 0
@animation_height = 3
@animation_regular_tone = false
end
end
def x_offset; return @x_offset || 0; end
def y_offset; return @y_offset || 0; end
def at_coordinate?(check_x, check_y)
return check_x >= @x && check_x < @x + @width &&
check_y > @y - @height && check_y <= @y
end
def in_line_with_coordinate?(check_x, check_y)
return (check_x >= @x && check_x < @x + @width) ||
(check_y > @y - @height && check_y <= @y)
end
def each_occupied_tile
(@x...(@x + @width)).each do |i|
((@y - @height + 1)..@y).each do |j|
yield i, j
end
end
end
def move_speed=(val)
@move_speed = val
# 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
case val
when 6 then @move_time = 0.05
when 5 then @move_time = 0.1
else @move_time = 2.0 / (2**val)
end
end
# Takes the same values as move_speed above.
def jump_speed=(val)
@jump_speed = val
case val
when 6 then @jump_time = 0.05
when 5 then @jump_time = 0.1
else @jump_time = 2.0 / (2**val)
end
end
# 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
# 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
@bob_height = 0 if !@bob_height
return @bob_height
end
def lock
return if @locked
@prelock_direction = 0 # Was @direction but disabled
turn_toward_player
@locked = true
end
def minilock
@prelock_direction = 0 # Was @direction but disabled
@locked = true
end
def lock?
return @locked
end
def unlock
return unless @locked
@locked = false
@direction = @prelock_direction if !@direction_fix && @prelock_direction != 0
end
#=============================================================================
# Information from map data
#=============================================================================
def map
return (@map) ? @map : $game_map
end
def terrain_tag
return self.map.terrain_tag(@x, @y)
end
def bush_depth
return @bush_depth || 0
end
def calculate_bush_depth
if @tile_id > 0 || @always_on_top || jumping?
@bush_depth = 0
return
end
this_map = (self.map.valid?(@x, @y)) ? [self.map, @x, @y] : $map_factory&.getNewMap(@x, @y, self.map.map_id)
if this_map && this_map[0].deepBush?(this_map[1], this_map[2])
xbehind = @x + (@direction == 4 ? 1 : @direction == 6 ? -1 : 0)
ybehind = @y + (@direction == 8 ? 1 : @direction == 2 ? -1 : 0)
if moving?
behind_map = (self.map.valid?(xbehind, ybehind)) ? [self.map, xbehind, ybehind] : $map_factory&.getNewMap(xbehind, ybehind, self.map.map_id)
@bush_depth = Game_Map::TILE_HEIGHT if behind_map[0].deepBush?(behind_map[1], behind_map[2])
else
@bush_depth = Game_Map::TILE_HEIGHT
end
elsif this_map && this_map[0].bush?(this_map[1], this_map[2]) && !moving?
@bush_depth = 12
else
@bush_depth = 0
end
end
def fullPattern
case self.direction
when 2 then return self.pattern
when 4 then return self.pattern + 4
when 6 then return self.pattern + 8
when 8 then return self.pattern + 12
end
return 0
end
#=============================================================================
# Passability
#=============================================================================
def passable?(x, y, dir, strict = false)
new_x = x + (dir == 6 ? 1 : dir == 4 ? -1 : 0)
new_y = y + (dir == 2 ? 1 : dir == 8 ? -1 : 0)
return false unless self.map.valid?(new_x, new_y)
return true if @through
if strict
return false unless self.map.passableStrict?(x, y, dir, self)
return false unless self.map.passableStrict?(new_x, new_y, 10 - dir, self)
else
return false unless self.map.passable?(x, y, dir, self)
return false unless self.map.passable?(new_x, new_y, 10 - dir, self)
end
self.map.events.each_value do |event|
next if self == event || !event.at_coordinate?(new_x, new_y) || event.through
return false if self != $game_player || event.character_name != ""
end
if $game_player.x == new_x && $game_player.y == new_y &&
!$game_player.through && @character_name != ""
return false
end
return true
end
def can_move_from_coordinate?(start_x, start_y, dir, strict = false)
case dir
when 2, 8 # Down, up
y_diff = (dir == 8) ? @height - 1 : 0
(start_x...(start_x + @width)).each do |i|
return false if !passable?(i, start_y - y_diff, dir, strict)
end
return true
when 4, 6 # Left, right
x_diff = (dir == 6) ? @width - 1 : 0
((start_y - @height + 1)..start_y).each do |i|
return false if !passable?(start_x + x_diff, i, dir, strict)
end
return true
when 1, 3 # Down diagonals
# Treated as moving down first and then horizontally, because that
# describes which tiles the character's feet touch
(start_x...(start_x + @width)).each do |i|
return false if !passable?(i, start_y, 2, strict)
end
x_diff = (dir == 3) ? @width - 1 : 0
((start_y - @height + 1)..start_y).each do |i|
return false if !passable?(start_x + x_diff, i + 1, dir + 3, strict)
end
return true
when 7, 9 # Up diagonals
# Treated as moving horizontally first and then up, because that describes
# which tiles the character's feet touch
x_diff = (dir == 9) ? @width - 1 : 0
((start_y - @height + 1)..start_y).each do |i|
return false if !passable?(start_x + x_diff, i, dir - 3, strict)
end
x_tile_offset = (dir == 9) ? 1 : -1
(start_x...(start_x + @width)).each do |i|
return false if !passable?(i + x_tile_offset, start_y - @height + 1, 8, strict)
end
return true
end
return false
end
def can_move_in_direction?(dir, strict = false)
return can_move_from_coordinate?(@x, @y, dir, strict)
end
#=============================================================================
# Screen position of the character
#=============================================================================
def screen_x
ret = ((@real_x.to_f - self.map.display_x) / Game_Map::X_SUBPIXELS).round
ret += @width * Game_Map::TILE_WIDTH / 2
ret += self.x_offset
return ret
end
def screen_y_ground
ret = ((@real_y.to_f - self.map.display_y) / Game_Map::Y_SUBPIXELS).round
ret += Game_Map::TILE_HEIGHT
return ret
end
def screen_y
ret = screen_y_ground
if jumping?
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
end
def screen_z(height = 0)
return 999 if @always_on_top
z = screen_y_ground
if @tile_id > 0
begin
return z + (self.map.priorities[@tile_id] * 32)
rescue
raise "Event's graphic is an out-of-range tile (event #{@id}, map #{self.map.map_id})"
end
end
# Add z if height exceeds 32
return z + ((height > Game_Map::TILE_HEIGHT) ? Game_Map::TILE_HEIGHT - 1 : 0)
end
#=============================================================================
# Movement
#=============================================================================
def moving?
return !@move_timer.nil?
end
def jumping?
return !@jump_timer.nil?
end
def straighten
@pattern = 0 if @walk_anime || @step_anime
@anime_count = 0
@prelock_direction = 0
end
def force_move_route(move_route)
if @original_move_route.nil?
@original_move_route = @move_route
@original_move_route_index = @move_route_index
end
@move_route = move_route
@move_route_index = 0
@move_route_forcing = true
@prelock_direction = 0
@wait_count = 0
@wait_start = nil
move_type_custom
end
def moveto(x, y)
@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
@prelock_direction = 0
@moveto_happened = true
calculate_bush_depth
triggerLeaveTile
end
def triggerLeaveTile
if @oldX && @oldY && @oldMap &&
(@oldX != self.x || @oldY != self.y || @oldMap != self.map.map_id)
EventHandlers.trigger(:on_leave_tile, self, @oldMap, @oldX, @oldY)
end
@oldX = self.x
@oldY = self.y
@oldMap = self.map.map_id
end
def increase_steps
@stop_count = 0
triggerLeaveTile
end
#=============================================================================
# Movement commands
#=============================================================================
def move_type_random
case rand(6)
when 0..3 then move_random
when 4 then move_forward
when 5 then @stop_count = 0
end
end
def move_type_toward_player
sx = @x + (@width / 2.0) - ($game_player.x + ($game_player.width / 2.0))
sy = @y - (@height / 2.0) - ($game_player.y - ($game_player.height / 2.0))
if sx.abs + sy.abs >= 20
move_random
return
end
case rand(6)
when 0..3 then move_toward_player
when 4 then move_random
when 5 then move_forward
end
end
def move_type_custom
return if jumping? || moving?
return if @move_route.list.size <= 1 # Empty move route
start_index = @move_route_index
(@move_route.list.size - 1).times do
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
@move_route = @original_move_route
@move_route_index = @original_move_route_index
@original_move_route = nil
end
@stop_count = 0
return
end
end
done_one_command = true
# 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
when 2 then move_left
when 3 then move_right
when 4 then move_up
when 5 then move_lower_left
when 6 then move_lower_right
when 7 then move_upper_left
when 8 then move_upper_right
when 9 then move_random
when 10 then move_toward_player
when 11 then move_away_from_player
when 12 then move_forward
when 13 then move_backward
when 14 then jump(command.parameters[0], command.parameters[1])
end
@move_route_index += 1 if @move_route.skippable || moving? || jumping?
return
end
# 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
when 19 then turn_up
when 20 then turn_right_90
when 21 then turn_left_90
when 22 then turn_180
when 23 then turn_right_or_left_90
when 24 then turn_random
when 25 then turn_toward_player
when 26 then turn_away_from_player
end
@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
$game_switches[command.parameters[0]] = true
self.map.need_refresh = true
when 28
$game_switches[command.parameters[0]] = false
self.map.need_refresh = true
when 29 then self.move_speed = command.parameters[0]
when 30 then self.move_frequency = command.parameters[0]
when 31 then @walk_anime = true
when 32 then @walk_anime = false
when 33 then @step_anime = true
when 34 then @step_anime = false
when 35 then @direction_fix = true
when 36 then @direction_fix = false
when 37 then @through = true
when 38 then @through = false
when 39
old_always_on_top = @always_on_top
@always_on_top = true
calculate_bush_depth if @always_on_top != old_always_on_top
when 40
old_always_on_top = @always_on_top
@always_on_top = false
calculate_bush_depth if @always_on_top != old_always_on_top
when 41
old_tile_id = @tile_id
@tile_id = 0
@character_name = command.parameters[0]
@character_hue = command.parameters[1]
if @original_direction != command.parameters[2]
@direction = command.parameters[2]
@original_direction = @direction
@prelock_direction = 0
end
if @original_pattern != command.parameters[3]
@pattern = command.parameters[3]
@original_pattern = @pattern
end
calculate_bush_depth if @tile_id != old_tile_id
when 42 then @opacity = command.parameters[0]
when 43 then @blend_type = command.parameters[0]
when 44 then pbSEPlay(command.parameters[0])
when 45
eval(command.parameters[0])
if command.parameters[0][/^move_random_range/] ||
command.parameters[0][/^move_random_UD/] ||
command.parameters[0][/^move_random_LR/]
@move_route_index += 1
return
end
end
@move_route_index += 1
end
end
end
def move_generic(dir, turn_enabled = true)
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)
end
end
def move_down(turn_enabled = true)
move_generic(2, turn_enabled)
end
def move_left(turn_enabled = true)
move_generic(4, turn_enabled)
end
def move_right(turn_enabled = true)
move_generic(6, turn_enabled)
end
def move_up(turn_enabled = true)
move_generic(8, turn_enabled)
end
def move_upper_left
unless @direction_fix
@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
def move_upper_right
unless @direction_fix
@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
def move_lower_left
unless @direction_fix
@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
def move_lower_right
unless @direction_fix
@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
# Anticlockwise.
def moveLeft90
case self.direction
when 2 then move_right # down
when 4 then move_down # left
when 6 then move_up # right
when 8 then move_left # up
end
end
# Clockwise.
def moveRight90
case self.direction
when 2 then move_left # down
when 4 then move_up # left
when 6 then move_down # right
when 8 then move_right # up
end
end
def move_random
case rand(4)
when 0 then move_down(false)
when 1 then move_left(false)
when 2 then move_right(false)
when 3 then move_up(false)
end
end
def move_random_range(xrange = -1, yrange = -1)
dirs = [] # 0=down, 1=left, 2=right, 3=up
if xrange < 0
dirs.push(1)
dirs.push(2)
elsif xrange > 0
dirs.push(1) if @x > @original_x - xrange
dirs.push(2) if @x < @original_x + xrange
end
if yrange < 0
dirs.push(0)
dirs.push(3)
elsif yrange > 0
dirs.push(0) if @y < @original_y + yrange
dirs.push(3) if @y > @original_y - yrange
end
return if dirs.length == 0
case dirs[rand(dirs.length)]
when 0 then move_down(false)
when 1 then move_left(false)
when 2 then move_right(false)
when 3 then move_up(false)
end
end
def move_random_UD(range = -1)
move_random_range(0, range)
end
def move_random_LR(range = -1)
move_random_range(range, 0)
end
def move_toward_player
sx = @x + (@width / 2.0) - ($game_player.x + ($game_player.width / 2.0))
sy = @y - (@height / 2.0) - ($game_player.y - ($game_player.height / 2.0))
return if sx == 0 && sy == 0
abs_sx = sx.abs
abs_sy = sy.abs
if abs_sx == abs_sy
(rand(2) == 0) ? abs_sx += 1 : abs_sy += 1
end
if abs_sx > abs_sy
(sx > 0) ? move_left : move_right
if !moving? && sy != 0
(sy > 0) ? move_up : move_down
end
else
(sy > 0) ? move_up : move_down
if !moving? && sx != 0
(sx > 0) ? move_left : move_right
end
end
end
def move_away_from_player
sx = @x + (@width / 2.0) - ($game_player.x + ($game_player.width / 2.0))
sy = @y - (@height / 2.0) - ($game_player.y - ($game_player.height / 2.0))
return if sx == 0 && sy == 0
abs_sx = sx.abs
abs_sy = sy.abs
if abs_sx == abs_sy
(rand(2) == 0) ? abs_sx += 1 : abs_sy += 1
end
if abs_sx > abs_sy
(sx > 0) ? move_right : move_left
if !moving? && sy != 0
(sy > 0) ? move_down : move_up
end
else
(sy > 0) ? move_down : move_up
if !moving? && sx != 0
(sx > 0) ? move_right : move_left
end
end
end
def move_forward
case @direction
when 2 then move_down(false)
when 4 then move_left(false)
when 6 then move_right(false)
when 8 then move_up(false)
end
end
def move_backward
last_direction_fix = @direction_fix
@direction_fix = true
case @direction
when 2 then move_up(false)
when 4 then move_right(false)
when 6 then move_left(false)
when 8 then move_down(false)
end
@direction_fix = last_direction_fix
end
def jump(x_plus, y_plus)
if x_plus != 0 || y_plus != 0
if x_plus.abs > y_plus.abs
(x_plus < 0) ? turn_left : turn_right
else
(y_plus < 0) ? turn_up : turn_down
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_plus
@y += 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
@jumping_on_spot = (real_distance == 0)
increase_steps
end
def jumpForward(distance = 1)
return false if distance == 0
old_x = @x
old_y = @y
case self.direction
when 2 then jump(0, distance) # down
when 4 then jump(-distance, 0) # left
when 6 then jump(distance, 0) # right
when 8 then jump(0, -distance) # up
end
return @x != old_x || @y != old_y
end
def jumpBackward(distance = 1)
return false if distance == 0
old_x = @x
old_y = @y
case self.direction
when 2 then jump(0, -distance) # down
when 4 then jump(distance, 0) # left
when 6 then jump(-distance, 0) # right
when 8 then jump(0, distance) # up
end
return @x != old_x || @y != old_y
end
def turn_generic(dir)
return if @direction_fix
oldDirection = @direction
@direction = dir
@stop_count = 0
check_event_trigger_after_turning if dir != oldDirection
end
def turn_down; turn_generic(2); end
def turn_left; turn_generic(4); end
def turn_right; turn_generic(6); end
def turn_up; turn_generic(8); end
def turn_right_90
case @direction
when 2 then turn_left
when 4 then turn_up
when 6 then turn_down
when 8 then turn_right
end
end
def turn_left_90
case @direction
when 2 then turn_right
when 4 then turn_down
when 6 then turn_up
when 8 then turn_left
end
end
def turn_180
case @direction
when 2 then turn_up
when 4 then turn_right
when 6 then turn_left
when 8 then turn_down
end
end
def turn_right_or_left_90
(rand(2) == 0) ? turn_right_90 : turn_left_90
end
def turn_random
case rand(4)
when 0 then turn_up
when 1 then turn_right
when 2 then turn_left
when 3 then turn_down
end
end
def turn_toward_player
sx = @x + (@width / 2.0) - ($game_player.x + ($game_player.width / 2.0))
sy = @y - (@height / 2.0) - ($game_player.y - ($game_player.height / 2.0))
return if sx == 0 && sy == 0
if sx.abs > sy.abs
(sx > 0) ? turn_left : turn_right
else
(sy > 0) ? turn_up : turn_down
end
end
def turn_away_from_player
sx = @x + (@width / 2.0) - ($game_player.x + ($game_player.width / 2.0))
sy = @y - (@height / 2.0) - ($game_player.y - ($game_player.height / 2.0))
return if sx == 0 && sy == 0
if sx.abs > sy.abs
(sx > 0) ? turn_right : turn_left
else
(sy > 0) ? turn_down : turn_up
end
end
#=============================================================================
# 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
# Update command
update_command
# Update movement
(moving? || jumping?) ? update_move : update_stop
# Update animation
update_pattern
end
def update_command
if @wait_count > 0
return if System.uptime - @wait_start < @wait_count
@wait_count = 0
@wait_start = nil
end
if @move_route_forcing
move_type_custom
elsif !@starting && !lock? && !moving? && !jumping?
update_command_new
end
end
def update_command_new
if @stop_count >= @command_delay
case @move_type
when 1 then move_type_random
when 2 then move_type_toward_player
when 3 then move_type_custom
end
end
end
def update_move
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
# 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 >= @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
@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?
EventHandlers.trigger(:on_step_taken, self)
calculate_bush_depth
@stopped_this_frame = true
elsif !@moved_last_frame || @stopped_last_frame # Started a new step
calculate_bush_depth
end
# Increment animation counter
@anime_count += @delta_t if @walk_anime || @step_anime
@moved_this_frame = true
end
def update_stop
@anime_count += @delta_t if @step_anime
@stop_count += @delta_t if !@starting && !lock?
end
def update_pattern
return if @lock_pattern
# 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
@anime_count = 0
return
end
# Character has started to move, change pattern immediately
if !@moved_last_frame && @moved_this_frame && !@step_anime
@pattern = (@pattern + 1) % 4 if @walk_anime
@anime_count = 0
return
end
# 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.
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 -= pattern_time
end
end