248 lines
8.6 KiB
Plaintext
248 lines
8.6 KiB
Plaintext
////////////////////////////////////////////////////////////////////////////////
|
|
// 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 ==]///////////
|