This reminds me that I really want A-star pathfinding and Dijkstra range-finding as built-in features. Your input Mogri, would be valuable as to how a plotscript interface for these should look.
I actually wrote a kludgy a* algorithm for my own game. It uses globals from.. I think around 1000 to 16000 to represent map tile costs (so I'm limited to 100 x 150 / 122 x 122 -tile maps but hey) and then it fans out from any given x, y coordinates using two for-loops (x, -range, range), (y, -range, range) and an if (abs(x) + abs(y) << range) and sets a cost for the given tile if it is adjacent to any cost-having tiles (it ignores 0-value tiles; the function starts off by writing a 1 at the given x, y). It then adds the range to the cost if the tile contains an npc or is otherwise an "obstructed tile". In that way, I created a situation where the enemies would go around obstructions if possible but would just bump up against them if not.
This took me several weeks to get working right for a few reasons. The first is that if you get to a range of, let's say around 50, the engine starts to chug (as you might imagine). To combat this, I have the algorithm dump out if it writes a tile next its target and the tile-cost it has written is less than the total range (still not sure if this logically makes 100% sense but in practice it seems to).. I also changed the direction the x and y for-loops fan out so that it will examine tiles that are closest to an "as-the-crow-flies" path first. Additionally, I have set up a waypoint system whereby there are waypoint npcs that attempt to cut off very large ranges; e.g. if hero x is above waypoint a and enemy y (the searcher) is below waypoint a, use waypoint a as the cutoff point rather than hero x.
Anyway, if I had my druthers, the plotscripting version would work like this:
First, there would be a function that would attach value to a range of maptiles fanning out from x, y arguments with a third arg being the range. An optional fourth argument would tell it how to behave if it found "obstructions" (and maybe another optional fifth arg that would determine what constitutes an obstruction, e.g. npcs and walls). The three behaviors I can think of are that it should either write a zero (valueless or "unreachable" tile), write a cost + range (as I have it doing above) or ignore the obstruction and just write the normal cost.
Next there would be functions like "get tile cost" and "set tile cost" to be run after the above function (args are x, y). And also a "get direction of lowest cost adjacent tile" and "highest cost" (args would be x, y again; I'd say "get coordinates" or "get tile" but I don't know how it would return that). These functions might also have an optional arg for it to determine behavior if two or more adjacent tiles are of equal value (e.g. "choose random", "choose bottom-leftmost", etc.). Also, there would be a "wipe out all costs" function, of course.
Okay, that was a lot of text... Please let me know if you have any questions or would like me to clarify. If you'd like to see any of this code I've described, too, just let me know.
Also, I'm not at all saying that this way is the best, please keep that in mind. Code optimization has always been a problem for me. If anything, I'm hoping that this thread sparks something of a dialogue on this subject (which fascinates me; I had never even heard of a* before about a month ago when I was doing Google searches for "path-finding for npcs"). I'll probably learn something!