Heretic's Move Straight
Authors: Heretic
Version: 1.0
Type: Custom Movement System
Key Term: Custom Movement System
IntroductionThis script allows you to move your Characters in a Straight Line from Point A to Point B.
You might think it is useless, but try moving a Character up two spaces and right five spaces. You'll see the
movement comes out a bit strange without this script. When you use this command, it moves your character in a
straight line directly to your target, regardless if the target can not be reached by moving one of the 8 default directions.
THIS IS NOT A PATHFINDING SCRIPT.
THIS IS NOT A PIXEL MOVEMENT SCRIPT.
Features
- Just one command to use: move_straight(x, y, [optional duration])
- Optional Duration for precise movement timings
- One time, at band camp...
ScreenshotsNo Screenshots
DemoNo Demo. I might build one upon request.
Script
#===============================================================================
#
# HERETIC'S MOVE STRAIGHT
# Version 1.0
# Wednesday, April 3rd, 2013
#
#===============================================================================
#
# Author: Heretic
# Date: Wednesday, April 3rd, 2013
# Version 1.0
#
# This script allows a character to move to a location in a straight line.
#
# This is NOT a Pathfinding Script
#
# This is NOT a Pixel Movement Script
#
# This is NOT a Projectile Script
#
# Straight Lines are easy if you are moving one of the 8 predefined directions.
# Move Left, Move Left, sure, that moves straight, but what if the spot you
# wanted to move to isnt in one of the 8 Default Directions including Diagonals?
#
# What if you wanted your character to move at a 22.5 degree angle? That is
# what this script allows you to do, without all the angles.
#
# Really, it is just a duplication of Jump, and works similarly.
#
# move_straight(x, y, [duration optional])
#
# Script Calls here go into Move Route -> Scripts
#
# X and Y coordinates how far to move. Thus, they are RELATIVE to the current
# position of your Character and are NOT Absolute. That is to say (1, 1) will
# move your Character one space down and one space right. It is NOT saying to
# move to a Map Coordinate of 1, 1.
#
# Positive Values are Down and Right
# Negative Values are Up and Left
#
# --- Usage Commands (Enter these in a Move Route Script) ---
#
# move_straight(1, 3) - this will cause the NPC to move Down and Right
# move_straight(-1, 3) - this will cause the NPC to move Down and Left
# move_straight(-1, -3) - this will cause the NPC to move Up and Left
#
# --- Usage Command with Optional Duration ---
#
# move_straight(1, -3, 62) - this will cause the NPC to move Up and Right and
# take exactly 62 frames to get there.
#
# The optional Duration can be used to Syncrhonize Animations, say if you
# wanted a character to take exactly 23 frames to get from its current location
# to the new location. Otherwise it is just based on the current Move Speed.
#
# Passability: Just like jump, passability is NOT checked between points A
# and B. Passability IS checked for the spot being moved to, and only if
# the NPC being moved does not have Through enabled.
#
# Move and Step Animations are both enabled for this. So if you do not want
# your character to walk to a location, disable Move and Stop Animations in
# your Move Route.
#
# Character Turning is enabled for this. If your Character needs to turn to
# get to a location, it will. If this causes you trouble, then just turn on
# Direction Fix. Don't forget to turn it back off if you want that Character
# to turn later.
#
# Move Speed of 0 will cause your character to snap to the location on the
# next frame. This was done to prevent a divsion by zero error.
#
# Practical uses: I needed to write this in order to simulate a projectile, so
# I figure you might need it for the exact same thing.
#
# Examples: Magic Missle, Shooting an Arrow, a Football, etc...
#
#
#
#
# --- Installation and Compatability ----
#
#
# Place BELOW any scripts that affect Movement. It can go above everything
# else.
#
# This script fully redefines Game_Character update. The rest of the commands
# are aliased and should not cause you any difficulty. The changes made in
# Game_Character update are very minimal, so merges with other scripts should
# be relatively easy, that is, if it was update that is giving you a problem.
#
#
#
# # Branch with jumping, moving, and stopping
# if jumping?
#
# ... was changed to ...
#
# # Branch with moving_straight, jumping, moving, and stopping
# if moving_straight?
# update_move_straight
# elsif jumping?
#
# If another script fully redefines Game_Character update, it may be easier to
# make the changes listed above in the other script to allow for that script
# to be compatible with this one. This isn't common, except for extensive
# scripts.
#
# The SDK also fully redefines Game_Character update, hence why this script
# needs to go below it. I've encountered more issues with the SDK than
# anything else, so hopefully it doesnt give you any sort of issue there.
#
# screen_y has been aliased, but redefinitions of that are extremely uncommon.
#
# move_type_custom has also been aliased. If you have another script that might
# fully redefine move_type_custom that is below this script, you may need to
# cut the move_type_custom from here, and place it as its own script BELOW
# the redefined move_type_custom. Probably easier than merging them.
#
#
#
# --- Legal ---
#
# You may use, alter, and distribute this script as long as you give
# me credit. This script may need to be edited, hence why you are allowed to
# make changes, then redistribute it. You may take credit where credit is due.
#
# If you make any changes to this script, you may claim any part of the code
# that you have changed as your own.
#
# This script may be freely used in commercial projects without any form of
# compensation to me, or other authors of modifications to this script for
# the use of this script.
#
# You may NOT sell this script, or any alterations thereof.
#
# You may NOT alter the existing Legal section, but may add to it in order to
# provide yourself credit for any work you have done. I am willing to
# negotiate with you on any other alterations or usage of this script.
#==============================================================================
# ** Game_Character (part 1)
#------------------------------------------------------------------------------
# This class deals with characters. It's used as a superclass for the
# Game_Player and Game_Event classes.
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
alias move_straight_initialize initialize
def initialize
# Call Original
move_straight_initialize
# New Properties
@straight_count = 0
end
#--------------------------------------------------------------------------
# * Determine if Moving Straight
#--------------------------------------------------------------------------
def moving_straight?
# A move straight is occurring if straight count is larger than 0
return @straight_count > 0
end
#--------------------------------------------------------------------------
# * Move Straight
# x_move : x-coordinate plus value
# y_move : y-coordinate plus value
#--------------------------------------------------------------------------
def move_straight(x_move, y_move, duration = nil)
# If plus value is not (0,0)
if x_move != 0 or y_move != 0
# If horizontal distnace is longer
if x_move.abs > y_move.abs
# Change direction to left or right
x_move < 0 ? turn_left : turn_right
# If vertical distance is longer, or equal
else
# Change direction to up or down
y_move < 0 ? turn_up : turn_down
end
end
# Calculate new coordinates
new_x = @x + x_move
new_y = @y + y_move
# If plus value is (0,0) or straight destination is passable
if (x_move == 0 and y_move == 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_move * x_move + y_move * y_move).round
# If Moving Duration is specified (use for Syncing Movements)
if duration
# Time it takes to Move * 2 for Engine
@straight_count = duration * 2
else
# Calculate how many Frames it will take to move to new location
duration = (@move_speed > 0) ? distance * 32 / @move_speed : 0.5
# Note: duration set to 0.5 allows duration to be ONE Frame in order
# to allow the necessary update to occur once
end
# Assign Duration
@straight_count = duration * 2
# Clear stop count
@stop_count = 0
end
end
#--------------------------------------------------------------------------
# * Get Screen Y-Coordinates
#--------------------------------------------------------------------------
alias move_straight_screen_y screen_y
def screen_y
# Get screen coordinates from real coordinates and map display position
y = (@real_y - $game_map.display_y + 3) / 4 + 32
# If Moving Straight
if @straight_count > 0
# Just return the normal Y value
return y
end
# Call Original
move_straight_screen_y
end
#--------------------------------------------------------------------------
# * Frame Update (move straight)
#--------------------------------------------------------------------------
def update_move_straight
# Reduce straight count by 1
@straight_count -= 1
# If move animation is ON
if @walk_anime
# Increase animation count by 1.5
@anime_count += 1.5
# If move animation is OFF, and stop animation is ON
elsif @step_anime
# Increase animation count by 1
@anime_count += 1
end
# Calculate new coordinates
@real_x = (@real_x * @straight_count + @x * 128) / (@straight_count + 1)
@real_y = (@real_y * @straight_count + @y * 128) / (@straight_count + 1)
end
#--------------------------------------------------------------------------
# * Frame Update - FULL REDEFINITION - MAY CAUSE COMPATABILITY ISSUES
#
# This entire script should be BELOW the SDK and Below Movement Scripts.
# It should be able to go above anything else that isnt Movement Related.
#
# --- Compatability ----
# If this part of the script is giving you any sort of issues, the only
# thing that was changed here was that if jumping? was changed to
# if moving_straight? ... elsif jumping? so just changing that in any
# other def updates for Game_Character should make that other redefinition
# compatible.
#
#--------------------------------------------------------------------------
def update
# Branch with moving_straight, jumping, moving, and stopping
if moving_straight?
update_move_straight
elsif 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) % 4
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 Type : Custom
#
# This part of the script will check for any move_straight commands before
# executing other movement commands. It is necessary because without this,
# using "Wait for Move's Completion" is not possible, and NPCs will try to
# execute their next Move Command prematurely.
#
# This bit of code seems to get redefined semi-frequently. If you have any
# other scripts that fully redefine (not alias) move_type_custom and
# are placed below this script, this section wont work. You may have some
# luck by moving this part of the script BELOW that script that redefines
# move_type_custom.
#
#--------------------------------------------------------------------------
alias move_straight_move_type_custom move_type_custom
def move_type_custom
# Interrupt if not stopping
# @move_route.nil? is a Bugfix for Zer0's Pathfind
return if jumping? || moving? || moving_straight? || @move_route.nil?
# Loop until finally arriving at move command list
if @move_route_index < @move_route.list.size
# Get the move command at index
command = @move_route.list[@move_route_index]
# If command code is a Script
if command.code == 45 # Script
if command.parameters[0].gsub(/move_straight/){}
# Run Move Straight command so we can wait for it
eval(command.parameters[0])
# If movement failure occurs when [Ignore if can't move] option is OFF
if not @move_route.skippable and not moving_straight?
return
end
# Advance Index if Can't Move and Ignore
@move_route_index += 1
end
end
end
# Call Original, or Modified Original
move_straight_move_type_custom
end
end
InstructionsPlace below any other movement related scripts. Some fine tuning may be required, and I can help with that.
CompatibilityCompatible with pretty much everything. If it isn't, this script isn't too difficult to modify so I can work with you to make it 100% compatible with your script.
Credits and Thanks
- KK20 for a precise explanation why a particular glitch occured.
Author's NotesIt works just like Jump, except it moves in a straight line. Speed is based on the current move speed of the Character. The optional duration can be very useful for perfect synchronization of animations. You'll probably find that it is rather useful for simulating projectiles, although it is not a Projectile script in and of itself.
Think: Magic Missle (http://www.youtube.com/watch?v=dVQsQ1LZ0Gg)
Legal: See Script
/Love
I needed this a few times in the past for cutscenes. I'm sure I'll need it some time soon...
Nice work. I'm glad to see that you got it done. xD
Thanks!
I was hoping to give someone else a chance and a goal to script something. But the more I thought about it, the more I came up with ways to "improve" it, and decided I had to do it myself.
So although it is pretty simple, I tried to put it together in a way that it would become a very useful Animation Tool instead of something that is fairly well useless. Hence the extra option to specify a duration in frames as opposed to just being speed dependant, which, when I thought about it, I most likely would have had to build that in anyway.
Hey is there anyway you can make this for VXA? I use it for cutscenes because in isometric maps i need the characters to walk at a different angle than normal
I havent tried it on ace (dont own it) but it should work. Might need to change the name of the classes or methods tho. There isnt really that much to it, as 90% of the script is comments explaining stuff. Havent had time recently, being nice and warm outside and Im sick of being stuck inside due to crappy weather! Maybe this weekend I can take a crack at it...
Cross engined XP & VXA
- Rename move_straight to move_straight_line (conflict with VXA method)
- Changed from overwriting Game_Character#update -> Aliasing Game_Character#update, #update_jump, #update_move, and #update_stop.
#===============================================================================
#
# HERETIC'S MOVE STRAIGHT
# Version 1.1
# Wednesday, April 3rd, 2013
#
#===============================================================================
#
# Author: Heretic
# Date: Wednesday, April 3rd, 2013
# Version 1.0
#
# This script allows a character to move to a location in a straight line.
#
# This is NOT a Pathfinding Script
#
# This is NOT a Pixel Movement Script
#
# This is NOT a Projectile Script
#
# Straight Lines are easy if you are moving one of the 8 predefined directions.
# Move Left, Move Left, sure, that moves straight, but what if the spot you
# wanted to move to isnt in one of the 8 Default Directions including Diagonals?
#
# What if you wanted your character to move at a 22.5 degree angle? That is
# what this script allows you to do, without all the angles.
#
# Really, it is just a duplication of Jump, and works similarly.
#
# move_straight_line(x, y, [duration optional])
#
# Script Calls here go into Move Route -> Scripts
#
# X and Y coordinates how far to move. Thus, they are RELATIVE to the current
# position of your Character and are NOT Absolute. That is to say (1, 1) will
# move your Character one space down and one space right. It is NOT saying to
# move to a Map Coordinate of 1, 1.
#
# Positive Values are Down and Right
# Negative Values are Up and Left
#
# --- Usage Commands (Enter these in a Move Route Script) ---
#
# move_straight_line(1, 3) - this will cause the NPC to move Down and Right
# move_straight_line(-1, 3) - this will cause the NPC to move Down and Left
# move_straight_line(-1, -3) - this will cause the NPC to move Up and Left
#
# --- Usage Command with Optional Duration ---
#
# move_straight_line(1, -3, 62) - this will cause the NPC to move Up and Right and
# take exactly 62 frames to get there.
#
# The optional Duration can be used to Syncrhonize Animations, say if you
# wanted a character to take exactly 23 frames to get from its current location
# to the new location. Otherwise it is just based on the current Move Speed.
#
# Passability: Just like jump, passability is NOT checked between points A
# and B. Passability IS checked for the spot being moved to, and only if
# the NPC being moved does not have Through enabled.
#
# Move and Step Animations are both enabled for this. So if you do not want
# your character to walk to a location, disable Move and Stop Animations in
# your Move Route.
#
# Character Turning is enabled for this. If your Character needs to turn to
# get to a location, it will. If this causes you trouble, then just turn on
# Direction Fix. Don't forget to turn it back off if you want that Character
# to turn later.
#
# Move Speed of 0 will cause your character to snap to the location on the
# next frame. This was done to prevent a divsion by zero error.
#
# Practical uses: I needed to write this in order to simulate a projectile, so
# I figure you might need it for the exact same thing.
#
# Examples: Magic Missle, Shooting an Arrow, a Football, etc...
#
#
#
#
# --- Installation and Compatability ----
#
#
# Place BELOW any scripts that affect Movement. It can go above everything
# else.
#
# The SDK also fully redefines Game_Character update, hence why this script
# needs to go below it. I've encountered more issues with the SDK than
# anything else, so hopefully it doesnt give you any sort of issue there.
#
# screen_y has been aliased, but redefinitions of that are extremely uncommon.
#
# update_jump, update_move, and update_stop has also been aliased.
# This alias is to prevent those methods from working when characters
# in the middle of moving straight.
#
# move_type_custom has also been aliased. If you have another script that might
# fully redefine move_type_custom that is below this script, you may need to
# cut the move_type_custom from here, and place it as its own script BELOW
# the redefined move_type_custom. Probably easier than merging them.
#
#
#
# --- Legal ---
#
# You may use, alter, and distribute this script as long as you give
# me credit. This script may need to be edited, hence why you are allowed to
# make changes, then redistribute it. You may take credit where credit is due.
#
# If you make any changes to this script, you may claim any part of the code
# that you have changed as your own.
#
# This script may be freely used in commercial projects without any form of
# compensation to me, or other authors of modifications to this script for
# the use of this script.
#
# You may NOT sell this script, or any alterations thereof.
#
# You may NOT alter the existing Legal section, but may add to it in order to
# provide yourself credit for any work you have done. I am willing to
# negotiate with you on any other alterations or usage of this script.
#==============================================================================
# ** Game_Character (part 1)
#------------------------------------------------------------------------------
# This class deals with characters. It's used as a superclass for the
# Game_Player and Game_Event classes.
#==============================================================================
class Game_Character
#--------------------------------------------------------------------------
# * Constant
#--------------------------------------------------------------------------
VXA = defined?(Window_BattleActor)
#--------------------------------------------------------------------------
# * Class Variable
#--------------------------------------------------------------------------
@@move_screen_y_straight = VXA ? :jump_height : :screen_y
@@move_type_custom_straight = VXA ? :update_routine_move : :move_type_custom
#--------------------------------------------------------------------------
# * Determine if Moving Straight
#--------------------------------------------------------------------------
def moving_straight?
# A move straight is occurring if straight count is larger than 0
return (@straight_count ||= 0) > 0
end
#--------------------------------------------------------------------------
# * Move Straight
# x_move : x-coordinate plus value
# y_move : y-coordinate plus value
#--------------------------------------------------------------------------
def move_straight_line(x_move, y_move, duration = nil)
# If plus value is not (0,0)
if x_move != 0 or y_move != 0
# If horizontal distnace is longer
if x_move.abs > y_move.abs
# Change direction to left or right
if respond_to?(:set_direction)
set_direction(x_move < 0 ? 4 : 6)
else
x_move < 0 ? turn_left : turn_right
end
# If vertical distance is longer, or equal
else
# Change direction to up or down
if respond_to?(:set_direction)
set_direction(y_move < 0 ? 8 : 2)
else
y_move < 0 ? turn_up : turn_down
end
end
end
# Calculate new coordinates
new_x = @x + x_move
new_y = @y + y_move
# If plus value is (0,0) or straight destination is passable
if (zero = (x_move == 0 and y_move == 0)) or passable?(new_x, new_y, 0)
# Straighten position
straighten
# Update coordinates
@x = new_x
@y = new_y
# Calculate distance
distance = zero ? 0 : Math.sqrt(x_move * x_move + y_move * y_move).round
# If Moving Duration is specified (use for Syncing Movements)
if duration
# Time it takes to Move * 2 for Engine
@straight_count = duration * 2
else
# Calculate how many Frames it will take to move to new location
speed = respond_to?(:real_move_speed) ? real_move_speed : @move_speed
duration = (speed > 0) ? distance * 32 / speed : 0.5
# Note: duration set to 0.5 allows duration to be ONE Frame in order
# to allow the necessary update to occur once
end
# Clear stop count
@stop_count = (@straight_count = duration * 2) * 0
end
end
#--------------------------------------------------------------------------
# * Get Screen Y-Coordinates
#--------------------------------------------------------------------------
$@ || alias_method(:move_straight_screen_y, @@move_screen_y_straight)
define_method(@@move_screen_y_straight) do
# Get screen coordinates from real coordinates and map display position
y = (@real_y - $game_map.display_y + 3) / 4 + 32
# Just return the normal Y value if Moving Straight
return VXA ? 0 : y if moving_straight?
# Call Original
move_straight_screen_y
end
#--------------------------------------------------------------------------
# * Frame Update (move straight)
#--------------------------------------------------------------------------
def update_move_straight
# Reduce straight count by 1
@straight_count -= 1
# VXA already have another animation update method
unless VXA
# If move animation is ON
if @walk_anime
# Increase animation count by 1.5
@anime_count += 1.5
# If move animation is OFF, and stop animation is ON
elsif @step_anime
# Increase animation count by 1
@anime_count += 1
end
end
# Calculate new coordinates
real_x = @real_x * @straight_count + @x * (VXA ? 1 : 128)
real_y = @real_y * @straight_count + @y * (VXA ? 1 : 128)
@real_x = real_x / (@straight_count + 1.0)
@real_y = real_y / (@straight_count + 1.0)
if @straight_count == 0
@real_x = VXA ? (@x = $game_map.round_x(@x)) : @real_x.round
@real_y = VXA ? (@y = $game_map.round_y(@y)) : @real_y.round
end
end
#--------------------------------------------------------------------------
# * Frame Update -
#
# This entire script should be BELOW the SDK and Below Everything that
# aliases update_jump, update_move, and update_stop.
# It should be able to go above anything else that isnt Movement Related.
#
#--------------------------------------------------------------------------
$@ || alias_method(:move_straight_update,:update)
def update
update_move_straight if moving_straight?
move_straight_update
end
#--------------------------------------------------------------------------
# * Frame Update (jump)
#--------------------------------------------------------------------------
$@ || alias_method(:move_straight_update_jump,:update_jump)
def update_jump
move_straight_update_jump unless moving_straight?
end
#--------------------------------------------------------------------------
# * Frame Update (move)
#--------------------------------------------------------------------------
$@ || alias_method(:move_straight_update_move,:update_move)
def update_move
move_straight_update_move unless moving_straight?
end
#--------------------------------------------------------------------------
# * Frame Update (stop)
#--------------------------------------------------------------------------
$@ || alias_method(:move_straight_update_stop,:update_stop)
def update_stop
move_straight_update_stop unless moving_straight?
end
#--------------------------------------------------------------------------
# * Move Type : Custom
#
# This part of the script will check for any move_straight commands before
# executing other movement commands. It is necessary because without this,
# using "Wait for Move's Completion" is not possible, and NPCs will try to
# execute their next Move Command prematurely.
#
# This bit of code seems to get redefined semi-frequently. If you have any
# other scripts that fully redefine (not alias) move_type_custom and
# are placed below this script, this section wont work. You may have some
# luck by moving this part of the script BELOW that script that redefines
# move_type_custom.
#
#--------------------------------------------------------------------------
$@ || alias_method(:move_straight_mt_custom, @@move_type_custom_straight)
define_method(@@move_type_custom_straight) do
# Interrupt if not stopping
# @move_route.nil? is a Bugfix for Zer0's Pathfind
return if jumping? || moving? || moving_straight? || @move_route.nil?
# Loop until finally arriving at move command list
if @wait_count == 0 && @move_route_index < @move_route.list.size
# Get the move command at index
command = @move_route.list[@move_route_index]
# If command code is a Script
if command.code == 45 # Script
if (params = command.parameters)[0].gsub(/move_straight_line/){}
# Run Move Straight command so we can wait for it
eval(params[0])
# If movement failure occurs when [Ignore if can't move] option is OFF
if not @move_route.skippable and not moving_straight?
return
end
# Advance Index if Can't Move and Ignore
return @move_route_index += 1
end
end
end
# Call Original, or Modified Original
move_straight_mt_custom
end
end