200 lines
7.9 KiB
Plaintext
200 lines
7.9 KiB
Plaintext
// ai_harvester - Challenging AI harvesting unit
|
|
#include "ai_header2"
|
|
#include "antistuck_h"
|
|
|
|
/////////////////////////////////////////////////////////////////////// MAIN
|
|
void main()
|
|
{
|
|
object oMe=OBJECT_SELF;
|
|
int nState=GetLocalInt(oMe,"nSState");
|
|
string sID=GetLocalString(oMe,"sTeamID");
|
|
string sTagMP1="MinorManaPool";
|
|
string sTagMP2="ManaPool";
|
|
string sTagMP5="StrongManaPool";
|
|
string sTagMC1="MANA_CRYSTAL_1";
|
|
string sTagMC2="MANA_CRYSTAL_2";
|
|
string sTagMC5="MANA_CRYSTAL_5";
|
|
object oItem=GetLocalObject(oMe,"oItem");
|
|
object oDest=GetLocalObject(oMe,"oDestWP");
|
|
object oOb;
|
|
object oTarget;
|
|
object oStart=GetWaypointByTag(sID+"_START");
|
|
object oVault=GetObjectByTag(sID+"_VAULT");
|
|
object oMod=GetModule();
|
|
int nErr;
|
|
int nHas=FALSE;
|
|
float fDist;
|
|
int nR;
|
|
//AssignCommand(oMe,SpeakString("*hu "+IntToString(nState)+"*"));
|
|
if (GetItemPossessedBy(OBJECT_SELF,sTagMC1)!=OBJECT_INVALID) nHas=TRUE;
|
|
if (GetItemPossessedBy(OBJECT_SELF,sTagMC2)!=OBJECT_INVALID) nHas=TRUE;
|
|
if (GetItemPossessedBy(OBJECT_SELF,sTagMC5)!=OBJECT_INVALID) nHas=TRUE;
|
|
switch(nState)
|
|
{ // sub-state
|
|
case 0: { // leave lair
|
|
if (oDest==OBJECT_INVALID)
|
|
{ // pick a destination outside the lair
|
|
if (sID=="SPID") oDest=GetWaypointByTag("AIPATH32");
|
|
else if (sID=="UND") oDest=GetWaypointByTag("AIPATH23");
|
|
else if (sID=="UNC") oDest=GetWaypointByTag("AIPATH21");
|
|
else if (sID=="DWF") oDest=GetWaypointByTag("AIPATH12");
|
|
SetLocalObject(oMe,"oDestWP",oDest);
|
|
AssignCommand(oMe,ClearAllActions());
|
|
AssignCommand(oMe,ActionForceMoveToObject(oDest,TRUE,1.0,90.0));
|
|
} // pick a destination outside the lair
|
|
if (GetArea(oMe)!=GetArea(oStart)) nState=1;
|
|
break;
|
|
} // leave lair
|
|
case 1: { // choose action 0=search in this area, 1 = move on
|
|
oOb=GetNearestObjectByTag(sTagMP5,oMe,1);
|
|
if (oOb==OBJECT_INVALID) oOb=GetNearestObjectByTag(sTagMP2,oMe,1);
|
|
if (oOb==OBJECT_INVALID) oOb=GetNearestObjectByTag(sTagMP1,oMe,1);
|
|
if (oOb==OBJECT_INVALID) oOb=GetNearestObjectByTag(sTagMC5,oMe,1);
|
|
if (oOb==OBJECT_INVALID) oOb=GetNearestObjectByTag(sTagMC2,oMe,1);
|
|
if (oOb==OBJECT_INVALID) oOb=GetNearestObjectByTag(sTagMC1,oMe,1);
|
|
if (oOb==OBJECT_INVALID||fDist>40.0)
|
|
{ // pick what to do
|
|
nR=d6();
|
|
if (nR<3) nState=2;
|
|
else { nState=3; }
|
|
} // pick what to do
|
|
else
|
|
{ // found something act on it
|
|
SetLocalObject(oMe,"oItem",oOb);
|
|
if (GetObjectType(oOb)==OBJECT_TYPE_PLACEABLE) nState=4;
|
|
else { nState=5; }
|
|
} // found something act on it
|
|
break;
|
|
} // choose action 0 = search in this area, 1 = move on
|
|
case 2: { // search in this area
|
|
if (oDest==OBJECT_INVALID)
|
|
{
|
|
oOb=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d20());
|
|
if (oOb==OBJECT_INVALID) oOb=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d12());
|
|
if (oOb==OBJECT_INVALID) oOb=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d10());
|
|
if (oOb==OBJECT_INVALID) oOb=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d8());
|
|
if (oOb==OBJECT_INVALID) oOb=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d6());
|
|
if (oOb==OBJECT_INVALID) oOb=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,d4());
|
|
if (oOb==OBJECT_INVALID) oOb=GetNearestObject(OBJECT_TYPE_WAYPOINT,oMe,1);
|
|
if (oOb!=OBJECT_INVALID)
|
|
{ // waypoint found
|
|
SetLocalObject(oMe,"oDestWP",oOb);
|
|
} // waypoint found
|
|
}
|
|
else
|
|
{ // move
|
|
nErr=fnMoveToDestination(oDest,TRUE);
|
|
if (nErr==-1) { AssignCommand(oMe,JumpToObject(oDest)); nState=1; DeleteLocalObject(oMe,"oDestWP"); }
|
|
else if (nErr==1||GetDistanceBetween(oMe,oDest)<1.0) { nState=1; DeleteLocalObject(oMe,"oDestWP");}
|
|
} // move
|
|
break;
|
|
} // search in this area
|
|
case 3: { // move on
|
|
if (oDest==OBJECT_INVALID)
|
|
{ // find transition
|
|
oOb=fnFindSafeTransition();
|
|
if (oOb==OBJECT_INVALID) { nState=1; DeleteLocalObject(oMe,"oDestWP"); }
|
|
else
|
|
{ SetLocalObject(oMe,"oDestWP",oOb); }
|
|
} // find transition
|
|
else
|
|
{ // move to transition
|
|
nErr=fnMoveToDestination(oDest,TRUE);
|
|
if (nErr==-1) { AssignCommand(oMe,JumpToObject(oDest));}
|
|
if (nErr==1||nErr==-1||(GetArea(oDest)==GetArea(oMe)&&GetDistanceBetween(oMe,oDest)<3.0))
|
|
{ // arrived
|
|
nState=1; DeleteLocalObject(oMe,"oDestWP");
|
|
} // arrived
|
|
} // move to transition
|
|
break;
|
|
} // move on
|
|
case 4: { // harvest mana pool
|
|
if (GetDistanceBetween(oMe,oItem)>1.9) nErr=fnMoveToDestination(oItem,TRUE);
|
|
if (nErr==-1)
|
|
{
|
|
AssignCommand(oMe,JumpToObject(oItem));
|
|
AssignCommand(oMe,ActionMoveAwayFromObject(oItem,TRUE,3.0));
|
|
}
|
|
else if (oItem!=OBJECT_INVALID&&(nErr==1||GetDistanceBetween(oMe,oItem)<2.0))
|
|
{ // harvest
|
|
AssignCommand(oMe,ActionMoveToObject(oItem));
|
|
AssignCommand(oMe,ActionInteractObject(oItem));
|
|
AssignCommand(oMe,ActionDoCommand(SetLocalInt(oMe,"nSState",6)));
|
|
nState=7;
|
|
} // harvest
|
|
else if (oItem==OBJECT_INVALID) { DeleteLocalObject(oMe,"oItem"); nState=1; }
|
|
break;
|
|
} // harvest mana pool
|
|
case 5: { // pickup mana crystal
|
|
if (oItem!=OBJECT_INVALID)
|
|
{ // item exists
|
|
if (GetItemPossessor(oItem)==oMe) nState=6;
|
|
else if (GetItemPossessor(oItem)!=OBJECT_INVALID)
|
|
{ // someone else got it
|
|
DeleteLocalObject(oMe,"oItem"); nState=1;
|
|
} // someone else got it
|
|
else if (GetDistanceBetween(oMe,oItem)<3.0) { // pick it up
|
|
AssignCommand(oMe,ClearAllActions());
|
|
AssignCommand(oMe,ActionMoveToObject(oItem));
|
|
AssignCommand(oMe,ActionPickUpItem(oItem));
|
|
} // pick it up
|
|
else
|
|
{
|
|
nErr=fnMoveToDestination(oItem,TRUE);
|
|
}
|
|
} // item exists
|
|
else { DeleteLocalObject(oMe,"oItem"); nState=1; }
|
|
break;
|
|
} // pickup mana crystal
|
|
case 6: { // return to lair
|
|
nErr=0;
|
|
if (GetArea(oMe)!=GetArea(oVault))
|
|
{
|
|
if (sID=="SPID") nErr=3;
|
|
else if (sID=="DWF") nErr=2;
|
|
else if (sID=="UNC") nErr=1;
|
|
else if (sID=="UND") nErr=3;
|
|
if (GetIsDay()==TRUE&&GetLocalInt(oMod,GetResRef(oMe)+"_light")==2) nErr=4; // light fatal
|
|
SetLocalInt(oMe,"nRun",TRUE);
|
|
oDest=fnPathNextDestination(GetArea(oMe),sID,nErr);
|
|
nErr=fnMoveToDestination(oDest,TRUE);
|
|
if (nErr==-1) { AssignCommand(oMe,ClearAllActions()); AssignCommand(oMe,JumpToObject(oStart)); }
|
|
}
|
|
else
|
|
{ // deposit mana
|
|
nState=13;
|
|
SetLocalInt(oMe,"nSState",13);
|
|
} // deposit mana
|
|
break;
|
|
} // return to lair
|
|
case 7: { // null state
|
|
break;
|
|
} // null state
|
|
case 13: { // deliver up the crystal
|
|
fDist=GetDistanceBetween(oMe,oVault);
|
|
if ((fDist==0.0&&GetArea(oVault)!=GetArea(OBJECT_SELF))||fDist>1.5)
|
|
{ // move
|
|
nErr=fnMoveToDestination(oVault,TRUE);
|
|
if (nHas==FALSE)
|
|
{ // delivered
|
|
SetLocalInt(oMe,"nSState",0);
|
|
DeleteLocalObject(oMe,"oDestWP");
|
|
nState=0;
|
|
} // delivered
|
|
} // move
|
|
else if (nHas==TRUE)
|
|
{ // move away and try again
|
|
AssignCommand(oMe,ClearAllActions());
|
|
AssignCommand(oMe,ActionMoveAwayFromObject(oVault,TRUE,8.0));
|
|
} // move away and try again
|
|
break;
|
|
} // deliver up the crystal
|
|
default: break;
|
|
} // sub-state
|
|
SetLocalInt(oMe,"nSState",nState);
|
|
}
|
|
/////////////////////////////////////////////////////////////////////// MAIN
|
|
|
|
|
|
|