#==============================================================================
# ** Eight Directional / Multiple Frame Movement Script v2 (10-05-2006)
# by DerVVulfman
#------------------------------------------------------------------------------
#
# This system allows the user to have either 4 OR 8 directional movement by
# the events and player sprites he uses. It also allows the user to set up
# the number of animation frames and whether a generic idle pose is used.
#
#==============================================================================
# * Configuration Section *
DIR_8_CHAR = false # This enables/disables 8 directional charsets
DIR_8_CONTROL = true # This enables/disables 8 directional movement
DIR_8_POSES = false # This enables/disables 8 directional facing
DIR_8_FRAMES = 4 # This holds the number of motion frames when walking
DIR_8_STAND = false # This determines if separate frame used for standing
$dir_8_fram = {1 => 8, 2 => 4}
#==============================================================================
# ** Game_Character (Modification)
#------------------------------------------------------------------------------
# This class deals with characters. It's used as a superclass for the
# Game_Player and Game_Event classes.
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Public Instance Variables
#--------------------------------------------------------------------------
attr_reader :step_anime # Holds a sprite's step flag
attr_reader :walk_anime # Holds an event's movement flag
attr_reader :stop_count # The number of steps left to count
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Branch with jumping, moving, and stopping
if jumping?
update_jump
elsif moving?
update_move
else
update_stop
end
# 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 ) % DIR_8_FRAMES)
end
# Clear animation count
@anime_count = 0
end
# If waiting
if @wait_count > 0
# Reduce wait count
@wait_count -= 1
return
end
# If move route is forced
if @move_route_forcing
# Custom move
move_type_custom
return
end
# When waiting for event execution or locked
if @starting or lock?
# Not moving by self
return
end
# If stop count exceeds a certain value (computed from move frequency)
if @stop_count > (40 - @move_frequency * 2) * (6 - @move_frequency)
# Branch by move type
case @move_type
when 1 # Random
move_type_random
when 2 # Approach
move_type_toward_player
when 3 # Custom
move_type_custom
end
end
end
#--------------------------------------------------------------------------
# * Move Lower Left (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def move_lower_left
unless @direction_fix
if DIR_8_POSES
# Face down-left
@direction = 1
else
# Face down is facing right or up
@direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction)
end
end
# When a down to left or a left to down course is passable
if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 4)) or
(passable?(@x, @y, 4) and passable?(@x - 1, @y, 2))
if DIR_8_POSES
turn_downleft
end
@x -= 1
@y += 1
increase_steps
end
end
#--------------------------------------------------------------------------
# * Move Lower Right (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def move_lower_right
unless @direction_fix
if DIR_8_POSES
@direction = 3
else
# Face right if facing left, and face down if facing up
@direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction)
end
end
if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 6)) or
(passable?(@x, @y, 6) and passable?(@x + 1, @y, 2))
if DIR_8_POSES
turn_downright
end
@x += 1
@y += 1
increase_steps
end
end
#--------------------------------------------------------------------------
# * Move Upper Left (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def move_upper_left
unless @direction_fix
if DIR_8_POSES
@direction = 7
else
# Face left if facing right, and face up if facing down
@direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction)
end
end
if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 4)) or
(passable?(@x, @y, 4) and passable?(@x - 1, @y, 8))
if DIR_8_POSES
turn_upleft
end
@x -= 1
@y -= 1
increase_steps
end
end
#--------------------------------------------------------------------------
# * Move Upper Left (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def move_upper_right
unless @direction_fix
if DIR_8_POSES
@direction = 9
else
# Face right if facing left, and face up if facing down
@direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction)
end
end
if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 6)) or
(passable?(@x, @y, 6) and passable?(@x + 1, @y, 8))
if DIR_8_POSES
turn_upright
end
@x += 1
@y -= 1
increase_steps
end
end
#--------------------------------------------------------------------------
# * Move at Random (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def move_random
# Determine random value's max based on the number of poses used
if DIR_8_POSES
# Random value maxed out at 8 directions
caserand=8
else
# Random value maxed out at 4 directions
caserand=4
end
# Branch according to random value
case rand(caserand)
when 0 # Move down
move_down(false)
when 1 # Move left
move_left(false)
when 2 # Move right
move_right(false)
when 3 # Move up
move_up(false)
when 4 # Move Upper Left
move_lower_left
when 5 # Move Upper Right
move_lower_right
when 6 # Move Lower Left
move_upper_left
when 7 # Move Lower Right
move_upper_right
end
end
#--------------------------------------------------------------------------
# * Move toward Player (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def move_toward_player
# Get difference in player coordinates
sx = @x - $game_player.x
sy = @y - $game_player.y
# If coordinates are equal
if sx == 0 and sy == 0
return
end
# Get absolute value of difference
abs_sx = sx.abs
abs_sy = sy.abs
if DIR_8_POSES
# Move towards player, prioritizes diagonal before straight
if sx > 0
if sy > 0
move_upper_left
elsif sy <0
move_lower_left
else
move_left
end
elsif sx <0
if sy > 0
move_upper_right
elsif sy <0
move_lower_right
else
move_right
end
else
if sy > 0
move_up
elsif sy <0
move_down
else
# nada (Completely Equal)
end
end
else
# If horizontal and vertical distances are equal
if abs_sx == abs_sy
# Increase one of them randomly by 1
rand(2) == 0 ? abs_sx += 1 : abs_sy += 1
end
# 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
end
#--------------------------------------------------------------------------
# * Move away from Player (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def move_away_from_player
# Get difference in player coordinates
sx = @x - $game_player.x
sy = @y - $game_player.y
# If coordinates are equal
if sx == 0 and sy == 0
return
end
# Get absolute value of difference
abs_sx = sx.abs
abs_sy = sy.abs
if DIR_8_POSES
# Move away from player, prioritizes diagonal before straight
if sx > 0
if sy > 0
move_lower_right
elsif sy <0
move_upper_right
else
move_right
end
elsif sx <0
if sy > 0
move_lower_left
elsif sy <0
move_upper_left
else
move_left
end
else
if sy > 0
move_down
elsif sy <0
move_up
else
# nada (Completely Equal)
end
end
else
# If horizontal and vertical distances are equal
if abs_sx == abs_sy
# Increase one of them randomly by 1
rand(2) == 0 ? abs_sx += 1 : abs_sy += 1
end
# If horizontal distance is longer
if abs_sx > abs_sy
# Move away from player, prioritize left and right directions
sx > 0 ? move_right : move_left
if not moving? and sy != 0
sy > 0 ? move_down : move_up
end
# If vertical distance is longer
else
# Move away from player, prioritize up and down directions
sy > 0 ? move_down : move_up
if not moving? and sx != 0
sx > 0 ? move_right : move_left
end
end
end
end
#--------------------------------------------------------------------------
# * 1 Step Forward (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def move_forward
if DIR_8_POSES
case @direction
when 2
move_down(false)
when 4
move_left(false)
when 6
move_right(false)
when 8
move_up(false)
end
else
case @direction
when 1
move_lower_left
when 2
move_down(false)
when 3
move_lower_right
when 4
move_left(false)
when 6
move_right(false)
when 7
move_upper_left
when 8
move_up(false)
when 9
move_upper_right
end
end
end
#--------------------------------------------------------------------------
# * 1 Step Backward (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def move_backward
# Remember direction fix situation
last_direction_fix = @direction_fix
# Force directino fix
@direction_fix = true
if DIR_8_POSES
# Branch by direction
case @direction
when 1
move_upper_right
when 2
move_up(false)
when 3
move_upper_left
when 4
move_right(false)
when 6
move_left(false)
when 7
move_lower_right
when 8
move_down(false)
when 9
move_lower_left
end
else
case @direction
when 2 # Down
move_up(false)
when 4 # Left
move_right(false)
when 6 # Right
move_left(false)
when 8 # Up
move_down(false)
end
end
# Return direction fix situation back to normal
@direction_fix = last_direction_fix
end
#--------------------------------------------------------------------------
# * Jump (Rewritten for diagonal animation)
# x_plus : x-coordinate plus value
# y_plus : y-coordinate plus value
#--------------------------------------------------------------------------
def jump(x_plus, y_plus)
if DIR_8_POSES
# Turns player, prioritizes diagonal before straight
if x_plus > 0
if y_plus > 0
turn_downright
elsif y_plus <0
turn_upright
else
turn_right
end
elsif x_plus <0
if y_plus > 0
turn_downleft
elsif y_plus <0
turn_upleft
else
turn_left
end
else
if y_plus > 0
turn_down
elsif y_plus <0
turn_up
else
# nada (Completely Equal)
end
end
else
# If plus value is not (0,0)
if x_plus != 0 or y_plus != 0
# If horizontal distnace is longer
if x_plus.abs > y_plus.abs
# Change direction to left or right
x_plus < 0 ? turn_left : turn_right
# If vertical distance is longer, or equal
else
# Change direction to up or down
y_plus < 0 ? turn_up : turn_down
end
end
end
# Calculate new coordinates
new_x = @x + x_plus
new_y = @y + y_plus
# If plus value is (0,0) or jump destination is passable
if (x_plus == 0 and y_plus == 0) or passable?(new_x, new_y, 0)
# Straighten position
straighten
# Update coordinates
@x = new_x
@y = new_y
# Calculate distance
distance = Math.sqrt(x_plus * x_plus + y_plus * y_plus).round
# Set jump count
@jump_peak = 10 + distance - @move_speed
@jump_count = @jump_peak * 2
# Clear stop count
@stop_count = 0
end
end
#--------------------------------------------------------------------------
# * Turn Up Left (Added for diagonal animation)
#--------------------------------------------------------------------------
def turn_upleft
unless @direction_fix
@direction = 7
@stop_count = 0
end
end
#--------------------------------------------------------------------------
# * Turn Up Right (Added for diagonal animation)
#--------------------------------------------------------------------------
def turn_upright
unless @direction_fix
@direction = 9
@stop_count = 0
end
end
#--------------------------------------------------------------------------
# * Turn Down Left (Added for diagonal animation)
#--------------------------------------------------------------------------
def turn_downleft
unless @direction_fix
@direction = 1
@stop_count = 0
end
end
#--------------------------------------------------------------------------
# * Turn Down Right (Added for diagonal animation)
#--------------------------------------------------------------------------
def turn_downright
unless @direction_fix
@direction = 3
@stop_count = 0
end
end
#--------------------------------------------------------------------------
# * Turn 90° Right (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def turn_right_90
case @direction
when 1
turn_downright
when 2
turn_left
when 3
turn_upright
when 4
turn_up
when 6
turn_down
when 7
turn_downleft
when 8
turn_right
when 9
turn_upleft
end
end
#--------------------------------------------------------------------------
# * Turn 90° Left (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def turn_left_90
case @direction
when 1
turn_upleft
when 2
turn_right
when 3
turn_downleft
when 4
turn_down
when 6
turn_up
when 7
turn_upright
when 8
turn_left
when 9
turn_downright
end
end
#--------------------------------------------------------------------------
# * Turn 180° (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def turn_180
case @direction
when 1
turn_upright
when 2
turn_up
when 3
turn_upleft
when 4
turn_right
when 6
turn_left
when 7
turn_downright
when 8
turn_down
when 9
turn_downleft
end
end
#--------------------------------------------------------------------------
# * Turn at Random (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def turn_random
if DIR_8_POSES
caserand = 8
else
caserand = 4
end
case rand(caserand)
when 0 # Move down
turn_down
when 1 # Move left
turn_left
when 2 # Move right
turn_right
when 3 # Move up
turn_up
when 4 # Move Upper Left
turn_downleft
when 5 # Move Upper Right
turn_downright
when 6 # Move Lower Left
turn_upleft
when 7 # Move Lower Right
turn_upright
end
end
#--------------------------------------------------------------------------
# * Turn Towards Player
#--------------------------------------------------------------------------
def turn_toward_player
# Get difference in player coordinates
sx = @x - $game_player.x
sy = @y - $game_player.y
if DIR_8_POSES
# turn towards player, prioritizes diagonal before straight
if sx > 0
if sy > 0
turn_upleft
elsif sy <0
turn_downleft
else
turn_left
end
elsif sx <0
if sy > 0
turn_upright
elsif sy <0
turn_downright
else
turn_right
end
else
if sy > 0
turn_up
elsif sy <0
turn_down
else
# nada (Completely Equal)
end
end
else
# If coordinates are equal
if sx == 0 and sy == 0
return
end
# If horizontal distance is longer
if sx.abs > sy.abs
# Turn to the right or left towards player
sx > 0 ? turn_left : turn_right
# If vertical distance is longer
else
# Turn up or down towards player
sy > 0 ? turn_up : turn_down
end
end
end
#--------------------------------------------------------------------------
# * Turn away from Player (Rewritten for diagonal animation)
#--------------------------------------------------------------------------
def turn_away_from_player
# Get difference in player coordinates
sx = @x - $game_player.x
sy = @y - $game_player.y
if DIR_8_POSES
# Move away from player, prioritizes diagonal before straight
if sx > 0
if sy > 0
turn_downright
elsif sy <0
turn_upright
else
turn_right
end
elsif sx <0
if sy > 0
turn_downleft
elsif sy <0
turn_upleft
else
turn_left
end
else
if sy > 0
turn_down
elsif sy <0
turn_up
else
# nada (Completely Equal)
end
end
else
# If coordinates are equal
if sx == 0 and sy == 0
return
end
# If horizontal distance is longer
if sx.abs > sy.abs
# Turn to the right or left away from player
sx > 0 ? turn_right : turn_left
# If vertical distance is longer
else
# Turn up or down away from player
sy > 0 ? turn_down : turn_up
end
end
end
end
#==============================================================================
# ** Game_Player
#------------------------------------------------------------------------------
# This class handles the player. Its functions include event starting
# determinants and map scrolling. Refer to "$game_player" for the one
# instance of this class.
#==============================================================================
class Game_Player < Game_Character
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# Remember whether or not moving in local variables
last_moving = moving?
# If moving, event running, move route forcing, and message window
# display are all not occurring
unless moving? or $game_system.map_interpreter.running? or
@move_route_forcing or $game_temp.message_window_showing
# Move player in the direction the directional button is being pressed
# Rewritten for diagonal animation
if DIR_8_CONTROL
case Input.dir8
when 2
move_down
when 4
move_left
when 6
move_right
when 8
move_up
when 7
move_upper_left
when 9
move_upper_right
when 3
move_lower_right
when 1
move_lower_left
end
else
case Input.dir4
when 2
move_down
when 4
move_left
when 6
move_right
when 8
move_up
end
end
end
# Remember coordinates in local variables
last_real_x = @real_x
last_real_y = @real_y
super
# If character moves down and is positioned lower than the center
# of the screen
if @real_y > last_real_y and @real_y - $game_map.display_y > CENTER_Y
# Scroll map down
$game_map.scroll_down(@real_y - last_real_y)
end
# If character moves left and is positioned more let on-screen than
# center
if @real_x < last_real_x and @real_x - $game_map.display_x < CENTER_X
# Scroll map left
$game_map.scroll_left(last_real_x - @real_x)
end
# If character moves right and is positioned more right on-screen than
# center
if @real_x > last_real_x and @real_x - $game_map.display_x > CENTER_X
# Scroll map right
$game_map.scroll_right(@real_x - last_real_x)
end
# If character moves up and is positioned higher than the center
# of the screen
if @real_y < last_real_y and @real_y - $game_map.display_y < CENTER_Y
# Scroll map up
$game_map.scroll_up(last_real_y - @real_y)
end
# If not moving
unless moving?
# If player was moving last time
if last_moving
# Event determinant is via touch of same position event
result = check_event_trigger_here([1,2])
# If event which started does not exist
if result == false
# Disregard if debug mode is ON and ctrl key was pressed
unless $DEBUG and Input.press?(Input::CTRL)
# Encounter countdown
if @encounter_count > 0
@encounter_count -= 1
end
end
end
end
# If C button was pressed
if Input.trigger?(Input::C)
# Same position and front event determinant
check_event_trigger_here([0])
check_event_trigger_there([0,1,2])
end
end
end
end
#==============================================================================
# ** Sprite_Character
#------------------------------------------------------------------------------
# This sprite is used to display the character.It observes the Game_Character
# class and automatically changes sprite conditions.
#==============================================================================
class Sprite_Character < RPG::Sprite
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
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)
if DIR_8_STAND
@cw = bitmap.width / (DIR_8_FRAMES + 1) # Movement frames w/ stand
else
@cw = bitmap.width / (DIR_8_FRAMES) # Movement frames regular
end
if DIR_8_CHAR
@ch = bitmap.height / 8 # This sets for 8 directions
else
@ch = bitmap.height / 4 # This sets for 4 directions
end
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 horizontal transfer (animation frames)
if not @character.step_anime and @character.stop_count > 0
sx = (@character.pattern) * @cw
else
# If event's Movement flag is checked (or player sprite)
if @character.walk_anime
if not DIR_8_CHAR and not DIR_8_STAND
sx = (@character.pattern) * @cw
else
sx = (@character.pattern + 1) * @cw
end
# If event's Movement flag unchecked
else
sx = (@character.pattern) * @cw
end
end
# Set vertical transfer (direction)
if DIR_8_CHAR
dir = @character.direction # These routines allow for eight
dec = (dir == 7 or dir== 9) ? 3 : 1 # directional movement.
sy = (dir - dec) * @ch
else
sy = (@character.direction - 2) / 2 * @ch
end
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