• Nextbot PathFollower:Compute() generator doesn't work?
    4 replies, posted
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.