// 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