#==============================================================================
# ** 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 = true # This enables/disables 8 directional charsets
DIR_8_CONTROL = true # This enables/disables 8 directional movement
DIR_8_POSES = true # This enables/disables 8 directional facing
DIR_8_FRAMES = 8 # This holds the number of motion frames when walking
DIR_8_STAND = true # This determines if separate frame used for standing
$dir_8_fram = {1 => 8, 2 => 4}
=begin
FULL DEFINITIONS ON EDITABLES ABOVE:
DIR_8_CHAR: This value (true/false) determines whether the sprite's charset
uses 4 directional movement (up,down,left,right), or whether it
uses 8 directional movement (the diagonals too). Turning it on
allows you to use sprites that have 8 directional movement.
--If you turn this to 'true' when using a 4 directional sprite,
you will have an on-screen image of a sprite cut in half. Or,
if you set this to 'false' when using an 8 directional sprite
in your system, then your sprite will show two images on top
of each other.--
Ex: [1] Down [1] Down/left
[2] Right [2] Down
[3] Left [3] Down/Right
[4] Up [4] Right
[5] Up/Left
[6] Left
[7] Up/Right
[8] Up
DIR_8_CONTROL: This value (true/false) determines whether the player-control-
led character can be moved diagonally, regardless of character
pose. It won't affect [event] movement controls.
--If you turn this to 'true' when using a 4 directional char-
racter sprite, you will still only have them facing 4 ways
(up, down, left, right), even if your character is moving in
diagonal directions. Likewise, if you have this value set to
'false', even 8 directional player-controlled will be forced
to move in just the 4 prime directions... even if events can
move in all 8.
DIR_8_POSES: This value (true/false) determines whether the event or sprite
(if using an 8-directional charset) uses all 8 poses available
or whether just the prime 4 poses are used. It's pretty much
a given that IF you turn DIR_8_CHAR to true, you'll turn this
value to true as well.
DIR_8_FRAMES: This value (numeric) sets how many frames of animation is per-
formed by the sprite or event in motion. By default, the RTP
sprite uses a basic 4 frames (the default). Please note that
this only determines how many frames are in the animation of
the sprite and has nothing to do with the IDLE pose.
DIR_8_STAND: This value (true/false) determines whether an additional frame
is in the charset. This frame is of the character in an IDLE
pose... standing. The idle pose is always the first frame per
direction.
--This in no way is an animated idle pose (feet tapping on the
ground as the game waits for the player to make an action).
It only shows a single frame. The inclusion of a 'dash/idle'
script that replaces the charset with an applicable charset
would do the trick. But the charset would still have to be
goverened by the same layout as all the other charactersets.
Implementing the other person's idle/dash script will be up
to you, including timing mechanics such as how long to wait
before the on-screen character begins to perform their ani-
mated idle pose.
NOTE: If you have a sprite with 6 frames of animation and an idle pose (for a
total of 7 frames per direction) you would label them as:
DIR_8_FRAMES = 6
DIR_8_STAND = true
________ ________ ________ ________ ________ ________ ________
EX: | | | | | | | |
| Idle | Move 1 | Move 2 | Move 3 | Move 4 | Move 5 | Move 6 |
| Pose | Frame | Frame | Frame | Frame | Frame | Frame |
|________|________|________|________|________|________|________|
FINAL NOTES FOR EVENTS:
1) This script affects ALL charactersets used in your game. You cannot have
8 directional and/or 8 framed characters running around the screen and not
use similarly designed charactersets in your events. Using RTP graphics
with more advanced character graphics will give you... weirdly clipped re-
sults. You've been warned! Mwuahahahahahaha..... *cough*
2) To allow [event] sprites to remain in place while triggering the the "Turn
to Player" command in the event editor (to simulate sentries), you will
want to toggle the event's 'Move Animation' checkbox OFF (So uncheck it!).
For charsets that contain an 'IDLE' pose,this'll prevent these event-drawn
characters from using the first frame of the movement animation from being
shown... a little fix I picked up on.
=end
#==============================================================================
# ** 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 += 0.5
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 += 0.5
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 -= 0.5
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 -= 0.5
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