by Near Fantastica & Fuso
Credit due: Fuso made the main part of this script all I did was make it work… Fuso needs as much credit or more then I do for this script…
Features:
NO MORE CUSTOM MOVEMENTS ~! This script uses path finding to return the shortest path from the START XY to the END XY then uses the custom movement to move the character… You can chain this path finds together to path link between 2 points or more...
As well an Error message will be displayed if you try to send an event to a place it can not get to…. “Target Is Unreachable for Event ID�
Syntax Event:
CODE
$AEMS.setup_event(index, repeat, skippable = false)
index = the index of the event
repeat = set the repeat flag to true and the define movement will repeat false it will not repeat..
skippable = set skippable flag to true and the event will move ever when blocked
NOTE : This is not wanted in must cases that is why its defaulted to false
CODE
$AEMS.add_command_event(index, code, parameters = [])
index = the index of the event
code = movement code
parameters = the needed parameters for that movement code
Note : the movement codes can be found in the Game_Character page 2 move_type_custom as well as there needed parameters
CODE
$AEMS.start_movement_event(index)
index = the index of the event
CODE
$AEMS.add_paths_event(index, src_x, src_y, trg_x, trg_y)
index = the index of the event
src_x = source x
src_y = source y
trg_x = target x
trg_y = target y
Syntax Player:
CODE
$AEMS.setup_player(repeat, skippable = false)
repeat = set the repeat flag to true and the define movement will repeat false it will not repeat..
skippable = set skippable flag to true and the event will move ever when blocked
NOTE : This is not wanted in must cases that is why its defaulted to false
CODE
$AEMS.add_command_player(code, parameters = [])
code = movement code
parameters = the needed parameters for that movement code
Note : the movement codes can be found in the Game_Character page 2 move_type_custom as well as there needed parameters
CODE
$AEMS.start_movement_player
CODE
$AEMS.add_paths_player(src_x, src_y, trg_x, trg_y)
src_x = source x
src_y = source y
trg_x = target x
trg_y = target y
How to use:
You need to setup a movement event before you can add a path or commands this is done with the $AEMS.setup(index, repeat) command then you can add a command or a path this is done by $AEMS.add_command(index, code, parameters = []) or $AEMS.add_paths(index, src_x, src_y, trg_x, trg_y) commands. Now you can add as many commands and paths as you want to event by adding more of these… this is called path linking… then when you are ready to start the movement use $AEMS.start_movement(index)
Now this can be done in 2 places in the events command window or in the custom movement of an event. If you do it in the movement window to start use this
return $AEMS.start_movement(index) or the code will not work right…
As well I found out something interesting if you have a repeating movement event using this movement with a defined wait the wait will repeat everytime… but if you add a normal move event wait it will only operate once… this can be a good things to add this delay so not all the events start at once yet do not repeat that wait later…
Code:
#======================================
# â–� Advanced Event Movement System
#------------------------------------------------------------------------------
#  By: Near Fantastica
# Date: 23/3/05
#
# Advanced Event Movement using Path Fiding and the Game
# Characters force_move_route method
#======================================
class AEMS
#--------------------------------------------------------------------------
def initialize
@event_route = []
@player_route = nil
end
#--------------------------------------------------------------------------
def setup_event(index, repeat, skippable = false)
@event_route[index] = RPG::MoveRoute.new
@event_route[index].repeat = repeat
@event_route[index].skippable = skippable
@event_route[index].list.clear
end
#--------------------------------------------------------------------------
def add_command_event(index, code, parameters = [])
@event_route[index].list.push RPG::MoveCommand.new(code,parameters)
end
#--------------------------------------------------------------------------
def start_movement_event(index)
@event_route[index].list.push RPG::MoveCommand.new(0)
$game_map.events[index].move_route = @event_route[index]
$game_map.events[index].move_route_index = 0
end
#--------------------------------------------------------------------------
def add_paths_event(index, src_x,src_y,trg_x,trg_y)
paths = $game_map.find_short_paths(src_x,src_y,trg_x,trg_y)
if paths == nil
print "Target Is Unreachable for Event " + index.to_s
return
end
for i in 0...paths.size
case paths[i]
when 2
@event_route[index].list.push RPG::MoveCommand.new(4)
when 4
@event_route[index].list.push RPG::MoveCommand.new(2)
when 6
@event_route[index].list.push RPG::MoveCommand.new(3)
when 8
@event_route[index].list.push RPG::MoveCommand.new(1)
end
end
end
#--------------------------------------------------------------------------
def setup_player(repeat, skippable = false)
@player_route = RPG::MoveRoute.new
@player_route.repeat = repeat
@player_route.skippable = skippable
@player_route.list.clear
end
#--------------------------------------------------------------------------
def add_command_player(code, parameters = [])
@player_route.list.push RPG::MoveCommand.new(code,parameters)
end
#--------------------------------------------------------------------------
def start_movement_player
@player_route.list.push RPG::MoveCommand.new(0)
$game_player.move_route = @player_route
$game_player.move_route_index = 0
end
#--------------------------------------------------------------------------
def add_paths_player(src_x,src_y,trg_x,trg_y)
paths = $game_map.find_short_paths(src_x,src_y,trg_x,trg_y)
if paths == nil
print "Target Is Unreachable for Player "
return
end
for i in 0...paths.size
case paths[i]
when 2
@player_route.list.push RPG::MoveCommand.new(4)
when 4
@player_route.list.push RPG::MoveCommand.new(2)
when 6
@player_route.list.push RPG::MoveCommand.new(3)
when 8
@player_route.list.push RPG::MoveCommand.new(1)
end
end
end
end
#======================================
# â–� Path Finding
#------------------------------------------------------------------------------
#  By: Fuso
#======================================
class Game_Map
#--------------------------------------------------------------------------
attr_accessor :events
#--------------------------------------------------------------------------
def initialize
@events = {}
end
#--------------------------------------------------------------------------
UP = 2
LEFT = 4
RIGHT = 6
DOWN = 8
#--------------------------------------------------------------------------
def find_short_paths(src_x,src_y,trg_x,trg_y,depth = 100, self_event = nil, option_close = false)
return [] if not (passable?(trg_x, trg_y, UP, self_event) or
passable?(trg_x, trg_y, LEFT, self_event) or
passable?(trg_x, trg_y, RIGHT, self_event) or
passable?(trg_x, trg_y, DOWN, self_event))
# Paths will hold the succeeding paths.
paths = []
# path_map will hold what paths has already been visited, to prevent that we attempt to
# walk on the same tile twice.
path_map = [src_x + src_y / 10000.0]
trackers = []
new_trackers = [[src_x, src_y, []]]
if not option_close
depth.times {
trackers = new_trackers
new_trackers = []
for tracker in trackers
if tracker[0] == trg_x and tracker[1] == trg_y
paths.push tracker[2].compact
next
end
path_map.push tracker[0] + tracker[1] / 10000.0
if passable?(tracker[0], tracker[1], DOWN, self_event) and
passable?(tracker[0], tracker[1] - 1, UP) and
not path_map.include? tracker[0] + (tracker[1] - 1) / 10000.0
path_map.push tracker[0] + (tracker[1] - 1) / 10000.0
new_trackers.push [tracker[0], tracker[1] - 1, [tracker[2], UP].flatten]
end
if passable?(tracker[0], tracker[1], RIGHT, self_event) and
passable?(tracker[0] - 1, tracker[1], LEFT) and
not path_map.include? tracker[0] - 1 + tracker[1] / 10000.0
path_map.push tracker[0] - 1 + tracker[1] / 10000.0
new_trackers.push [tracker[0] - 1, tracker[1], [tracker[2], LEFT].flatten]
end
if passable?(tracker[0], tracker[1], LEFT, self_event) and
passable?(tracker[0] + 1, tracker[1], RIGHT) and
not path_map.include? tracker[0] + 1 + tracker[1] / 10000.0
path_map.push tracker[0] + 1 + tracker[1] / 10000.0
new_trackers.push [tracker[0] + 1, tracker[1], [tracker[2], RIGHT].flatten]
end
if passable?(tracker[0], tracker[1], UP, self_event) and
passable?(tracker[0], tracker[1] + 1, DOWN) and
not path_map.include? tracker[0] + (tracker[1] + 1) / 10000.0
path_map.push tracker[0] + (tracker[1] + 1) / 10000.0
new_trackers.push [tracker[0], tracker[1] + 1, [tracker[2], DOWN].flatten]
end
end
break if paths.size > 0
}
else
paths_distance = 10000 ** 2 * 2
depth.times {
trackers = new_trackers
new_trackers = []
for tracker in trackers
if tracker[0] == trg_x and tracker[1] == trg_y
if paths_distance > 0
paths_distance = 0
paths.clear
end
paths.push tracker[2].compact
next
end
distance = (tracker[0] - trg_x) ** 2 + (tracker[1] - trg_y) ** 2
if distance <= paths_distance
if distance < paths_distance
paths.clear
paths_distance = distance
end
paths.push tracker[2].compact
end
path_map.push tracker[0] + tracker[1] / 10000.0
if passable?(tracker[0], tracker[1], DOWN, self_event) and
passable?(tracker[0], tracker[1] - 1, UP) and
not path_map.include? tracker[0] + (tracker[1] - 1) / 10000.0
path_map.push tracker[0] + (tracker[1] - 1) / 10000.0
new_trackers.push [tracker[0], tracker[1] - 1, [tracker[2], UP].flatten]
end
if passable?(tracker[0], tracker[1], RIGHT, self_event) and
passable?(tracker[0] - 1, tracker[1], LEFT) and
not path_map.include? tracker[0] - 1 + tracker[1] / 10000.0
path_map.push tracker[0] - 1 + tracker[1] / 10000.0
new_trackers.push [tracker[0] - 1, tracker[1], [tracker[2], LEFT].flatten]
end
if passable?(tracker[0], tracker[1], LEFT, self_event) and
passable?(tracker[0] + 1, tracker[1], RIGHT) and
not path_map.include? tracker[0] + 1 + tracker[1] / 10000.0
path_map.push tracker[0] + 1 + tracker[1] / 10000.0
new_trackers.push [tracker[0] + 1, tracker[1], [tracker[2], RIGHT].flatten]
end
if passable?(tracker[0], tracker[1], UP, self_event) and
passable?(tracker[0], tracker[1] + 1, DOWN) and
not path_map.include? tracker[0] + (tracker[1] + 1) / 10000.0
path_map.push tracker[0] + (tracker[1] + 1) / 10000.0
new_trackers.push [tracker[0], tracker[1] + 1, [tracker[2], DOWN].flatten]
end
end
break if distance == 0 and paths.size > 0
}
end
route = paths[0]
return route
end
end
#======================================
class Scene_Title
#--------------------------------------------------------------------------
alias aems_scene_title_update update
#--------------------------------------------------------------------------
def update
$AEMS = AEMS.new
aems_scene_title_update
end
end
#======================================
class Game_Character
attr_accessor :move_route
attr_accessor :move_route_index
end