528 lines
19 KiB
Plaintext
528 lines
19 KiB
Plaintext
///////////////////////////////////////////////////////////////////////////////////
|
|
// Real Time Strategy - NWN - Complex Path Finding Made Easy
|
|
//================================================================================
|
|
// By Deva Bryson Winblood. 03/09/2003
|
|
///////////////////////////////////////////////////////////////////////////////////
|
|
// required: each area have a waypoint with tag FIND_NODE
|
|
// NAME must be setup as follows x.y.z.UP.DOWN.NORTH.EAST.SOUTH.WEST
|
|
// where x,y,z is a number 0 and up. The directions are replaced by the tag
|
|
// of the area that leads to. This waypoint will be used by units for
|
|
// pathing.
|
|
|
|
|
|
int MAX_SEARCH = 15;
|
|
int DIR_UP = 1;
|
|
int DIR_DOWN = 2;
|
|
int DIR_NORTH = 3;
|
|
int DIR_EAST = 4;
|
|
int DIR_SOUTH = 5;
|
|
int DIR_WEST = 6;
|
|
|
|
void fnError(string sE)
|
|
{ // quick error message
|
|
SendMessageToPC(GetFirstPC(),sE);
|
|
PrintString(sE);
|
|
} // fnError()
|
|
|
|
string fnParsePeriod(string sIn)
|
|
{ // Parse period
|
|
string sH=sIn;
|
|
string sR="";
|
|
while (GetStringLength(sH)>0&&GetStringLeft(sH,1)!=".")
|
|
{ // build string
|
|
sR=sR+GetStringLeft(sH,1);
|
|
sH=GetStringRight(sH,GetStringLength(sH)-1);
|
|
} // build string
|
|
return sR;
|
|
} // fnParsePeriod()
|
|
|
|
string fnRemParsed(string sO, string sP)
|
|
{ // Remove parsed portion from sO
|
|
string sR="";
|
|
if (GetStringLength(sO)>=GetStringLength(sP))
|
|
sR=GetStringRight(sO,GetStringLength(sO)-GetStringLength(sP));
|
|
if (GetStringLeft(sR,1)==".") sR=GetStringRight(sR,GetStringLength(sR)-1);
|
|
return sR;
|
|
} // fnRemParsed()
|
|
|
|
string fnCanGoDirection(object oArea,int nDir)
|
|
{ // is their a direction for this returns NA if false
|
|
string sMNDown; // down destination
|
|
string sMNUp; // up destination
|
|
string sMNNorth; // North destination
|
|
string sMNSouth; // South destination
|
|
string sMNEast; // East destination
|
|
string sMNWest; // West destination
|
|
string x,y,z; // coordinates
|
|
object oNode=GetNearestObjectByTag("FIND_NODE",oArea);
|
|
string sName=GetName(oNode);
|
|
x=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,x);
|
|
y=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,y);
|
|
z=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,z);
|
|
sMNUp=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,sMNUp);
|
|
sMNDown=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,sMNDown);
|
|
sMNNorth=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,sMNNorth);
|
|
sMNEast=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,sMNEast);
|
|
sMNSouth=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,sMNSouth);
|
|
sMNWest=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,sMNWest);
|
|
if (nDir==DIR_UP&&sMNUp!="NA"&&GetStringLength(sMNUp)>1)
|
|
return sMNUp;
|
|
else if (nDir==DIR_DOWN&&sMNDown!="NA"&&GetStringLength(sMNDown)>1)
|
|
return sMNDown;
|
|
else if (nDir==DIR_NORTH&&sMNNorth!="NA"&&GetStringLength(sMNNorth)>1)
|
|
return sMNNorth;
|
|
else if (nDir==DIR_EAST&&sMNEast!="NA"&&GetStringLength(sMNEast)>1)
|
|
return sMNEast;
|
|
else if (nDir==DIR_SOUTH&&sMNSouth!="NA"&&GetStringLength(sMNSouth)>1)
|
|
return sMNSouth;
|
|
else if (nDir==DIR_WEST&&sMNWest!="NA"&&GetStringLength(sMNWest)>1)
|
|
return sMNWest;
|
|
return "NA";
|
|
} // fnCanGoDirection()
|
|
|
|
int fnAreaWhichDirection(object oArea,object oDest)
|
|
{ // returns the direction to be taken to the area specified
|
|
// return of 0 = already there
|
|
int nRet=0;
|
|
string x,y,z;
|
|
string dx,dy,dz;
|
|
string sName=GetName(oArea);
|
|
int nx,ny,nz;
|
|
int ndx,ndy,ndz;
|
|
object oHandle;
|
|
x=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,x);
|
|
y=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,y);
|
|
z=fnParsePeriod(sName);
|
|
sName=GetName(oDest);
|
|
dx=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,dx);
|
|
dy=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,dy);
|
|
dz=fnParsePeriod(sName);
|
|
nx=StringToInt(x);
|
|
ny=StringToInt(y);
|
|
nz=StringToInt(z);
|
|
ndx=StringToInt(dx);
|
|
ndy=StringToInt(dy);
|
|
ndz=StringToInt(dz);
|
|
if (oArea!=oDest)
|
|
{ // separate areas
|
|
if (nz!=ndz)
|
|
{ // deal with Z axis first
|
|
if (ndz>nz)
|
|
{ // need to go up
|
|
if (fnCanGoDirection(oArea,DIR_UP)!="NA")
|
|
return DIR_UP;
|
|
else { // find nearby up location
|
|
sName=fnCanGoDirection(oArea,DIR_NORTH);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_UP)!="NA")
|
|
return DIR_NORTH;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_SOUTH);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_UP)!="NA")
|
|
return DIR_SOUTH;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_EAST);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_UP)!="NA")
|
|
return DIR_EAST;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_WEST);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_UP)!="NA")
|
|
return DIR_WEST;
|
|
} // test this direction
|
|
return d6(); // random direction
|
|
} // find nearby up location
|
|
} // need to go up
|
|
else
|
|
{ // need to go down
|
|
if (fnCanGoDirection(oArea,DIR_DOWN)!="NA")
|
|
return DIR_DOWN;
|
|
else { // find nearby down location
|
|
sName=fnCanGoDirection(oArea,DIR_NORTH);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_DOWN)!="NA")
|
|
return DIR_NORTH;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_SOUTH);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_DOWN)!="NA")
|
|
return DIR_SOUTH;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_EAST);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_DOWN)!="NA")
|
|
return DIR_EAST;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_WEST);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_DOWN)!="NA")
|
|
return DIR_WEST;
|
|
} // test this direction
|
|
return d6(); // random direction
|
|
} // find nearby down location
|
|
} // need to go down
|
|
} // deal with Z axis first
|
|
else if (nx!=ndx)
|
|
{ // deal with X axis
|
|
if (ndx>nx)
|
|
{ // need to go east
|
|
if (fnCanGoDirection(oArea,DIR_EAST)!="NA")
|
|
return DIR_EAST;
|
|
else { // find nearby east location
|
|
sName=fnCanGoDirection(oArea,DIR_NORTH);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_EAST)!="NA")
|
|
return DIR_NORTH;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_SOUTH);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_EAST)!="NA")
|
|
return DIR_SOUTH;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_UP);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_EAST)!="NA")
|
|
return DIR_UP;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_DOWN);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_EAST)!="NA")
|
|
return DIR_DOWN;
|
|
} // test this direction
|
|
return d6(); // random direction
|
|
} // find nearby east location
|
|
} // need to go east
|
|
else
|
|
{ // need to go west
|
|
if (fnCanGoDirection(oArea,DIR_WEST)!="NA")
|
|
return DIR_WEST;
|
|
else { // find nearby west location
|
|
sName=fnCanGoDirection(oArea,DIR_NORTH);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_WEST)!="NA")
|
|
return DIR_NORTH;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_SOUTH);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_WEST)!="NA")
|
|
return DIR_SOUTH;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_UP);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_WEST)!="NA")
|
|
return DIR_UP;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_DOWN);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_WEST)!="NA")
|
|
return DIR_DOWN;
|
|
} // test this direction
|
|
return d6(); // random direction
|
|
} // find nearby west location
|
|
} // need to go west
|
|
} // deal with X axis
|
|
else if (ny!=ndy)
|
|
{ // deal with Y axis
|
|
if (ndy>ny)
|
|
{ // need to go south
|
|
if (fnCanGoDirection(oArea,DIR_SOUTH)!="NA")
|
|
return DIR_SOUTH;
|
|
else { // find nearby south location
|
|
sName=fnCanGoDirection(oArea,DIR_EAST);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_SOUTH)!="NA")
|
|
return DIR_EAST;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_WEST);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_SOUTH)!="NA")
|
|
return DIR_WEST;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_UP);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_SOUTH)!="NA")
|
|
return DIR_UP;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_DOWN);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_SOUTH)!="NA")
|
|
return DIR_DOWN;
|
|
} // test this direction
|
|
return d6(); // random direction
|
|
} // find nearby south location
|
|
} // need to go south
|
|
else
|
|
{ // need to go north
|
|
if (fnCanGoDirection(oArea,DIR_NORTH)!="NA")
|
|
return DIR_NORTH;
|
|
else { // find nearby north location
|
|
sName=fnCanGoDirection(oArea,DIR_EAST);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_NORTH)!="NA")
|
|
return DIR_EAST;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_WEST);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_NORTH)!="NA")
|
|
return DIR_WEST;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_UP);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_NORTH)!="NA")
|
|
return DIR_UP;
|
|
} // test this direction
|
|
sName=fnCanGoDirection(oArea,DIR_DOWN);
|
|
oHandle=GetObjectByTag(sName);
|
|
if (oHandle!=OBJECT_INVALID)
|
|
{ // test this direction
|
|
if(fnCanGoDirection(oHandle,DIR_NORTH)!="NA")
|
|
return DIR_DOWN;
|
|
} // test this direction
|
|
return d6(); // random direction
|
|
} // find nearby north location
|
|
} // need to go north
|
|
} // deal with Y axis
|
|
else
|
|
return -1; // error
|
|
} // separate areas
|
|
return nRet;
|
|
} // fnAreaWhichDirection()
|
|
|
|
int fnDirectPathBetween(object oStart,object oEnd)
|
|
{ // find out if there is a direct route between oStart and oEnd
|
|
int nRet=FALSE;
|
|
object oDoor;
|
|
object oTrans;
|
|
int nC=1;
|
|
oDoor=GetNearestObject(OBJECT_TYPE_DOOR,oStart,nC);
|
|
while(oDoor!=OBJECT_INVALID&&nRet==FALSE)
|
|
{ // check doors
|
|
nC++;
|
|
oTrans=GetTransitionTarget(oDoor);
|
|
if (oTrans!=OBJECT_INVALID)
|
|
{
|
|
if (GetArea(oTrans)==oEnd) nRet=TRUE;
|
|
}
|
|
oDoor=GetNearestObject(OBJECT_TYPE_DOOR,oStart,nC);
|
|
} // check doors
|
|
nC=1;
|
|
oDoor=GetNearestObject(OBJECT_TYPE_TRIGGER,oStart,nC);
|
|
while(oDoor!=OBJECT_INVALID&&nRet==FALSE)
|
|
{ // check doors
|
|
nC++;
|
|
oTrans=GetTransitionTarget(oDoor);
|
|
if (oTrans!=OBJECT_INVALID)
|
|
{
|
|
if (GetArea(oTrans)==oEnd) nRet=TRUE;
|
|
}
|
|
oDoor=GetNearestObject(OBJECT_TYPE_TRIGGER,oStart,nC);
|
|
} // check doors
|
|
return nRet;
|
|
} // fnDirectPathBetween()
|
|
|
|
void fnSneak()
|
|
{ // sneaky method
|
|
} // fnSneak()
|
|
|
|
|
|
//====================================================== MAIN ==================
|
|
void main()
|
|
{
|
|
object oMe=OBJECT_SELF;
|
|
object oMDest=GetLocalObject(oMe,"oMainDest"); // main destination
|
|
object oDest=GetLocalObject(oMe,"oDestWP"); // current destination
|
|
int nMM=GetLocalInt(oMe,"nMoveMethod"); // 0 = whatever RUN is set at 1= sneak
|
|
int nRun=GetLocalInt(oMe,"nRun"); // FALSE = WALK, TRUE = RUN
|
|
int nWalk=GetLocalInt(oMe,"nWalkDir"); // move in specific direction
|
|
object oCMNode=GetNearestObjectByTag("FIND_NODE",GetArea(oMe)); // local map node
|
|
object oDMNode=GetNearestObjectByTag("FIND_NODE",GetArea(oMDest));
|
|
int nDir;
|
|
string cx,cy,cz; // current X,Y,Z coordinates
|
|
string dx,dy,dz; // destination X,Y,Z coordinates
|
|
string sMNDown; // down destination
|
|
string sMNUp; // up destination
|
|
string sMNNorth; // North destination
|
|
string sMNSouth; // South destination
|
|
string sMNEast; // East destination
|
|
string sMNWest; // West destination
|
|
string sName; // name stored for FIND_NODES
|
|
string sParse; // used for parsing
|
|
float fDist=GetDistanceBetween(oDest,oMe);
|
|
float fAS=GetLocalFloat(oMe,"fAS");
|
|
int nASC=GetLocalInt(oMe,"nASC");
|
|
sName=GetName(oCMNode); ////// Get X,Y,Z coordinates
|
|
cx=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,cx);
|
|
cy=fnParsePeriod(sName);
|
|
sName=fnRemParsed(sName,cy);
|
|
cz=fnParsePeriod(sName); ////// End X,Y,Z get
|
|
if (nMM==1) fnSneak();
|
|
if (GetArea(oDest)==GetArea(oMe)||fnDirectPathBetween(GetArea(oDest),GetArea(oMe)))
|
|
{ // same area
|
|
if (fDist<3.0&&fDist!=0.0)
|
|
{ // we are there
|
|
if (oDest==oMDest)
|
|
{ // final destination reached
|
|
SetLocalObject(oMe,"oMainDest",OBJECT_INVALID);
|
|
} // final destination reached
|
|
else
|
|
{ // set new destination
|
|
SetLocalObject(oMe,"oDestWP",oMDest);
|
|
} // set new destination
|
|
} // we are there
|
|
else
|
|
{ // check for anti-stuck
|
|
if (fAS==fDist&&fDist!=0.0)
|
|
{ // possibly stuck
|
|
nASC++;
|
|
if (nASC<5)
|
|
{ // gentle prod
|
|
AssignCommand(oMe,ActionMoveToObject(oDest,nRun,2.0));
|
|
} // gentle prod
|
|
else if (nASC==5)
|
|
{ // simple anti-stuck
|
|
oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d4());
|
|
AssignCommand(oMe,ClearAllActions());
|
|
AssignCommand(oMe,ActionMoveToObject(oDest,nRun,3.0));
|
|
DelayCommand(10.0,AssignCommand(oMe,ClearAllActions()));
|
|
} // simple anti-stuck
|
|
else if (nASC==10)
|
|
{ // really stuck TELEPORT
|
|
AssignCommand(oMe,ClearAllActions());
|
|
AssignCommand(oMe,JumpToObject(oDest));
|
|
} // really stuck TELEPORT
|
|
else if (nASC>12)
|
|
{ // get unstuck - just do it
|
|
oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d8());
|
|
AssignCommand(oMe,ClearAllActions());
|
|
AssignCommand(oMe,JumpToObject(oDest));
|
|
} // get unstuck - just do it
|
|
SetLocalInt(oMe,"nASC",nASC);
|
|
} // possibly stuck
|
|
else
|
|
{ // set distance for future AS and set AS counter to 0
|
|
SetLocalInt(oMe,"nASC",0);
|
|
SetLocalFloat(oMe,"fAS",fDist);
|
|
AssignCommand(oMe,ActionMoveToObject(oDest,nRun,2.0));
|
|
} // set distance for future AS and set AS counter to 0
|
|
} // check for anti-stuck
|
|
} // same area
|
|
else
|
|
{ // different area
|
|
fDist=GetDistanceBetween(oMe,oCMNode);
|
|
if (fDist==fAS)
|
|
{ // possibly stuck
|
|
nASC++;
|
|
if (nASC==5)
|
|
{ // simple anti-stuck
|
|
oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d4());
|
|
AssignCommand(oMe,ClearAllActions());
|
|
AssignCommand(oMe,ActionMoveToObject(oDest,nRun,3.0));
|
|
DelayCommand(10.0,AssignCommand(oMe,ClearAllActions()));
|
|
} // simple anti-stuck
|
|
else if (nASC==10)
|
|
{ // really stuck TELEPORT
|
|
AssignCommand(oMe,ClearAllActions());
|
|
AssignCommand(oMe,JumpToObject(oDest));
|
|
} // really stuck TELEPORT
|
|
else if (nASC>12)
|
|
{ // get unstuck - just do it
|
|
oDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d8());
|
|
AssignCommand(oMe,ClearAllActions());
|
|
AssignCommand(oMe,JumpToObject(oDest));
|
|
} // get unstuck - just do it
|
|
SetLocalInt(oMe,"nASC",nASC);
|
|
} // possibly stuck
|
|
else
|
|
{ // not stuck
|
|
SetLocalInt(oMe,"nASC",0);
|
|
SetLocalFloat(oMe,"fAS",fDist);
|
|
nDir=fnAreaWhichDirection(oCMNode,oDMNode);
|
|
if (nDir==0)
|
|
{ // should be there
|
|
SetLocalObject(oMe,"oDestWP",oMDest);
|
|
} // should be there
|
|
else if (nDir==-1)
|
|
{ // error
|
|
} // error
|
|
else
|
|
{ // go that way
|
|
sName=fnCanGoDirection(GetArea(oMe),nDir);
|
|
oDest=GetObjectByTag(sName);
|
|
if (oDest!=OBJECT_INVALID)
|
|
{ // go to that area
|
|
oMDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oDest,d8());
|
|
while(oMDest==OBJECT_INVALID)
|
|
oMDest=GetNearestObject(OBJECT_TYPE_WAYPOINT,oDest,d8());
|
|
SetLocalObject(oMe,"oDestWP",oMDest);
|
|
} // go to that area
|
|
else
|
|
{
|
|
fnError(GetName(GetArea(oMe))+" pathing error direction: "+IntToString(nDir));
|
|
}
|
|
} // go that way
|
|
} // not stuck
|
|
} // different area
|
|
}
|