Here is part from nextbot code from RunBehaviour coroutine:
[CODE]path:Compute( self, pos, function( area, fromArea, ladder, elevator, length )
if ( !IsValid( fromArea ) ) then
// first area in path, no cost
return 0
else
if ( !self.loco:IsAreaTraversable( area ) ) then
// our locomotor says we can't move here
return -1
end
// compute distance traveled along path so far
local dist = 0
if ( IsValid( ladder ) ) then
dist = ladder:GetLength()
elseif ( length > 0 ) then
// optimization to avoid recomputing length
dist = length
else
dist = ( area:GetCenter() - fromArea:GetCenter() ):GetLength()
end
local cost = dist + fromArea:GetCostSoFar()
// check height change
local deltaZ = fromArea:ComputeAdjacentConnectionHeightChange( area )
if ( deltaZ >= 18 ) then
// Involves jumping, skip it
return -1
elseif ( deltaZ < -self.loco:GetDeathDropHeight() ) then
// too far to drop
return -1
end
return cost
end
end )[/CODE]
Basically, I want path generator NOT to create path where jumping is needed and use alternative path that don't need jumping. But for some reasons, it still creates path with jumps. What am I doing wrong?
well the first problem is you're making a new function every time you run the path:Compute()
[lua]
local function pathComputeFunc(...)
// do stuff
end
function ENT:RunBehaviour()
path:Compute(self,pos, pathComputeFunc)
end
[/lua]
The second problem probably has something to do with an alternative path not existing?
What i'm saying is, perhaps post some information about how you've debugged this.
How do you know for certain the path contains jumps?
Have you added any debug code to check what's happening in these cases? (ex. if(deltaZ >= 18) then print("foundjump") end)
How are you sure there are alternative routes that don't require jumping?
Or for that matter, how do you know you've even got a complete path to your destination?
[CODE]path:Compute(self,pos, pathComputeFunc)[/CODE]
attempt to index global 'self' (a nil value)
[QUOTE=xDShot;52864509][CODE]path:Compute(self,pos, pathComputeFunc)[/CODE]
attempt to index global 'self' (a nil value)[/QUOTE]
Needs to be inside an ENT: function.[code]function ENT:RunBehaviour()[/code]
self is used in OOP: [url]http://lua-users.org/wiki/ObjectOrientationTutorial[/url]
Crash course:
[code]function ENT:AFunction()
// self works in here. The "ENT:" part sets the "self" to the entity this runs on. Like: Entity:AFunction()
end
function mahrandomfunction()
//self doesn't work here .. there is no "ENT:" part to refere to.
end
// self doesn't work here .. this is outside any functions.
[/code]
[QUOTE]Needs to be inside an ENT: function.[/QUOTE]
Tried that. What is odd is that I did put print( area, fromArea, ladder, elevator, length ) inside of this function to see variables, and all of them always were [I]nil[/I].
[editline]8th November 2017[/editline]
Solved. I needed to check area attributes along with height deltas.
So, I made it as separate nextbot function:
[CODE]function ENT:ComputePath( path, pos )
if not path then
print( self, "ENT:ComputePath", "path not provided!" )
elseif not pos then
print( self, "ENT:ComputePath", "pos not provided!" )
else
local function generator( area, fromArea, ladder, elevator, length )
if ( !IsValid( fromArea ) ) then
-- first area in path, no cost
return 0
else
if ( !self.loco:IsAreaTraversable( area ) ) then
-- our locomotor says we can't move here
return -1
end
-- compute distance traveled along path so far
local dist = 0
if ( IsValid( ladder ) ) then
dist = ladder:GetLength()
elseif ( length > 0 ) then
-- optimization to avoid recomputing length
dist = length
else
dist = ( area:GetCenter() - fromArea:GetCenter() ):GetLength()
end
local cost = dist + fromArea:GetCostSoFar()
-- check height change
local deltaZ = fromArea:ComputeAdjacentConnectionHeightChange( area )
if ( deltaZ >= 18 ) then
if ( deltaZ >= 48 ) then
-- too high to reach
return -1
end
-- jumping is slower than flat ground
local jumpPenalty = 666
cost = cost + jumpPenalty * dist
elseif ( deltaZ < -self.loco:GetDeathDropHeight() ) then
-- too far to drop
return -1
end
local attributes = fromArea:GetAttributes()
if bit.band( attributes, NAV_MESH_JUMP ) > 0 then
-- jumping is slower than flat ground
-- return -1
local jumpPenalty = 666
cost = cost + jumpPenalty * dist
end
if bit.band( attributes, NAV_MESH_CROUCH ) > 0 then
-- crouching is slower than running
local crouchPenalty = 5
cost = cost + crouchPenalty * dist
end
return cost
end
end
path:Compute( self, pos, generator )
end
end[/CODE]
and used [I]self:ComputePath( path, pos )[/I] instead of path:Compute(). Thanks for tip of debugging and dumb rating.
P.S. Never use it outside of coroutine...
Sorry, you need to Log In to post a reply to this thread.