// ai_itemcollect - Challenging AI item collecting unit #include "ai_header2" void fnFoundMercLord(int nNum,string sTeamID,object oML); int fnIsManaObject(object oItem) { // return true if mana crystal int nRet=FALSE; string sRes=GetResRef(oItem); if (sRes=="mana_crystal_5"||sRes=="mana_crystal_2"||sRes=="mana_crystal_1") nRet=TRUE; return nRet; } // fnIsManaObject() int fnIsSoulObject(object oItem) { // return true if is soul token int nRet=FALSE; string sRes=GetResRef(oItem); if (sRes=="soultoken") nRet=TRUE; return nRet; } // fnIsSoulObject() void fnDestroyContainer(object oContainer) { // empty items object oItem=GetFirstItemInInventory(oContainer); while(oItem!=OBJECT_INVALID) { DelayCommand(0.2,DestroyObject(oItem)); oItem=GetNextItemInInventory(oContainer); } DelayCommand(0.3,DestroyObject(oContainer)); } // fnDestroyContainer() /////////////////////////////////////////////////////////////////////// MAIN void main() { object oMe=OBJECT_SELF; int nState=GetLocalInt(oMe,"nSState"); string sID=GetLocalString(oMe,"sTeamID"); object oItem=GetLocalObject(oMe,"oItem"); object oDest=GetLocalObject(oMe,"oDestWP"); object oOb; object oTarget; string sRes; string sTag; string sSoulToken=""; object oStart=GetWaypointByTag(sID+"_START"); object oVault=GetObjectByTag(sID+"_STORAGE"); object oMod=GetModule(); int nErr; int nHas=FALSE; float fDist; int nMLN; int nR; //AssignCommand(oMe,SpeakString("*nSState="+IntToString(nState)+"["+sID+"]*")); 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); nErr=fnMoveToDestination(oDest); } // pick a destination outside the lair if (GetArea(oMe)==GetArea(oDest)&&oDest!=OBJECT_INVALID) nState=1; else { nErr=fnMoveToDestination(oDest); } break; } // leave lair case 1: { // choose action 0=search in this area, 1 = move on nR=1; oOb=GetNearestObject(OBJECT_TYPE_ITEM,oMe,nR); fDist=GetDistanceBetween(oMe,oOb); oTarget=OBJECT_INVALID; while(oOb!=OBJECT_INVALID&&fDist<20.0&&oTarget==OBJECT_INVALID) { // look for item if (GetPlotFlag(oOb)==FALSE&&fnIsSoulObject(oOb)==FALSE&&fnIsManaObject(oOb)==FALSE) oTarget=oOb; nR++; oOb=GetNearestObject(OBJECT_TYPE_ITEM,oMe,nR); fDist=GetDistanceBetween(oMe,oOb); } // look for item if (oTarget==OBJECT_INVALID) { // look for containers nR=1; oOb=GetNearestObject(OBJECT_TYPE_PLACEABLE,oMe,nR); fDist=GetDistanceBetween(oMe,oOb); while(oOb!=OBJECT_INVALID&&fDist<20.0&&oTarget==OBJECT_INVALID) { // look for bodies if (GetHasInventory(oOb)==TRUE) oTarget=oOb; nR++; oOb=GetNearestObject(OBJECT_TYPE_PLACEABLE,oMe,nR); fDist=GetDistanceBetween(oMe,oOb); } // look for bodies } // look for containers if (oTarget==OBJECT_INVALID) { // did not find a target if (d6()<5) {nState=2; DeleteLocalObject(oMe,"oDestWP"); } else { nState=3; DeleteLocalObject(oMe,"oDestWP"); } } // did not find a target else { // found something act on it SetLocalObject(oMe,"oItem",oTarget); if (GetObjectType(oTarget)==OBJECT_TYPE_ITEM) 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) { // 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.5) { 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: { // destroy item fDist=GetDistanceBetween(oMe,oItem); if (fDist>1.5&&GetItemPossessor(oItem)==OBJECT_INVALID) { // move to object nErr=fnMoveToDestination(oItem,TRUE); if (nErr==-1) { AssignCommand(oMe,ClearAllActions()); nState=1; } } // move to object else { // should be at item DestroyObject(oItem); DeleteLocalObject(oMe,"oItem"); nState=1; } // should be at item break; } // destroy item case 5: { // destroy container if (oItem!=OBJECT_INVALID) { // item exists fDist=GetDistanceBetween(oMe,oItem); if (fDist>1.5) { nErr=fnMoveToDestination(oItem,TRUE); } else { fnDestroyContainer(oItem); DeleteLocalObject(oMe,"oItem"); nState=1; } } // item exists else { DeleteLocalObject(oMe,"oItem"); nState=1; } break; } // destroy container 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 CreateItemOnObject(GetResRef(oItem),oVault,GetItemStackSize(oItem)); DestroyObject(oItem); nState=0; } // move away and try again break; } // deliver up the crystal default: break; } // sub-state SetLocalInt(oMe,"nSState",nState); } /////////////////////////////////////////////////////////////////////// MAIN void fnFoundMercLord(int nNum,string sTeamID,object oML) { object oMod=GetModule(); int nC1=GetLocalInt(oML,"nMer1"); int nC2=GetLocalInt(oML,"nMer2"); string sS; int nN; float fF; object oC; object oWP=GetWaypointByTag(sTeamID+"_RESOURCES"); SetLocalObject(oMod,"oMerL"+IntToString(nNum)+sTeamID,oML); sS="MER"+IntToString(nC1); oC=CreateObject(OBJECT_TYPE_CREATURE,sS,GetLocation(oWP)); fF=GetChallengeRating(oC); if (fF<1.0) fF=fF*60.0; else { fF=fF*fF*30.0; } nN=FloatToInt(fF); SetLocalString(oMod,"sMerL"+IntToString(nNum)+"_1",sS); SetLocalInt(oMod,"nMercLC"+IntToString(nNum)+"_1",nN); DestroyObject(oC); sS="MER"+IntToString(nC2); oC=CreateObject(OBJECT_TYPE_CREATURE,sS,GetLocation(oWP)); fF=GetChallengeRating(oC); if (fF<1.0) fF=fF*60.0; else { fF=fF*fF*30.0; } nN=FloatToInt(fF); SetLocalString(oMod,"sMerL"+IntToString(nNum)+"_2",sS); SetLocalInt(oMod,"nMercLC"+IntToString(nNum)+"_2",nN); DestroyObject(oC); } // fnFoundMercLord()