Quote Originally Posted by Dan
The way point system is not so much different from a grid system.
Every node simply needs to store the pointers to all the neighbour nodes.
And what kind of game exactly are you making?
dan see this plz

http://leafproject.com.sapo.pt/leaf.html

the unit LEAF_Pathfinding is that i want but thin unit dont work

Code:
Unit LEAF_Pathfinding;

Interface
Uses LEAF_System,LEAF_IO;

Type
 LPath=Class
  List:Array Of Integer;
  Size:Word;
 End;

 PNode=^LNode; // Pointer to a node
 LNode=Record
  Name:String; //If Null then Name='NODE'+LStr(I)
  Position:LVector;
  NextNode:Array[0..3]Of Integer;
  Distance:Array[0..3]Of Single;
  //DIJKSTRAs ALGORITHM
  VisitNumber:Integer; //What order was this node visited
  CurrentDistance:Single; //What the current distance was at this point
  TmpVar:Single; //Temporary area for storing distance data...
 End;

 LNodeList=Array Of LNode;

 LPathfinder=Class
  Protected
   _NodeCount:Word;
   _NodeList:LNodeList;

  Public

   Procedure Load(Source:LStream);
   Procedure Save(Dest:LStream);

   Procedure AddNode(Position:LVector);
   Procedure RemoveNode(Id:Integer);
   Function GetNode(Name:String):Integer;
   Function GetNearNode(Pos:LVector):Integer;
   Function GetNodeDistance(Node:Integer;Pos:LVector):Single;
   Function GetPath(StartNode,EndNode:Word;Var Path:LPath):Boolean;


   Property NodeCount:Word Read _NodeCount;
   Property NodeList:LNodeList Read _NodeList;

 End;

Implementation
Uses LEAF_Math;

// LPathfinder

Procedure LPathfinder.Load(Source: LStream);
Var
 I,J:Integer;
 S:String;
Begin
 If Assigned(Source) Then
 Begin
  Source.Read(_NodeCount,SizeOf(_NodeCount));
  SetLength(_NodeList,_NodeCount);
  For I:=0 To Pred(_NodeCount) Do
  Begin
   Source.Read(_NodeList[I].Position,SizeOf(_NodeList[I].Position));
   Source.Read(_NodeList[I].NextNode[0],SizeOf(Integer)*4);
   Source.Read(_NodeList[I].Distance[0],SizeOf(Single)*4);
   For J:=0 To 3 Do
    If _NodeList[I].NextNode[J]>=_NodeCount Then
    Begin
     RaiseError('AI.Pathfinding.Load(): Invalid node.');
     Exit;
    End;
   Source.ReadString(S);
   _NodeList[I].Name:=UpStr(S);
  End;
 End Else
 Begin
  SetLength(_NodeList,1);
  For J:=0 To 3 Do
   _NodeList[0].NextNode[J]:=-1;
 End;
End;

Procedure LPathfinder.Save(Dest:LStream);
Var
 I:Integer;
Begin
 Dest.Write(_NodeCount,SizeOf(_NodeCount));
 For I:=0 To Pred(_NodeCount) Do
 Begin
  Dest.Write(_NodeList[I].Position,SizeOf(_NodeList[I].Position));
  Dest.Write(_NodeList[I].NextNode[0],SizeOf(Integer)*4);
  Dest.Write(_NodeList[I].Distance[0],SizeOf(Single)*4);
  Dest.WriteString(_NodeList[I].Name);
 End;
End;

Procedure LPathfinder.AddNode(Position:LVector);
Var
 I:Integer;
Begin
 SetLength(_NodeList,Succ(_NodeCount));
 _NodeList[_NodeCount].Position:=Position;
 _NodeList[_NodeCount].Name:='NODE'+LStr(Succ(_NodeCount));
 For I:=0 To 3 Do
 Begin
  _NodeList[_NodeCount].NextNode[I]:=-1;
  _NodeList[_NodeCount].Distance[I]:=0;
 End;
 Inc(_NodeCount);

End;

Procedure LPathfinder.RemoveNode(Id:Integer);
Var
 I,J:Integer;
Begin
 For I:=0 To Pred(_NodeCount) Do
  For J:=0 To 3 Do
   If _NodeList[I].NextNode[J]=Id Then
     _NodeList[I].NextNode[J]:=-1;

 If Id=Pred(_NodeCount) Then
  Dec(_NodeCount)
 Else
 Begin
  _NodeList[Id]:=_NodeList[Pred(_NodeCount)];
  For I:=0 To Pred(_NodeCount) Do
   For J:=0 To 3 Do
    If _NodeList[I].NextNode[J]=Pred(_NodeCount) Then
      _NodeList[I].NextNode[J]:=Id;
  Dec(_NodeCount);
 End;

End;

Function LPathfinder.GetNode(Name:String):Integer;
Var
 I:Integer;
Begin
 Name:=UpStr(Name);
 Result:=-1;
 For I:=0 To Pred(_NodeCount) Do
  If _NodeList[I].Name=Name Then
  Begin
   Result:=I;
   Break;
  End;

End;

Function LPathfinder.GetNodeDistance(Node:Integer;Pos:LVector):Single;
Begin
 Result:=VectorLength(VectorSubtract(_NodeList[Node].Position,Pos));
End;

Function LPathfinder.GetNearNode(Pos:LVector):Integer;
Var
 I:Integer;
 D,M:Single;
Begin
 Result:=-1;
 D:=99999;
 For I:=0 To Pred(_NodeCount)Do
  Begin
   M:=Sqrt(Sqr(Pos.X-_NodeList[I].Position.x)+
           Sqr(Pos.Y-_NodeList[I].Position.Y)+
           Sqr(Pos.Z-_NodeList[I].Position.Z));
   If M<D Then
   Begin
    D&#58;=M;
    Result&#58;=I;
   End;
  End;

End;

Function LPathfinder.GetPath&#40;StartNode,EndNode&#58;Word;Var Path&#58;LPath&#41;&#58;Boolean;
Var
// Any variables required
 I,J,K&#58;Word;
 CurrentVisitNumber&#58;Word; //Which visit the current node will be
 CurrNode&#58;Word; //Which node we are scanning...
 LowestNodeFound&#58;Word; //For when we are searching for the lowest temporary value
 LowestValFound&#58;Single; //For above variable
 StartTime&#58;Cardinal;
Begin
 Path.Size&#58;=2;
 SetLength&#40;Path.List,2&#41;;
 If StartNode=EndNode Then //we're already there...
 Begin
   Path.List&#91;0&#93;&#58;=StartNode;
   Path.List&#91;1&#93;&#58;=EndNode;
   Result&#58;=True;
   &#123;$IFDEF PROFILE&#125;Profiler.EndProfile;&#123;$ENDIF&#125;
   Exit;
 End;

//Setup all the data we need
 For I&#58;=0 To Pred&#40;_NodeCount&#41; Do
 Begin
  _NodeList&#91;I&#93;.VisitNumber&#58;=-1; //Not visited
  _NodeList&#91;I&#93;.CurrentDistance&#58;=-1; //Unknown distance
  _NodeList&#91;I&#93;.TmpVar&#58;=99999; //A high number that can easily be beaten
 End;

//Set the first variable
 _NodeList&#91;StartNode&#93;.VisitNumber&#58;=1;
 CurrentVisitNumber&#58;=1; //Initialise
 CurrNode&#58;=StartNode;
 _NodeList&#91;StartNode&#93;.CurrentDistance&#58;=0;
 _NodeList&#91;StartNode&#93;.TmpVar&#58;=0;

 LowestNodeFound&#58;=0;
 Repeat
 //Go to each node that the current one touches
 //and make it's temporary variable = source distance + weight of the arc
  For J&#58;=0 To 3 Do
   If &#40;_NodeList&#91;CurrNode&#93;.NextNode&#91;J&#93;<1>=0&#41;Then //Only if there is a node in this direction
    If &#40;_NodeList&#91;_NodeList&#91;CurrNode&#93;.NextNode&#91;J&#93;&#93;.VisitNumber>=0&#41;Then //Only if we visited this node...
     If &#40;_NodeList&#91;CurrNode&#93;.CurrentDistance-_NodeList&#91;_NodeList&#91;CurrNode&#93;.NextNode&#91;J&#93;&#93;.CurrentDistance=_NodeList&#91;CurrNode&#93;.Distance&#91;J&#93;&#41; Then //NextNode&#40;0&#41; is part of the route home
      Begin
       Inc&#40;Path.Size&#41;;
       SetLength&#40;Path.List,Path.Size&#41;;
       Path.List&#91;Pred&#40;Path.Size&#41;&#93;&#58;=_NodeList&#91;CurrNode&#93;.NextNode&#91;J&#93;;
       CurrNode&#58;=_NodeList&#91;CurrNode&#93;.NextNode&#91;J&#93;;
       Break;
      End;

 Until False;

 //Reverse the path list
 For I&#58;=0 To Pred&#40;Path.Size Div 2&#41; Do
  Begin
   J&#58;=Path.Size-Succ&#40;I&#41;;
   K&#58;=Path.List&#91;I&#93;;
   Path.List&#91;I&#93;&#58;=Path.List&#91;J&#93;;
   Path.List&#91;J&#93;&#58;=K;
  End;

 Result&#58;=True;
&#123;$IFDEF PROFILE&#125;Profiler.EndProfile;&#123;$ENDIF&#125;
End;

End.