#===============================================================================
#
# 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