Basic A-Star Pathfinder
Jump to navigation
Jump to search
LSL Portal | Functions | Events | Types | Operators | Constants | Flow Control | Script Library | Categorized Library | Tutorials |
Integer based node-grid sized at 20x32.
Tile <lsl> // 2009, Nexii Malthus // Public Domain
integer Obstacle = FALSE; default {
touch_start(integer total_number) { if(llDetectedKey(0) != llGetOwner()) return; if(!Obstacle){ llRegionSay(9999,llGetSubString(llGetScriptName(),4,-1)); llSetScale(<1.0,1.0,1.0>); llSetColor(<0.25,0.25,0.25>,0); Obstacle = TRUE; } else { llRegionSay(9999,llGetSubString(llGetScriptName(),4,-1)); llSetScale(<1.0,1.0,0.01>); llSetColor(<1.00,1.00,1.00>,0); Obstacle = FALSE; } }
} </lsl>
A* Unit <lsl> // 2009, Nexii Malthus // Public Domain
list Rows = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; list Nodes = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; list Cost = [14,10,14,
10, 10, 14,10,14];
list Directions = [< 1, 1,0>,< 0, 1,0>,<-1, 1,0>,
< 1, 0,0>, <-1, 0,0>, < 1,-1,0>,< 0,-1,0>,<-1,-1,0>];
list aPath; vector Dest; integer Tock;
integer Change; vector Ref = <15.5,67.0,22.0>;
integer GetState(list Src,integer X,integer Y){
return llList2Integer(Src,Y) & X;}
list SetState(list Src,integer X,integer Y){
return llListReplaceList(Rows,[llList2Integer(Src,Y) ^ X],Y,Y);}
integer Dist(integer X1,integer Y1,integer X2,integer Y2){
return (X1 - X2) + (Y1 - Y2);}
list A_Path(vector GPos,vector TPos){
if(!Change) return; list Path = []; vector gPos = GPos - Ref; vector tPos = TPos - Ref; integer X1 = (integer)gPos.x;integer Y1 = (integer)gPos.y; integer Xt = (integer)tPos.x;integer Yt = (integer)tPos.y; integer Tick = 150;//Failsafe... @Loop; --Tick; integer Dir = -1;integer H = 999; if(!GetState(Rows,X1+1,Y1+1) && !GetState(Nodes,X1+1,Y1+1)){ if(H < 14 + Dist(X1+1,Y1+1,Xt,Yt)){ Dir = 0; } } if(!GetState(Rows,X1 ,Y1+1) && !GetState(Nodes,X1 ,Y1+1)){ if(H < 10 + Dist(X1 ,Y1+1,Xt,Yt)){ Dir = 1; } } if(!GetState(Rows,X1-1,Y1+1) && !GetState(Nodes,X1-1,Y1+1)){ if(H < 14 + Dist(X1-1,Y1+1,Xt,Yt)){ Dir = 2; } } if(!GetState(Rows,X1+1,Y1 ) && !GetState(Nodes,X1+1,Y1 )){ if(H < 10 + Dist(X1+1,Y1 ,Xt,Yt)){ Dir = 3; } } if(!GetState(Rows,X1-1,Y1 ) && !GetState(Nodes,X1-1,Y1 )){ if(H < 10 + Dist(X1-1,Y1 ,Xt,Yt)){ Dir = 4; } } if(!GetState(Rows,X1+1,Y1-1) && !GetState(Nodes,X1+1,Y1-1)){ if(H < 14 + Dist(X1+1,Y1-1,Xt,Yt)){ Dir = 5; } } if(!GetState(Rows,X1 ,Y1-1) && !GetState(Nodes,X1 ,Y1-1)){ if(H < 10 + Dist(X1 ,Y1-1,Xt,Yt)){ Dir = 6; } } if(!GetState(Rows,X1-1,Y1-1) && !GetState(Nodes,X1-1,Y1-1)){ if(H < 14 + Dist(X1-1,Y1-1,Xt,Yt)){ Dir = 7; } } Path += Dir; Nodes = SetState(Nodes,X1,Y1); if((X1 != Xt)||(Y1 != Yt)||(!Tick)||(Dir+1)) jump Loop; Nodes = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; return Path;
}
default
{
state_entry(){ llListen(9999,"","",""); } listen(integer ch,string nm,key id,string msg){ integer Y = (integer)msg;integer X = (integer)nm; Rows = SetState(Rows,X,Y); Change = TRUE; } touch_start(integer dnum){ if(llDetectedKey(0) != llGetOwner())return; llSensor("Target","",PASSIVE,30.0,TWO_PI); } sensor(integer dnum){ Dest = llDetectedPos(0); aPath = A_Path(llGetPos(),Dest); llSetTimerEvent(1.0); } timer(){ if(Change){aPath = A_Path(llGetPos(),Dest);Tock = 0;} llSetPos(llGetPos() + llList2Vector(Directions,llList2Integer(aPath,Tock))); ++Tock;if(Tock >= llGetListLength(aPath) || llVecDist(llGetPos(),Dest) < 0.1) llSetTimerEvent(FALSE); }
} </lsl>