Hello everyone. A little bump at last. I have been pretty busy for the last months and I apologize for the lack of updates and for not answering your questions. I thank Me(tm) and Kain for their efforts on that end. I've been working on a new version, but it's been mostly small improvements that still don't amount to a new version. For 1.5 I want to take pathfinding calculation out of the loop (probably as an alternative update method to call every frame) so the calculation pause could be better controlled by your code, this allows calculating paths "in the background" and allow doing something else instead of just pausing everything. A change like that might take a while to implement and it's not a priority at the moment. If you have any suggestions for other changes, feel free to share them.
Anyway, to answer your questions:
Twin Matrix":1o9lwuxu said:
Bump for my question.
It's actually a simple question though it looks large.. I would appreciate it if someone could read it.
It's a few posts ^.
Use get_close to have the character get as close as possible to the goal. This is unlikely to fail which means the target might still be many tiles away and yet the character moves only a few tiles to get closer. You could have a reach method to be called where you check if the other character in range and then do what you want. If reach methods sound complex to you then create dummy ones like lambda { $game_switches[xxx] = true } and have the actual processing in some common event activated by the switch.
Goal Area is different. Instead of having a goal that's only one tile, you could have a circular area around the goal node by specifying the range when calling the setup method. A range of 1 means 1 tile around the goal and so on. Finding a goal area could fail, but it's useful for stuff like getting a character to move into the vicinity of another character or event without being precise or dealing with other characters not being passable.
So like I said, call setup setting the close argument to true (4th argument), and supply a reach method where you check if goal is actually within reach, if not you could teleport. You could also provide a failure method that teleports as well, just in case.
Now how you handle teleportation is up to you. Like I said, you could use a common event and take the code out of the reach method, but the complexity might arise when trying to know where to teleport and you don't know where the goal is (e.g. a moving character). I don't know how your game works so I can't recommend the best way to do it. It might involve scanning tiles around goal for passability, or specifying certain disconnected areas or rooms on map and having one teleport spot in each, teleporting to the spot closest to the goal, or some different way that makes sense in the context of your game. It's not really within the scope of this script.
I hope that made sense, or was helpful in a way. I generally wouldn't ask people to do that, but I advise you to study the script. Even if you're not a scripter or don't want to bother with the details, skimming it to get a general idea of how it works (just read the comments) will be greatly beneficial to understand how to utilize it in your game. I provide simple shortcuts for most general uses like moving a character from A to B, but to get the most from a script like this you need a general understanding of what goes behind the scenes.
This article is a good starting point. I'm not saying that to discourage you from asking me questions :P, I just thought that for your complex use of some script it pays to understand the cost of what you're doing (e.g. calculating many paths and checking if all failed... scary!)
etheon":1o9lwuxu said:
Just a question; wouldn't get a better average running-time (i.e.: O(nlogn)) with a binary tree implementation of your heap instead of an array implementation? Though Ruby arrays are different from conventional array, so I don't know...
Heap insertion and removal are O(logn) operations. It doesn't depend on whether you use a tree or an array. With an array binary heap, you could calculate children directly (2 * i and 2 * i + 1), and the minimum/maximum element is the first element so you never have to iterate over array elements to get O

behavior. Arrays might even be faster because there's less reference overhead and improved memory locality.
dario8676: I did implement your request but since I'm not releasing anything yet I might as well share it for your benefit. Replace the generate_path method with the following:
#--------------------------------------------------------------------------
# * Generate the Path by Following Parents and Return it
# as RPG::MoveRoute
# follow : If true the path is assigned to the character as a
# forced move route.
# steps : Actual number of steps to take, -1 means entire path
#--------------------------------------------------------------------------
def generate_path(follow = true, steps = -1)
# There's no path to generate if no path was found
if !@found
return
end
# Create a new move route that isn't repeatable
@route = RPG::MoveRoute.new
@route.repeat = false
# Generate path by starting from goal and following parents
node = @goal_node
code = 0 # Movement code for RPG::MoveCommand
while node.parent
# Get direction from parent to node as RPG::MoveCommand
direction = get_direction(node.parent.x, node.parent.y, node.x, node.y)
case direction
when 2 # Up
code = 4
when 4 # Left
code = 3
when 6 # Right
code = 2
when 8 # Down
code = 1
end
# Add movement code to the start of the array
@route.list.unshift(RPG::MoveCommand.new(code)) if code != 0
node = node.parent
end
if steps > -1
@route.list = @route.list[0, steps]
if @route.list[-1] and @route.list[-1].code != 0
@route.list.push(RPG::MoveCommand.new)
end
end
# If the path should be assigned to the character
if follow and !@route.list.empty?
@character.add_path(self)
end
# Return the constructed RPG::MoveRoute
return @route
end
end
Now you can call it with a number of steps to be followed: path.generate_path(true, 4).