#======================================
# ■ 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.force_move_route(@player_route)
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 Game_Character
attr_accessor :move_route
attr_accessor :move_route_index
end