Posted: 12th Jul 2003 11:10
Oki, heres the source...

Editor:
+ Code Snippet
global pathnode as integer
pathnode = 32
global dim pathnodes(pathnode, 9) as integer
global selectedpathnode as integer
selectedpathnode = 1

autocam off
flush video memory
sync on
sync rate 30
hide mouse
backdrop on
color backdrop rgb(80, 80, 80)
set text font "arial"
set text size 16
set text transparent


load object "modelname.x", 1
load object "modelname.x", 2
set object wireframe 2, 1
ghost object on 1
color object 1, 0
color object 2, 0


id_elephant = 600
Load Object "All_animations.x", id_elephant
scale object id_elephant, 500, 500, 500


InitNodes()
set object collision off 1

a#=0
b#=0

e_x#=400.0
e_y#=-118.0
e_z#=300.0
e_a#=0
`//////////////////////////////////////////// Beginning of Main Loop ////////////////////////////////////////
do
ink rgb(0, 255, 0), rgb(0, 255, 0)

`The "w" key
if keystate(17)=1 then inc pathnodes(selectedpathnode, 3), 2

 `The "s" key
 if keystate(31)=1 then dec pathnodes(selectedpathnode, 3), 2


 `The "a" key
 if keystate(30)=1 then dec pathnodes(selectedpathnode, 2), 2

 `The "d" key
 if keystate(32)=1 then inc pathnodes(selectedpathnode, 2), 2

 if leftkey()=1 then inc a#, 2
 if rightkey()=1 then dec a#, 2
 if upkey()=1 then inc y#, 4
 if downkey()=1 then dec y#, 4

 if inkey$()="q" then pathnodes(selectedpathnode, 1) = 0
 if inkey$()="e" then pathnodes(selectedpathnode, 1) = 1

 if inkey$()="]" then inc selectedpathnode
 if inkey$()="[" then dec selectedpathnode

 if inkey$() = "," then dec pathnodes(selectedpathnode, 4), 2

 if inkey$() = "." then inc pathnodes(selectedpathnode, 4), 2

 if returnkey() = 1
   SavePathNodes("PathNodes.node")
 endif
 if inkey$() = "l"
   LoadPathNodes("PathNodes.node")
 endif
`-----------------------------------------------------------
if inkey$()="1"
   input "Link 1: Link current node to node number? "; temp
   pathnodes(selectedpathnode, 6) = temp
endif
if inkey$()="2"
   input "Link 2: Link current node to node number? "; temp
   pathnodes(selectedpathnode, 7) = temp
endif
if inkey$()="3"
   input "Link 3: Link current node to node number? "; temp
   pathnodes(selectedpathnode, 8) = temp
endif
if inkey$()="4"
   input "Link 4: Link current node to node number? "; temp
   pathnodes(selectedpathnode, 9) = temp
endif

 if selectedpathnode<1 then selectedpathnode=1
 if selectedpathnode>pathnode then selectedpathnode=pathnode

 for i = 1 to pathnode
   position object i+2, pathnodes(i, 2), -100, pathnodes(i, 3)
   if pathnodes(i, 1) = 0 then set object wireframe i+2, 1
   if pathnodes(i, 1) = 1
      set object wireframe i+2, 0
      for j=1 to 4
         if pathnodes(i, 5+j)>0
            ink rgb(0, 0, 255), rgb(0, 0, 255)
            line object screen x(i+2), object screen y(i+2), object screen x(pathnodes(i, 5+j)+2), object screen y(pathnodes(i, 5+j)+2)
         endif
      next j
      ink rgb(0, 255, 0), rgb(0, 255, 0)
      set cursor object screen x(i+2), object screen y(i+2)
      print i
   endif
 next i

 position object pathnode+3, pathnodes(selectedpathnode, 2), -100, pathnodes(selectedpathnode, 3)
 scale object pathnode+3, pathnodes(selectedpathnode, 4), pathnodes(selectedpathnode, 4), pathnodes(selectedpathnode, 4)

 set camera to follow pathnodes(selectedpathnode, 2), -100, pathnodes(selectedpathnode, 3), a#, 600, y#, 10, 0
 point camera pathnodes(selectedpathnode, 2), -100, pathnodes(selectedpathnode, 3)


set cursor 0, 0
ink rgb(255, 255, 255), rgb(255, 255, 255)
`print screen fps()
print "Path Node Selected: "; selectedpathnode
print "Path Node Existant: "; pathnodes(selectedpathnode, 1)
print "X Position: "; pathnodes(selectedpathnode, 2)
print "Z Position: "; pathnodes(selectedpathnode, 3)
print "Node Area (Radius): "; pathnodes(selectedpathnode, 4)
print "Node Link 1: "; pathnodes(selectedpathnode, 6)
print "Node Link 2: "; pathnodes(selectedpathnode, 7)
print "Node Link 3: "; pathnodes(selectedpathnode, 8)
print "Node Link 4: "; pathnodes(selectedpathnode, 9)
for i=1 to pathnode
   print pathbank(i)
next i
sync
loop

Function InitNodes()

make object sphere pathnode+3, 100
ghost object on pathnode+3

for i=1 to pathnode
   pathnodes(i, 1) = 0
   pathnodes(i, 4) = 100
   pathnodes(i, 6) = 0
   pathnodes(i, 7) = 0
   pathnodes(i, 8) = 0
   pathnodes(i, 9) = 0

   make object sphere i+2, 40
   xrotate object i+2, 180
next i

EndFunction

function SavePathNodes(filename$)

   if file exist(filename$) then delete file filename$

   open to write 1, filename$

   print "Saving..."
   sync

   for i=1 to pathnode
      for j=1 to 9
         write long 1, pathnodes(i, j)
      next j
   next i

   close file 1

endfunction

function LoadPathNodes(filename$)

   open to read 1, filename$

   print "Loading..."
   sync

   for i=1 to pathnode
      for j=1 to 9
         read long 1, pathnodes(i, j)
      next j
   next i

   close file 1

endfunction

Function Distance(x1, y1, z1, x2, y2, z2)

   x = abs(x1-x2)
   y = abs(y1-y2)
   z = abs(z1-z2)

   dist = int(sqrt(x*x+y*y+z*z))

endfunction dist


Just replace modelname.x with the name of the model you want to use as a guide to model.
Controls:
- w, s, a, d to move the selected node
- [ and ] to change the selected node
- , and . to change the radius of the node (for calculating what node your player is on
- q and e toggle the node existance
- 1, 2, 3 and 4 let you set the node links
- Enter saves the data as pathnodes.node
- L loads pathnodes.node
Note: for the moment, you cannot have seperate node areas, meaning all nodes must be able to get every other node via links and other nodes.


The big function:
+ Code Snippet
Function FindPath(StartNode, EndNode)

   found = 1
   path = 0
   Parent = 0
   Child = 0

   for i=1 to pathnode
      OpenList(i) = StartNode
      OnOpenList(i) = 0
      ClosedList(i) = 0
      ParentNode(i) = 0
   next i

   ClosedList(1) = 0
   ParentNode(1) = 0
   Cost(StartNode, GCost) = 0
   Cost(StartNode, FCost) = 999999999

   if StartNode = EndNode
      `No Need to find path
      exitfunction found
   endif

   `Do until path found
   do

      `Set Parent Value
      Parent = OpenList(1)
      `Put Node on closed list
      ClosedList(Parent) = 1

      `Remove node from list and suffle up 1
      for i = 1 to (pathnode-1)
         OpenList(i) = OpenList(i+1)
      next i

      `Check Nodes children, and put them on the open list if not on closed list
      for q=1 to 4
         Child = pathnodes(Parent, 5+q)
         if ClosedList(Child)=0
            if Child>0
               if OnOpenList(Child)=0
                  `Put node on bottom of Open List
                  OpenList(pathnode) = Child
                  `Put Child on Open List
                  OnOpenList(Child) = 1
                  `Calculate its G cost
                  addedGCost = Distance(pathnodes(parent, HCost), 0, pathnodes(parent, FCost), pathnodes(child, HCost), 0, pathnodes(child, FCost))
                  Cost(Child, GCost) = Cost(Parent, GCost) + addedGCost
                  `Calculate its H Cost
                  Cost(Child, HCost) = Distance(pathnodes(child, HCost), 0, pathnodes(child, FCost), pathnodes(EndNode, HCost), 0, pathnodes(EndNode, FCost))
                  `Thus, Calculate its F Cost
                  Cost(Child, FCost) = Cost(Child, GCost) + Cost(Child, HCost)
                  `Bubble the Child to its correct position in the Open List
                  for i = 0 to pathnode-1
                     for j=1 to pathnode-i
                        if Cost(OpenList(j-1), 3)>Cost(OpenList(j), 3)
                           swap = OpenList(j)
                           OpenList(j) = OpenList(j-1)
                           OpenList(j-1) = swap
                        endif
                     next j
                  next i

                  `Set Parent Node to Parent
                  ParentNode(Child) = Parent

               `If Child Node is already on the open list, check to see if the path from the current parent
               `     to the child is less than the path from the childs parents to the child
               else
                  `Calculate the G cost
                  addedGCost = Distance(pathnodes(parent, 2), 0, pathnodes(parent, 3), pathnodes(child, 2), 0, pathnodes(child, 3))
                  tempcost = Cost(Parent, GCost) + addedGCost
                  `If this cost is less, then change the G and F costs
                  if Cost(Child, GCost)>tempcost
                     `Change Costs for new Parent
                     Cost(Child, GCost) = tempcost
                     Cost(Child, 3) = Cost(Child, HCost) + tempcost
                     `Set Parent Node to Parent
                     ParentNode(Child) = Parent
                     `Because we changed the FCost, we have to put it in its correct spot in the Open List
                     for i = 0 to pathnode-1
                        for j=1 to pathnode-i
                           if Cost(OpenList(j-1), 3)>Cost(OpenList(j), 3)
                              swap = OpenList(j)
                              OpenList(j) = OpenList(j-1)
                              OpenList(j-1) = swap
                           endif
                        next j
                     next i
                  endif : `if Cost(Child, GCost)>tempcost
               endif : `if OpenList(Child)=0
            endif : `if Child>0
         endif : `if ClosedList(Child)=1

      next q : `for q=1 to 4

      `Check if path found
      if OnOpenList(EndNode)
         `Path Found!
         Path = Found
         exit
      endif

   Loop : `While Path<Found

   `Calculate the path length
   pathlength = 0
   Node = EndNode
   do
      `Increment the path length
      inc pathlength
      `Go to current nodes parent
      Node = ParentNode(Node)
      `If at start, exit loop
      if Node = StartNode then exit
   loop

   `Fill array of node positions for the found path
   Node = EndNode
   for i=pathlength to 1 step -1
      `Store Current Node
      pathBank(i) = Node
      `Go to current Nodes parent
      Node = ParentNode(Node)
      if Node = StartNode then exit
   next i
`End of Function :: Path found
EndFunction 1


Globals needed for FindPath()
+ Code Snippet
global pathnode as integer
pathnode = 32
global dim pathnodes(pathnode, 9) as integer
global dim ClosedList(pathnode) as integer
global dim OnOpenList(pathnode) as integer
global dim OpenList(pathnode) as integer
global dim ParentNode(pathnode) as integer
global dim Cost(pathnode, 3) as integer
global dim PathBank(pathnode) as integer
global pathlength as integer
global GCost as integer
global HCost as integer
global FCost as integer
GCost = 1
HCost = 2
FCost = 3


Just put this and the LoadPathNodes() Function in yer game and run the function. It will return 1 if it finds the path (almost always). The pathfinding node data is stored in PathBank (which is an array).

Please reply if yo have any troubles

EDIT: Fixed post, it did some weird s***