////////////////////////////////////////////////////////////////////////////////
// ai_merchanth - Merchant Helper AI from the Lair Add-On for Merchants
//------------------------------------------------------------------------------
// By Deva B. Winblood.   Sept, 22nd.   2008
////////////////////////////////////////////////////////////////////////////////

#include "lib_hos2_shpath"
#include "rts_pathing"
#include "rts_header"
#include "antistuck_h"

/////////////////////////////
// FUNCTIONS
/////////////////////////////


object fnFindAGO(string sTeamID)
{ // PURPOSE: Find destination
    object oRet=OBJECT_INVALID;
    string sTag;
    if (sTeamID=="UND") sTag="HALL_AGS";
    else if (sTeamID=="DWF") sTag="HALL_AGW";
    else if (sTeamID=="UNC") sTag="HALL_AGN";
    else if (sTeamID=="SPID") sTag="HALL_AGE";
    oRet=GetWaypointByTag(sTag);
    return oRet;
} // fnFindAGO()


object fnFindBGO(string sTeamID)
{ // PURPOSE: Find destination
    object oRet=OBJECT_INVALID;
    string sTag;
    if (sTeamID=="UND") sTag="HALL_BGS";
    else if (sTeamID=="DWF") sTag="HALL_BGW";
    else if (sTeamID=="UNC") sTag="HALL_BGN";
    else if (sTeamID=="SPID") sTag="HALL_BGE";
    oRet=GetWaypointByTag(sTag);
    return oRet;
} // fnFindBGO()


object fnFindFar(string sTeamID)
{ // PURPOSE: Find far destination
    object oRet=OBJECT_INVALID;
    string sTag;
    if (sTeamID=="UND") sTag="HALL_BGC";
    else if (sTeamID=="DWF") sTag="DJINN_CITY";
    else if (sTeamID=="UNC") sTag="HALL_BGC";
    else if (sTeamID=="SPID") sTag="HALL_BGC";
    oRet=GetWaypointByTag(sTag);
    return oRet;
} // fnFindFar()


object fnFindIntermediate(string sTeamID)
{ // PURPOSE: Return Intermediate
    object oRet=OBJECT_INVALID;
    string sTag;
    if (sTeamID=="UND") sTag="HALL_BGS";
    else if (sTeamID=="DWF") sTag="HALL_AGW";
    else if (sTeamID=="UNC") sTag="HALL_BGN";
    else if (sTeamID=="SPID") sTag="HALL_BGE";
    oRet=GetWaypointByTag(sTag);
    return oRet;
} // fnFindIntermediate()




/////////////////////////////////////////////////////////[== MAIN ==]///////////
void main()
{
   object oMe=OBJECT_SELF;
   int nSState=GetLocalInt(oMe,"nSState");
   object oWP;
   string sTeamID=GetLocalString(oMe,"sTeamID");
   object oItem;
   object oCreature;
   object oFound;
   int nN;
   switch(nSState)
   { // sub-state
       case 0: { // In Lair - pick destination
           int nR=d6();
           if (nR<3) SetLocalInt(oMe,"nSState",1);
           else if (nR<5) SetLocalInt(oMe,"nSState",2);
           else { SetLocalInt(oMe,"nSState",3); }
           DeleteLocalInt(oMe,"nParm"); // used to track amount of seeking
           break;
       } // In Lair - pick destination
       case 1: { // Move to Above Ground Outside
           oWP=fnFindAGO(sTeamID);
           if (GetArea(oWP)!=GetArea(oMe))
           { // move
               MoveToObject(oMe,oWP,TRUE);
           } // move
           else
           { // switch state
               SetLocalInt(oMe,"nSState",4);
           } // switch state
           break;
       } // Move to above Ground Outside
       case 2: { // Move to Below Ground Outside
           oWP=fnFindBGO(sTeamID);
           if (GetArea(oWP)!=GetArea(oMe))
           { // move
               MoveToObject(oMe,oWP,TRUE);
           } // move
           else
           { // switch state
               SetLocalInt(oMe,"nSState",4);
           } // switch state
           break;
       } // Move to Below Ground Outside
       case 3: { // Move to far destination
           oWP=fnFindFar(sTeamID);
           if (GetArea(oWP)==GetArea(oMe))
           { // arrived - switch state
               SetLocalInt(oMe,"nSState",4);
           } // arrived - switch state
           else
           { // move transition
               oWP=fnFindIntermediate(sTeamID);
               if (GetArea(oWP)==GetArea(oMe))
               { // move to final destination
                   oWP=fnFindFar(sTeamID);
                   MoveToObject(oMe,oWP,TRUE);
               } // move to final destination
               else
               { // move
                   MoveToObject(oMe,oWP,TRUE);
               } // move
           } // move transition
           break;
       } // Move to far destination
       case 4: { // Seek Nearby things to pick up
           nN=GetLocalInt(oMe,"nParm");
           if (nN<10)
           { // seek
               nN=1;
               oFound=OBJECT_INVALID;
               oItem=GetNearestObject(OBJECT_TYPE_ITEM,oMe,nN);
               while(GetIsObjectValid(oItem)&&!GetIsObjectValid(oFound))
               { // seek item
                   oCreature=GetNearestCreature(CREATURE_TYPE_IS_ALIVE,TRUE,oItem,1);
                   if (GetIsObjectValid(oCreature)&&(GetDistanceBetween(oCreature,oItem)>4.0||!GetIsEnemy(oCreature,oMe))) oFound=oItem;
                   nN++;
                   oItem=GetNearestObject(OBJECT_TYPE_ITEM,oMe,nN);
               } // seek item
               if (GetIsObjectValid(oFound))
               { // go pick up
                   SetLocalObject(oMe,"oFound",oItem);
                   SetLocalInt(oMe,"nSState",5);
               } // go pick up
               else
               { // return to lair
                   SetLocalInt(oMe,"nSState",6);
               } // return to lair
           } // seek
           else { SetLocalInt(oMe,"nSState",6); }
           break;
       } // Seek Nearby things to pick up
       case 5: { // Pickup items
           oItem=GetLocalObject(oMe,"oFound");
           if (GetIsObjectValid(oItem))
           { // item still exists
               oCreature=GetItemPossessor(oItem);
               if (GetObjectType(oCreature)==OBJECT_TYPE_CREATURE)
               { // picked up
                   if (oCreature==oMe) SetLocalInt(oItem,"bPickedup",TRUE);
                   nN=GetLocalInt(oMe,"nParm");
                   SetLocalInt(oMe,"nParm",nN+1);
                   SetLocalInt(oMe,"nSState",4);
               } // picked up
               else if (GetDistanceBetween(oMe,oItem)<1.2)
               { // Pick it up
                   AssignCommand(oMe,ClearAllActions());
                   AssignCommand(oMe,ActionPickUpItem(oItem));
               } // Pick it up
               else
               { // move to the object
                   nN=MoveToObject(oMe,oItem,TRUE,1.0);
               } // move to the object
           } // item still exists
           else
           { // does not exist
               nN=GetLocalInt(oMe,"nParm");
               SetLocalInt(oMe,"nParm",nN+1);
               SetLocalInt(oMe,"nSState",4);
           } // does not exist
           break;
       } // Pickup items
       case 6: { // Return to lair
           int nErr;
           object oVault=GetObjectByTag(sTeamID+"_STORAGE");
           nErr=0;
           if (GetArea(oMe)!=GetArea(oVault))
           { // not home
              if (sTeamID=="SPID") nErr=3;
              else if (sTeamID=="DWF") nErr=2;
              else if (sTeamID=="UNC") nErr=1;
              else if (sTeamID=="UND") nErr=3;
              if (GetIsDay()==TRUE&&GetLocalInt(GetModule(),GetResRef(oMe)+"_light")==2) nErr=4; // light fatal
              oWP=fnPathNextDestination(GetArea(oMe),sTeamID,nErr);
              if (oWP!=OBJECT_INVALID)
                AssignCommand(oMe,ASActionMoveToObject(oWP,TRUE,8.0));
           } // not home
           else
           { // arrived in lair
               SetLocalInt(oMe,"nSState",7);
               AssignCommand(oMe,ClearAllActions());
           } // arrived in lair
           break;
       } // Return to lair
       case 7: { // Go to black barrel
           object oVault=GetObjectByTag(sTeamID+"_STORAGE");
           if (GetDistanceBetween(oMe,oVault)>1.5)
           { // move
               MoveToObject(oMe,oVault,TRUE,1.0);
           } // move
           else
           { // arrived
               SetLocalInt(oMe,"nSState",8);
           } // arrived
           break;
       } // Go to black barrel
       case 8: { // deposit goods in black barrel
           object oCopy;
           object oVault=GetObjectByTag(sTeamID+"_STORAGE");
           oItem=GetFirstItemInInventory(oVault);
           while(GetIsObjectValid(oItem))
           { // transfer items
               if (GetLocalInt(oItem,"bPickedUp"))
               { // transfer
                   oCopy=CopyItem(oItem,oVault,TRUE);
                   DeleteLocalInt(oCopy,"bPickedUp");
                   DelayCommand(0.1,DestroyObject(oItem));
               } // transfer
               oItem=GetNextItemInInventory(oVault);
           } // transfer items
           SetLocalInt(oMe,"nSState",0);
           break;
       } // deposit goods in black barrel
   } // sub-state
}
/////////////////////////////////////////////////////////[== MAIN ==]///////////