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