Page 2 of 2

Re: Pathing around other units using Jumper.

Posted: Sat Nov 30, 2013 11:28 am
by Roland_Yonaba
NemoVonFish wrote:Aha! Perfect! Thank you very much, i'm pretty sure i'm using an earlier version, so i'll get a newer one, give that a shot, and let you know how I go.
Just grab the latest stable release: 1.8.1.

Re: Pathing around other units using Jumper.

Posted: Sun Dec 01, 2013 1:06 am
by NemoVonFish
I noticed that the tunneling feature doesn't work with JPS pathfinding, and your suggestion worked fine with ASTAR, what is the difference between all the pathfinders? For what i'm doing, will one work better than any of the others?

*EDIT* Looked in to it a bit harder, I think I get why A* is the best for what i'm doing, but I don't quite get the difference between that and JPS

Re: Pathing around other units using Jumper.

Posted: Sun Dec 01, 2013 9:50 am
by NemoVonFish
Alright, best pathing system aside, I had a look at the links you gave me, did some reading, and yes, my method wasn't the best. A better way is to only block them from moving on to or through each other when they try, though my implementation is causing some rather fatal recursion problems.

Essentially, I want all of the entities to path to the PC, overlapping pathing is fine. But when one tries to move in to a space occupied by another, stop it, set the other entities as unpathable, then generate another path. If they can find one, follow that one instead, otherwise stand there and do nothing.
That's not what happens. As soon as one tries to step on another, they go AAAAAAAAAAAAAAAAAAAAAAAAAAAAHH and the stack overflows.

Two functions are causing the problem:

Code: Select all

function npcMoveTo(foo, x, y)
	-- Is the player there?
	if player.grid_x/tileSize == x and player.grid_y/tileSize == y then
		-- Attack the player.
		enemyAttackPC(foo)
		return
	end
	-- Is there a closed door at the destination?
	if mapCurrent.scenery[y][x] == 1 then
		-- If so, open it.
		entityOpenDoor(foo, x, y)
		return
	end
	-- Is there already an entity there?
	for i, v in ipairs(enemies) do
		if x*tileSize == v.grid_x and y*tileSize == v.grid_y then
			-- If so, tag every tile containing an entity as unpathable
			for i, v in ipairs(enemies) do
				mapCurrent.pathing[v.grid_y/tileSize][v.grid_x/tileSize] = 0
			end
			-- Then generate a new path
			approachPC(foo)
			mapCurrent.pathing = deepCopy(mapCurrent.terrain)
			return
		end
	end
	-- Otherwise, move closer.
	foo.grid_x = x * tileSize
	foo.grid_y = y * tileSize
	foo.energy = foo.energy - foo.moveCost
end
and

Code: Select all

function approachPC(foo)
	calculatePath(foo, player)
	if foo.path == false or foo.path == nil then -- Can the enemy path to the PC?
		-- If not, then do nothing
		foo.energy = foo.energy - foo.moveCost
	else
		-- Then take the first step
		local nextStep = foo.path[2]
		npcMoveTo(foo, nextStep.x, nextStep.y)
	end
end
I have poured over these two functions several times, found one error (that approachPC(foo) was approachPC(v) about twenty minutes ago, causing all sorts of problems), but nothing that solves the stack overflow. Can anyone see where i'm messing up in these two? Or is the problem somewhere else that's causing the stack overflow?

Re: Pathing around other units using Jumper.

Posted: Sun Dec 01, 2013 10:00 am
by Roland_Yonaba
NemoVonFish wrote:I noticed that the tunneling feature doesn't work with JPS pathfinding...
It is known. :nyu:
Actually, it was fixed in the following commits (after 1.8.1), but the API will be extended slightly (with new methods (get/set)Tunnelling()), so you should wait for the next release to use it. Until that, you can go with Astar finder, it handles tunnelling perfectly.
NemoVonFish wrote:What is the difference between all the pathfinders? For what i'm doing, will one work better than any of the others?
*EDIT* Looked in to it a bit harder, I think I get why A* is the best for what i'm doing, but I don't quite get the difference between that and JPS
JPS is just faster than regular Astar, as it using pruning tricks to go faster. But you will get a real benefit with JPS over Astar on large grids.
You can go through this article for in-depth details on how it works.

Re: Pathing around other units using Jumper.

Posted: Tue Dec 03, 2013 3:39 pm
by Rickton
How I fixed the problem was by, at the end of every turn, recalculating the collision map, and marking each enemy space as unpathable.
Make sure you mark the player's location as pathable, though, or they won't be able to path to the player. Likewise, they won't be able to path to each other, if you want to have creatures attack or follow each other. I came up with a way around this, too, but it's not very elegant so I won't post it if you don't need it. :P

Thanks, Roland_Yonaba, first of all for making Jumper, but secondly for mentioning that the Grid keeps a reference to the collision map object. I wasn't recreating the Grid every time I tried to pathfind, but I was recreating it after every turn when the collision map changed. Now I realize I just have to change the collision map and the Grid will update automatically.