#==============================================================================
# HEIRUKICHI MOVE ROUTE
#==============================================================================
# Version 2.1.1
# - Author: Heirukichi
# - Last update: 03-20-2019 [MM-DD-YYYY]
#==============================================================================
# TERMS OF USE
#------------------------------------------------------------------------------
# This script is licensed under the GNU General Public License 3.0. This means
# that you can:
# - use this script for both commercial and non commercial projects as long as
# * proper credit is given to me (Heirukichi);
# * a link to my website is provided;
# - modify this script as much as you want as long as
# * you do not pretend you wrote the whole script;
# * you still give credit to me for the original work;
# * you provide a link to my website instead of reposting my script when you
# post the modified version of the script.
#
# You can review the complete license here:
# https://www.gnu.org/licenses/gpl-3.0.html
#
# If you are using this script for a commercial game, I would like to receive a
# link of your game page. The link does not need to contain a free copy of your
# game and it is only used to keep track of games where my scripts are being
# used.
# While this is not mandatory for non commercial games, I really appreciate if
# you could send me a link regardless of your game being commercial or not.
# You can contact me using the Contacts form on my website or by sending me a
# private message on RPG Maker Web forum.
#
# IMPORTANT NOTICE:
# If you want to distribute this code, feel free to do it, but provide a link
# to my website instead of pasting my script somewhere else.
#==============================================================================
# DESCRIPTION
#------------------------------------------------------------------------------
# With this script is possible to set up move routes for characters in a fast
# and easy way. You can draw your own paths using Regions instead of using the
# move route command and then use a script call to tell the engine which
# character to move and which region is being used to draw your path.
#==============================================================================
# INSTRUCTIONS:
#------------------------------------------------------------------------------
# To use this script you have to draw your path using any region (in the
# example below I used region 63) and then use a script call to type this:
#
# path(region, character, event *OPTIONAL*)
#
# region is the region use to draw your path
# character is the id of the character you want to move (0 for player)
# event is either TRUE or FALSE. When it is true it tells the engine that your
# id refers to events, when it is false it tells the engine that your id refers
# to the player. If you leave this blank it will refer to player.
#
# IMPORTANT NOTE: using this script is also possible to draw move routes for
# player followers! When event is FALSE or omitted, the script automatically
# refers to the player. If character is 1 or more instead of 0 you can access
# to player followers.
#
# So it is like this:
# 0 = 1st party member
# 1 = 1st follower (2nd party member)
# 2 = 2nd follower (3rd party member) and so on.
#
# Example #1: path(63, 3, true)
# Example #2: path(63, 0)
# Example #3: path(63, 0, false)
#
# The code in Example 1 will move the event with ID = 3 following the path with
# region ID = 63.
# The code in Example 2 will move the player following the path with region
# ID = 63. Example 3 is the same.
#
#------------------------------------------------------------------------------
# WARNING: MOVING FOLLOWERS WITH PARALLEL PROCESS RESULTS IN A WEIRD EFFECT
# ONCE THEY GO BACK TO THEIR ORIGINAL POSITION IN THE SNAKE-LIKE TAIL!
#------------------------------------------------------------------------------
# WHAT'S NEW:
# * This version is 100% compatible with the previous one. If you used HMR.path
# instead of just path to move characters in your game you don't have to edit
# anything. The script just overwrites the old HMR.path with the new one.
# * It is now possible to speed up player movement even when the player is
# being moved by another event. This applies to followers as well.
# * The character that is being moved now turns briefly toward a blocked path
# to show where it is supposed to go. This can be useful for both players (it
# is a hint to tell them to move) and developers (so knowing where to look if
# they want to fix something is much easier).
# * The script now works for maps that loop in either direction.
#------------------------------------------------------------------------------
# BUG FIXES:
# * Fixed a bug causing the game to enter an endless loop when the character
# path was blocked.
# * Fixed a bug causing characters moved using this script to briefly stop
# after each step.
#==============================================================================
$imported = {} if $imported.nil?
$imported["Heirukichi_MoveRoute"] = true
#==============================================================================
# ** HMR module
#==============================================================================
module HMR
#----------------------------------------------------------------------------
# Current version. Used when an important update comes out to check if the
# version you are using is valid.
#----------------------------------------------------------------------------
CURRENT_VERSION = "2.1.1"
#----------------------------------------------------------------------------
# * Initialize Heirukichi-MoveRoute
#----------------------------------------------------------------------------
def self.start_moving(id, character)
@path_id = id
@actual_x = character.x
@actual_y = character.y
@character = character
@moving = true
@old_x = nil
@old_y = nil
@character.set_path(@path_id)
end # Start Moving
#----------------------------------------------------------------------------
# * Passable?
#----------------------------------------------------------------------------
def self.passable?(d = nil)
x = @character.x
y = @character.y
if (d == nil)
d = @character.direction
end
@character.passable?(x, y, d)
end # Passable?
#----------------------------------------------------------------------------
# * Moving?
#----------------------------------------------------------------------------
def self.moving?
@moving
end # Moving?
#----------------------------------------------------------------------------
# * Stop movement
#----------------------------------------------------------------------------
def self.stop_moving
@moving = false
@character.set_path(0)
end
#----------------------------------------------------------------------------
# * Move Character
#----------------------------------------------------------------------------
def self.move
d = get_direction
@character.move_straight(d) unless (d == nil)
save_movement
end # Move Character
#----------------------------------------------------------------------------
# * Get Character Direction
#----------------------------------------------------------------------------
def self.get_direction
direction = nil
x = @character.x
y = @character.y
step = false
[2, 4, 6, 8].each do |d|
x2 = $game_map.round_x_with_direction(x, d)
y2 = $game_map.round_y_with_direction(y, d)
next if ((x2 == @old_x) && (y2 == @old_y))
if $game_map.region_id(x2, y2) == @path_id
step = passable?(d)
if step
direction = d
break
end
end
end
stop_moving unless step
return direction
end # Get Character Direction
#----------------------------------------------------------------------------
# * Store Old Coordinates
#----------------------------------------------------------------------------
def self.save_movement
unless ((@actual_x == @character.x) && (@actual_y == @character.y))
@old_x = @actual_x
@old_y = @actual_y
@actual_x = @character.x
@actual_y = @character.y
else
stop_moving
end
end # Store Old Coordinates
#----------------------------------------------------------------------------
# This part adds compatibility with the old Heirukichi-MoveRoute version
#----------------------------------------------------------------------------
def self.path(id, c, event = false)
if event
target = $game_map.events[c]
else
target = ((c == 0) ? $game_player : $game_player.followers[(c - 1)])
end
start_moving(id, target)
while moving?
move
Fiber.yield while target.moving?
end
end # Compatibility with previous version
end # end of HMR module
#==============================================================================
# HMR module (part 2)
#------------------------------------------------------------------------------
# The following part allows the user to call path using variable arguments.
#==============================================================================
module HMR
class << HMR
#--------------------------------------------------------------------------
# * Aliased Method: path
#--------------------------------------------------------------------------
alias hmr_path_old path
def path(*args)
if (args.size == 2)
hmr_path_old(args[0], args[1])
elsif (args.size == 3)
if args[2].is_a?(Integer)
hmr_path_old(args[0], args[1])
if [2, 4, 6, 8].include?(args[2])
if (args[1] == 0)
character = $game_player
elsif [1, 2, 3].include?(args[1])
character = $game_player.followers[args[1] - 1]
end
character.set_direction(args[2])
end
elsif (!args[2] || args[2])
hmr_path_old(args[0], args[1], args[2])
end
elsif (args.size == 4)
hmr_path_old(args[0], args[1], args[2])
return unless [2, 4, 6, 8].include?(args[3])
if args[2]
$game_map.events[args[1]].set_direction(args[3])
else
if (args[1] == 0)
character = $game_player
elsif ([1, 2, 3].include?(args[1]))
character = $game_player.followers[args[1] - 1]
end
character.set_direction(args[3])
end
end
end # Path aliased version
end # end of HMR class
end # end of HMR module
#==============================================================================
# ** Game_CharacterBase class
#==============================================================================
class Game_CharacterBase
#----------------------------------------------------------------------------
# * Aliased method: init_private_members
#----------------------------------------------------------------------------
alias hrk_mr_initialize_private_old init_private_members
def init_private_members
hrk_mr_initialize_private_old
@current_path = 0
end # init_private_members
#----------------------------------------------------------------------------
# * Using Path?
#----------------------------------------------------------------------------
def using_path?
@current_path > 0
end # Using Path?
#----------------------------------------------------------------------------
# * Set Path
#----------------------------------------------------------------------------
def set_path(id)
@current_path = id
end # Set Path
end # end of Game_CharacterBase class
#==============================================================================
# ** Game_Follower class
#==============================================================================
class Game_Follower < Game_Character
#----------------------------------------------------------------------------
# * Preceeding Character
#----------------------------------------------------------------------------
def preceding_character
return @preceding_character if (@preceding_character == $game_player)
if @preceding_character.using_path?
@preceding_character.preceding_character
else
@preceding_character
end
end # Preceeding Character
#----------------------------------------------------------------------------
# * Aliased method: chase_preceding_character
#----------------------------------------------------------------------------
alias hrk_mr_chase_preceding_character_old chase_preceding_character
def chase_preceding_character
if $imported["Heirukichi_MoveRoute"]
unless moving?
return if gather?
sx = distance_x_from(preceding_character.x)
sy = distance_y_from(preceding_character.y)
if sx != 0 && sy != 0
move_diagonal(sx > 0 ? 4 : 6, sy > 0 ? 8 : 2)
elsif sx != 0
move_straight(sx > 0 ? 4 : 6)
elsif sy != 0
move_straight(sy > 0 ? 8 : 2)
end
end
else
hrk_mr_chase_preceding_character_old
end
end # aliased chase_preceding_character
end # end of Game_Follower class
#==============================================================================
# ** Game_Interpreter
#==============================================================================
class Game_Interpreter
#----------------------------------------------------------------------------
# * Path
#----------------------------------------------------------------------------
def path(*args)
case args.size
when 4
HMR.path(args[0], args[1], args[2], args[3])
when 3
HMR.path(args[0], args[1], args[2])
when 2
HMR.path(args[0], args[1])
end
end # Path
end # end of Game_Interpreter