HoS_PRC8/_mod/_module/nss/rts_wp_header.nss

282 lines
8.8 KiB
Plaintext
Raw Permalink Normal View History

2024-11-25 19:36:07 -05:00
////////////////////////////////////////////////////////////////////////
// Waypoint Pathing System
// By Deva Bryson Winblood 12/01/2003
////////////////////////////////////////////////////////////////////////
// Pathing works exclusively between lairs with exception of option 4
void fnBuildTransRand(object oArea)
{ // build a list of transitions from this area
int nC=0;
int nL=1;
object oFirst=GetFirstObjectInArea(oArea);
object oTrans;
oFirst=GetNearestObject(OBJECT_TYPE_WAYPOINT,oFirst,1);
//SendMessageToPC(GetFirstPC(),"fnBuildTransRand()");
if (oFirst!=OBJECT_INVALID)
{
oTrans=GetNearestObject(OBJECT_TYPE_TRIGGER,oFirst,nL);
while(oTrans!=OBJECT_INVALID)
{ // triggers
if(GetTransitionTarget(oTrans)!=OBJECT_INVALID)
{ // transition
nC++;
SetLocalObject(oArea,"oPathingTrans"+IntToString(nC),oTrans);
} // transition
nL++;
oTrans=GetNearestObject(OBJECT_TYPE_TRIGGER,oFirst,nL);
} // triggers
nL=1;
oTrans=GetNearestObject(OBJECT_TYPE_DOOR,oFirst,nL);
while(oTrans!=OBJECT_INVALID)
{ // doors
if(GetTransitionTarget(oTrans)!=OBJECT_INVALID)
{ // transition
nC++;
SetLocalObject(oArea,"oPathingTrans"+IntToString(nC),oTrans);
} // transition
nL++;
oTrans=GetNearestObject(OBJECT_TYPE_DOOR,oFirst,nL);
} // doors
SetLocalInt(oArea,"nPathingTC",nC);
}
else
{
AssignCommand(OBJECT_SELF,SpeakString("This area is impossible to escape!!!"));
SendMessageToPC(GetFirstPC(),"RTS SETUP ERROR: Area "+GetName(oArea)+" has no transitions!");
}
} // fnBuildTransRand()
void fnBuildObjectRand(object oArea)
{ // build a list of objects
int nC=0;
int nL=1;
object oFirst=GetFirstObjectInArea(oArea);
object oTrans;
//SendMessageToPC(GetFirstPC(),"fnBuildObjectRand()");
oFirst=GetNearestObject(OBJECT_TYPE_WAYPOINT,oFirst,1);
if (oFirst!=OBJECT_INVALID)
{
oTrans=GetNearestObject(OBJECT_TYPE_PLACEABLE,oFirst,nL);
while(oTrans!=OBJECT_INVALID)
{ // placeables
nC++;
SetLocalObject(oArea,"oPathingObs"+IntToString(nC),oTrans);
nL++;
oTrans=GetNearestObject(OBJECT_TYPE_PLACEABLE,oFirst,nL);
} // placeables
nL=1;
oTrans=GetNearestObject(OBJECT_TYPE_WAYPOINT,oFirst,nL);
while(oTrans!=OBJECT_INVALID)
{ // waypoints
nC++;
SetLocalObject(oArea,"oPathingObs"+IntToString(nC),oTrans);
nL++;
oTrans=GetNearestObject(OBJECT_TYPE_WAYPOINT,oFirst,nL);
} // waypoints
nC++;
SetLocalObject(oArea,"oPathingObs"+IntToString(nC),oFirst);
SetLocalInt(oArea,"nPathingOC",nC);
}
} // fnBuildObjectRand()
int fnPathValue(object oArea,string sID)
{ // returns path value for area based on team
int nRet=1000; // 1000 = avoid it!
object oFirst=GetFirstObjectInArea(oArea);
object oWP=GetNearestObjectByTag("PATHINGA",oFirst,1);
string sName;
int nPos;
string sL;
if (oWP==OBJECT_INVALID) oWP=GetNearestObjectByTag("PATHINGB",oFirst,1);
if (oWP==OBJECT_INVALID)
{ // check to see if the first object was the waypoint
if(GetTag(oFirst)=="PATHINGA"||GetTag(oFirst)=="PATHINGB") oWP=oFirst;
} // check to see if the first object was the waypoint
if (oWP!=OBJECT_INVALID)
{ //!OI
sName=GetName(oWP);
if (sName!="AVOID")
{ // !AVOID
if (sID=="UND") nPos=0;
else if (sID=="UNC") nPos=1;
else if (sID=="SPID") nPos=2;
else if (sID=="DWF") nPos=3;
sL=GetSubString(sName,nPos,1);
if (sL=="A") nRet=10;
else if (sL=="B") nRet=11;
else if (sL=="C") nRet=12;
else
{
nRet=StringToInt(sL);
}
} // !AVOID
} //!OI
return nRet;
} // fnPathValue()
object fnGetTransition(object oArea,int nNum)
{ // returns the specified transition object
object oTrans=OBJECT_INVALID;
oTrans=GetLocalObject(oArea,"oPathingTrans"+IntToString(nNum));
return oTrans;
} // fnGetTransition()
int fnIsAboveGroundDestination(object oTrans)
{ // does this transition lead to an above ground location
int nRet=FALSE;
object oDest=GetTransitionTarget(oTrans);
object oFirst=GetFirstObjectInArea(GetArea(oTrans));
if (GetTag(oFirst)=="PATHINGA") nRet=TRUE;
else
{ // test
oDest=GetNearestObjectByTag("PATHINGA",oFirst,1);
if (oDest!=OBJECT_INVALID) nRet=TRUE;
} // test
return nRet;
} // fnIsAboveGroundDestination()
object fnPathNextDestination(object oCurrentArea,string sDestID,int nOpt=0)
{ /* Find an object in next destination and return it
OPTIONS: 0 = Path choosing preferably the same area type as current
1 = Path choosing preferably underground ways
2 = Path choosing preferably aboveground ways
3 = Path choosing below ground during day, above ground at night
4 = Below ground a MUST! Also seek below ground shelter
NOTE: the above ground areas are generally less cluttered and thus offer
faster travel. So, option 3 is best for creatures with low light sensitivity.
Option 4 is suggested for light fatal creatures DURING THE day
*/
object oRet=OBJECT_INVALID;
int nCurrentPos=fnPathValue(oCurrentArea,sDestID);
object oBest=OBJECT_INVALID;
int nBest=100;
object oNonPref=OBJECT_INVALID;
int nNonPref=101;
int nL;
int nCur;
object oTrans;
object oDest;
int nC=GetLocalInt(oCurrentArea,"nPathingTC");
if (nC==0)
{ // need to build pathing info
fnBuildTransRand(oCurrentArea);
nC=GetLocalInt(oCurrentArea,"nPathingTC");
} // need to builg pathing info
nL=1;
while(nL<=nC)
{ // test transitions
oTrans=fnGetTransition(oCurrentArea,nL);
oDest=GetTransitionTarget(oTrans);
nCur=fnPathValue(GetArea(oDest),sDestID);
if (nCur<nBest||(nCur==nBest&&d4()<3))
{ // might be a good destination
if (nOpt==0)
{ // whatever works
nBest=nCur;
oBest=oDest;
} // whatever works
else if (nOpt==1)
{ // prefer underground
if (fnIsAboveGroundDestination(oTrans)==TRUE)
{ // above ground
if (nCur<=nNonPref)
{ // set nonpref
nNonPref=nCur;
oNonPref=oDest;
} // set nonpref
} // above ground
else
{ // below ground
nBest=nCur;
oBest=oDest;
} // below ground
} // prefer underground
else if (nOpt==2)
{ // prefer aboveground
if (fnIsAboveGroundDestination(oTrans)==TRUE)
{ // above ground
nBest=nCur;
oBest=oDest;
} // above ground
else
{ // below ground
if (nCur<nNonPref||(nCur==nNonPref&&d4()<3))
{ // set nonpref
nNonPref=nCur;
oNonPref=oDest;
} // set nonpref
} // below ground
} // prefer aboveground
else if (nOpt==3)
{ // day/night preference
if (GetIsDay()==TRUE||GetIsDawn()==TRUE)
{ // day time
if (fnIsAboveGroundDestination(oTrans)==TRUE)
{ // above ground
if (nCur<nNonPref||(nCur==nNonPref&&d4()<3))
{ // set nonpref
nNonPref=nCur;
oNonPref=oDest;
} // set nonpref
} // above ground
else
{ // below ground
nBest=nCur;
oBest=oDest;
} // below ground
} // day time
else
{ // night time
if (fnIsAboveGroundDestination(oTrans)==TRUE)
{ // above ground
nBest=nCur;
oBest=oDest;
} // above ground
else
{ // below ground
if (nCur<nNonPref||(nCur==nNonPref&&d4()<3))
{ // set nonpref
nNonPref=nCur;
oNonPref=oDest;
} // set nonpref
} // below ground
} // night time
} // day/night preference
else if (nOpt==4)
{ // if day MUST use below ground
if (GetIsDay()==TRUE||GetIsDawn()==TRUE)
{
if (fnIsAboveGroundDestination(oTrans)==FALSE)
{ // good destination
oBest=oDest;
nBest=nCur;
} // good destination
}
else
{ // any will do
oBest=oDest;
nBest=nCur;
} // any will do
} // if day MUST use below ground
} // might be a good destination
nL++;
} // test transitions
if (nNonPref<nBest)
{ // use non-prefered
oDest=oNonPref;
} // use non-prefered
else
{ // use the best
oDest=oBest;
} // use the best
if (oDest!=OBJECT_INVALID)
{ // choose nearby dest
oTrans=GetNearestObject(OBJECT_TYPE_WAYPOINT,oDest,d4());
if (oTrans==OBJECT_INVALID) oTrans=GetNearestObject(OBJECT_TYPE_WAYPOINT,oDest,1);
if (oTrans==OBJECT_INVALID) oTrans=GetNearestObject(OBJECT_TYPE_PLACEABLE,oDest,1);
oRet=oTrans;
} // choose nearby dest
return oRet;
} // fnPathNextDestination()