FRAMES = 4 # Number of Frames (horizontal)
DIRECTIONS = [2, 4, 6, 8, 1, 3, 7, 9] # 1 = lower_left, 2 = down,
# 3 = lower_right, 4 = left, 6 = right,
# 7 = upper_left, 8 = up, 9 = upper_right
class Game_Character
attr_reader :move_speed
#--------------------------------------------------------------------------
# * Frame Update : Animation Counters
#--------------------------------------------------------------------------
def update_animation
# If animation count exceeds maximum value
# * Maximum value is move speed * 1 taken from basic value 18
if @anime_count > 18 - @move_speed * 2
# If stop animation is OFF when stopping
if not @step_anime and @stop_count > 0
# Return to original pattern
@pattern = @original_pattern
# If stop animation is ON when moving
else
# Update pattern
@pattern = (@pattern + 1) % FRAMES
end
# Clear animation count
@anime_count = 0
end
end
#--------------------------------------------------------------------------
# * Move Lower Left
#--------------------------------------------------------------------------
def move_lower_left(turn_enabled = true)
# Turn to direction
#if turn_enabled
turn_lower_left
#end
# When a down to left or a left to down course is passable
if passable?(@x, @y, 1)
# Update coordinates
@x -= 1
@y += 1
# Increase steps
increase_steps
end
end
#--------------------------------------------------------------------------
# * Move Lower Right
#--------------------------------------------------------------------------
def move_lower_right(turn_enabled = true)
# Turn to direction
#if turn_enabled
turn_lower_right
#end
# When a down to right or a right to down course is passable
if passable?(@x, @y, 3)
# Update coordinates
@x += 1
@y += 1
# Increase steps
increase_steps
end
end
#--------------------------------------------------------------------------
# * Move Upper Left
#--------------------------------------------------------------------------
def move_upper_left(turn_enabled = true)
# Turn to direction
#if turn_enabled
turn_upper_left
#end
# When an up to left or a left to up course is passable
if passable?(@x, @y, 7)
# Update coordinates
@x -= 1
@y -= 1
# Increase steps
increase_steps
end
end
#--------------------------------------------------------------------------
# * Move Upper Right
#--------------------------------------------------------------------------
def move_upper_right(turn_enabled = true)
# Turn to direction
#if turn_enabled
turn_upper_right
#end
# When an up to right or a right to up course is passable
if passable?(@x, @y, 9)
# Update coordinates
@x += 1
@y -= 1
# Increase steps
increase_steps
end
end
#--------------------------------------------------------------------------
# * Move at Random
#--------------------------------------------------------------------------
def move_random
d = 0
count = 0
while not moving?
forward = rand(3)
case forward
when 0..1
case d
when 1
turn_right_45
count += 1
when 2
turn_left_45
count += 1
end
move_forward
if d == 0
d = rand(2)
end
when 2
case d
when 1
turn_right_90
count += 1
when 2
turn_left_90
count += 1
end
move_forward
if d == 0
d = rand(2)
end
end
break if count == 7
end
end
#--------------------------------------------------------------------------
# * 1 Step Forward
#--------------------------------------------------------------------------
def move_forward(move_dir = nil)
move_dir = @direction if move_dir.nil?
case move_dir
when 2 # Move down
move_down(false)
when 4 # Move left
move_left(false)
when 6 # Move right
move_right(false)
when 8 # Move up
move_up(false)
when 1
move_lower_left(false)
when 3
move_lower_right(false)
when 7
move_upper_left(false)
when 9
move_upper_right(false)
end
tries = 0
while not moving?
if tries == 4
@direction = move_dir unless @direction_fix
break
else
case move_dir
when 1
case tries
when 0
move_down
when 1
move_left
when 2
move_lower_right
when 3
move_upper_left
end
when 2
case tries
when 0
move_lower_right
when 1
move_lower_left
when 2
move_right
when 3
move_left
end
when 3
case tries
when 0
move_right
when 1
move_down
when 2
move_upper_right
when 3
move_lower_left
end
when 4
case tries
when 0
move_lower_left
when 1
move_upper_left
when 2
move_down
when 3
move_up
end
when 6
case tries
when 0
move_upper_right
when 1
move_lower_left
when 2
move_up
when 3
move_down
end
when 7
case tries
when 0
move_left
when 1
move_up
when 2
move_lower_left
when 3
move_upper_right
end
when 8
case tries
when 0
move_upper_left
when 1
move_upper_right
when 2
move_left
when 3
move_right
end
when 9
case tries
when 0
move_up
when 1
move_right
when 2
move_upper_left
when 3
move_lower_right
end
end
tries += 1
end
end
end
#--------------------------------------------------------------------------
# * 1 Step Backward
#--------------------------------------------------------------------------
def move_backward
# Remember direction fix situation
last_direction_fix = @direction_fix
# Force directino fix
@direction_fix = true
# Branch by direction
case @direction
when 8 # Move down
move_down(false)
when 6 # Move left
move_left(false)
when 4 # Move right
move_right(false)
when 2 # Move up
move_up(false)
when 9
move_lower_left(false)
when 7
move_lower_right(false)
when 3
move_upper_left(false)
when 1
move_upper_right(false)
end
# Return direction fix situation back to normal
@direction_fix = last_direction_fix
end
#--------------------------------------------------------------------------
# * Move Type : Random
#--------------------------------------------------------------------------
def move_type_random
# Branch by random numbers 0-5
case rand(5)
when 0..2
move_random
when 3
turn_random
move_forward
when 4 # Temporary stop
@stop_count = 0
end
end
#--------------------------------------------------------------------------
# * Move Type : Approach
#--------------------------------------------------------------------------
def move_type_toward_player
# Get difference in player coordinates
sx = @x - $game_player.x
sy = @y - $game_player.y
# Get absolute value of difference
abs_sx = sx > 0 ? sx : -sx
abs_sy = sy > 0 ? sy : -sy
# If separated by 20 or more tiles matching up horizontally and vertically
if sx + sy >= 20
# Random
move_random
return
end
# Branch by random numbers 0-5
case rand(6)
when 0..3 # Approach player
move_toward_player
when 4 # random
move_random
when 5 # 1 step forward
move_forward
end
end
#--------------------------------------------------------------------------
# * Move toward Player
#--------------------------------------------------------------------------
def move_toward_player
# Get difference in player coordinates
sx = @x - $game_player.x
sy = @y - $game_player.y
# Get absolute value of difference
abs_sx = sx.abs
abs_sy = sy.abs
# If coordinates are equal
if (sx == 0 and sy == 0)
return
end
#if event is already at nearest point
if not @through and [0, 1].include?(abs_sx) and [0,1].include?(abs_sy)
turn_toward_player
return
end
# Check if it is faster to walk diagonal
unless sx == 0 or sy == 0
case ((1.00 * sx / sy) * 3).round
when -9...-1
if sy < 0
move_lower_left
else
move_upper_right
end
when 1...9
if sy < 0
move_lower_right
else
move_upper_left
end
end
end
# check if already moving (diagonal)
unless moving?
# If horizontal distance is longer
if abs_sx > abs_sy
# Move towards player, prioritize left and right directions
sx > 0 ? move_left : move_right
if not moving? and sy != 0
sy > 0 ? move_up : move_down
end
# If vertical distance is longer
else
# Move towards player, prioritize up and down directions
sy > 0 ? move_up : move_down
if not moving? and sx != 0
sx > 0 ? move_left : move_right
end
end
end
unless moving?
move_random
end
end
#--------------------------------------------------------------------------
# * Move away from Player
#--------------------------------------------------------------------------
def move_away_from_player
# Get difference in player coordinates
sx = @x - $game_player.x
sy = @y - $game_player.y
d = []
# Get absolute value of difference
abs_sx = sx.abs
abs_sy = sy.abs
# If coordinates are equal
if sx == 0 and sy == 0
return
end
# If player is at safe distance
dis = (3.00 * $game_player.move_speed / @move_speed )
if abs_sx >= dis and abs_sy >= dis
move_random
return
end
unless sx == 0 or sy == 0
case ((1.00 * sx / sy) * 3).round
when -9...-1
if sy < 0
d.push(6, 8, 9)
else
d.push(1, 2, 4)
end
when 1...9
if sy < 0
d.push(4, 7, 8)
else
d.push(2, 3, 6)
end
end
end
if d == []
# If horizontal distance is longer
if abs_sx > abs_sy
# Move away from player, prioritize left and right directions
if sx > 0
d.push(3, 6, 9)
else
d.push(1, 4, 7)
end
# If vertical distance is longer
else
# Move away from player, prioritize up and down directions
if sy > 0
d.push(1, 2, 3)
else
d.push(7, 8, 9)
end
end
end
tried = []
dir = d[rand(d.length)]
while not moving?
if tried.sort == d.sort
move_random
break
end
while tried.include?(dir)
dir = d[rand(d.length)]
end
move_forward(dir)
tried.push(dir)
end
end
#--------------------------------------------------------------------------
# * Turn Lower Left
#--------------------------------------------------------------------------
def turn_lower_left
unless @direction_fix
@direction = 1
@stop_count = 0
end
end
#--------------------------------------------------------------------------
# * Turn Lower Right
#--------------------------------------------------------------------------
def turn_lower_right
unless @direction_fix
@direction = 3
@stop_count = 0
end
end
#--------------------------------------------------------------------------
# * Turn Upper Left
#--------------------------------------------------------------------------
def turn_upper_left
unless @direction_fix
@direction = 7
@stop_count = 0
end
end
#--------------------------------------------------------------------------
# * Turn Upper Right
#--------------------------------------------------------------------------
def turn_upper_right
unless @direction_fix
@direction = 9
@stop_count = 0
end
end
#--------------------------------------------------------------------------
# * Turn 45° Right
#--------------------------------------------------------------------------
def turn_right_45
case @direciton
when 1
turn_left
when 2
turn_lower_left
when 3
turn_down
when 6
turn_lower_right
when 9
turn_right
when 8
turn_upper_right
when 7
turn_up
when 4
turn_upper_ight
end
end
#--------------------------------------------------------------------------
# * Turn 45° Left
#--------------------------------------------------------------------------
def turn_left_45
case @direciton
when 1
turn_down
when 2
turn_lower_right
when 3
turn_right
when 6
turn_upper_right
when 9
turn_up
when 8
turn_upper_left
when 7
turn_left
when 4
turn_lower_left
end
end
#--------------------------------------------------------------------------
# * Turn 90° Right
#--------------------------------------------------------------------------
def turn_right_90
case @direction
when 1
turn_upper_left
when 2
turn_left
when 3
turn_lower_left
when 4
turn_up
when 6
turn_down
when 7
turn_upper_right
when 8
turn_right
when 9
turn_lower_right
end
end
#--------------------------------------------------------------------------
# * Turn 90° Left
#--------------------------------------------------------------------------
def turn_left_90
case @direction
when 1
turn_lower_right
when 2
turn_right
when 3
turn_upper_right
when 4
turn_down
when 6
turn_up
when 7
turn_upper_left
when 8
turn_left
when 9
turn_lower_left
end
end
#--------------------------------------------------------------------------
# * Turn 180°
#--------------------------------------------------------------------------
def turn_180
case @direction
when 1
turn_upper_right
when 2
turn_up
when 3
turn_upper_left
when 4
turn_right
when 6
turn_left
when 7
turn_lower_right
when 8
turn_down
when 9
turn_lower_left
end
end
#--------------------------------------------------------------------------
# * Turn 45° Right or Left
#--------------------------------------------------------------------------
def turn_right_or_left_45
if rand(2) == 0
turn_right_45
else
turn_left_45
end
end
#--------------------------------------------------------------------------
# * Turn 90° Right or Left
#--------------------------------------------------------------------------
def turn_right_or_left_90
if rand(2) == 0
turn_right_90
else
turn_left_90
end
end
#--------------------------------------------------------------------------
# * Turn at Random
#--------------------------------------------------------------------------
def turn_random
case rand(8)
when 0
turn_lower_left
when 1
turn_down
when 2
turn_lower_right
when 3
turn_left
when 4
turn_right
when 5
turn_upper_left
when 6
turn_up
when 7
turn_upper_right
end
end
#--------------------------------------------------------------------------
# * Turn Toward Player
#--------------------------------------------------------------------------
def turn_toward_player
# Get difference in player coordinates
sx = @x - $game_player.x
sy = @y - $game_player.y
d = 0
# If coordinates are equal
if sx == 0 and sy == 0
turn_random
return
end
# if there's an option to look diagonal
unless sx == 0 or sy == 0
case ((1.00 * sx / sy) * 3).round
when -9...-1
if sy < 0
d = 1
else
d = 9
end
when 1...9
if sy < 0
d = 3
else
d = 7
end
end
else
# Get absolute value of difference
abs_sx = sx.abs
abs_sy = sy.abs
# If horizontal distance is longer
if abs_sx > abs_sy
# Turn away from player, prioritize left and right directions
if sx > 0
d = 4
else
d = 6
end
# If vertical distance is longer
else
# Turn away from player, prioritize up and down directions
if sy > 0
d = 8
else
d = 2
end
end
end
turn(d)
end
#--------------------------------------------------------------------------
# * Turn Away From Player
#--------------------------------------------------------------------------
def turn_away_from_player
# Get difference in player coordinates
sx = @x - $game_player.x
sy = @y - $game_player.y
d = 0
# If coordinates are equal
if sx == 0 and sy == 0
turn_random
return
end
unless sx == 0 or sy == 0
case ((1.00 * sx / sy) * 3).round
when -9...-1
if sy < 0
d = 9
else
d = 1
end
when 1...9
if sy < 0
d = 7
else
d = 3
end
end
else
# Get absolute value of difference
abs_sx = sx.abs
abs_sy = sy.abs
# If horizontal distance is longer
if abs_sx > abs_sy
# Turn away from player, prioritize left and right directions
if sx > 0
d = 6
else
d = 4
end
# If vertical distance is longer
else
# Turn away from player, prioritize up and down directions
if sy > 0
d = 2
else
d = 8
end
end
end
turn(d)
end
#--------------------------------------------------------------------------
# * Turn (Direction)
#--------------------------------------------------------------------------
def turn(direction)
case direction
when 1
turn_lower_left
when 2
turn_down
when 3
turn_lower_right
when 4
turn_left
when 6
turn_right
when 7
turn_upper_left
when 8
turn_up
when 9
turn_upper_right
end
end
#--------------------------------------------------------------------------
# * Determine if Passable
# x : x-coordinate
# y : y-coordinate
# d : direction (0,2,4,6,8)
# * 0 = Determines if all directions are impassable (for jumping)
#--------------------------------------------------------------------------
def passable?(x, y, d)
# Get new coordinates
new_x = x + ([3, 6, 9].include?(d) ? 1 : [1, 4, 7].include?(d) ? -1 : 0)
new_y = y + ([1, 2, 3].include?(d) ? 1 : [7, 8, 9].include?(d) ? -1 : 0)
# If coordinates are outside of map
unless $game_map.valid?(new_x, new_y)
# impassable
return false
end
# If through is ON
if @through
# passable
return true
end
# If unable to leave first move tile in designated direction
unless $game_map.passable?(x, y, d, self)
# impassable
return false
end
# If unable to enter move tile in designated direction
unless $game_map.passable?(new_x, new_y, 10 - d)
# impassable
return false
end
# Loop all events
for event in $game_map.events.values
# If event coordinates are consistent with move destination
if event.x == new_x and event.y == new_y
# If through is OFF
unless event.through
# If self is event
if self != $game_player
# impassable
return false
end
# With self as the player and partner graphic as character
if event.character_name != ""
# impassable
return false
end
end
end
end
# If player coordinates are consistent with move destination
if $game_player.x == new_x and $game_player.y == new_y
# If through is OFF
unless $game_player.through
# If your own graphic is the character
if @character_name != ""
# impassable
return false
end
end
end
# passable
return true
end
end
class Sprite_Character
def update
super
# If tile ID, file name, or hue are different from current ones
if @tile_id != @character.tile_id or
@character_name != @character.character_name or
@character_hue != @character.character_hue
# Remember tile ID, file name, and hue
@tile_id = @character.tile_id
@character_name = @character.character_name
@character_hue = @character.character_hue
# If tile ID value is valid
if @tile_id >= 384
self.bitmap = RPG::Cache.tile($game_map.tileset_name,
@tile_id, @character.character_hue)
self.src_rect.set(0, 0, 32, 32)
self.ox = 16
self.oy = 32
# If tile ID value is invalid
else
self.bitmap = RPG::Cache.character(@character.character_name,
@character.character_hue)
@cw = bitmap.width / FRAMES # number of frames
@ch = bitmap.height / 8 # number of directions
self.ox = @cw / 2
self.oy = @ch
end
end
# Set visible situation
self.visible = (not @character.transparent)
# If graphic is character
if @tile_id == 0
# Set rectangular transfer
sx = @character.pattern * @cw
sy = DIRECTIONS.index(@character.direction) * @ch
self.src_rect.set(sx, sy, @cw, @ch)
end
# Set sprite coordinates
self.x = @character.screen_x
self.y = @character.screen_y
self.z = @character.screen_z(@ch)
# Set opacity level, blend method, and bush depth
self.opacity = @character.opacity
self.blend_type = @character.blend_type
self.bush_depth = @character.bush_depth
# Animation
if @character.animation_id != 0
animation = $data_animations[@character.animation_id]
animation(animation, true)
@character.animation_id = 0
end
end
end
class Game_Character
end
class Game_Player
def update_player_movement
# making the 8-way movement possible...
case Input.dir8
when 1
move_lower_left
when 2
move_down
when 3
move_lower_right
when 4
move_left
when 6
move_right
when 7
move_upper_left
when 8
move_up
when 9
move_upper_right
end
end
end