HoS_PRC8/_mod/_module/nss/ai_header.nss
Jaysyn904 04165202c0 Initial upload
Initial upload
2024-11-25 19:36:07 -05:00

348 lines
11 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
// ai_header - shared functions used in computer controlled team AI
// By Deva Bryson Winblood. 04/13/2004
////////////////////////////////////////////////////////////////////////////////
int MAX_AI_UNITS = 30;
int AI_GUARD = 2;
int AI_FOLLOW = 5;
int AI_GUARD_LAIR = 11;
int AI_HEAL = 9;
int AI_RAID = 17;
int AI_RAID_ATTACK = 1;
int AI_RAID_GOLD = 3;
int AI_RAID_MANA = 2;
//////////////////////////////
// PROTOTYPES
//////////////////////////////
// returns the starting waypoint where players and leaders spawn
object fnAIGetLairStart(string sID);
// returns the object that the taxes are stored in for this team
object fnAIGetLairChest(string sID);
// returns how many units currently have 30 max for AI controlled team
int fnAICountMembers(string sID);
// returns a unit that matches the sTag type. If bNotBusy is set to
// TRUE it will only return 1 that is not on a RAID, GUARD, or GUARD LAIR
object fnAIGetMemberByType(string sID,string sTag,int bNotBusy=FALSE);
// returns a unit that is not on RAID, GUARD, or GUARD LAIR
// if bIncludeGuardLair is set to TRUE then it will return them if they
// are doing Guard Lair also.
object fnAIGetNonBusyMember(string sID,int bIncludeGuardLair=FALSE);
// This returns how many of the sTag unit are currently under this AI Team
// Leaders control.
int fnAICountMemberType(string sID,string sTag);
// This AI works with 30 units. This will return a # to an unaffiliated
// number that can be used to create a new unit.
int fnAIGetEmptyUnitNumber(string sID);
// This will create sRes unit at location and assign it to unit
// nNum 1-30.
object fnAICreateUnit(string sID,string sRes,location lLoc,int nNum);
// this returns a unit that is wounded down to nPercent or less of
// their life. If bIncludeRaid is set to FALSE it will not return
// any units on raiding missions.
object fnAIGetWoundedUnit(string sID,int nPercent,int bIncludeRaid=FALSE);
// returns the ID of the team that has the most trespass counts against this
// team sID.
string fnAIGetLargestTrespasser(string sID);
// returns the ID of a team that has trespassed randomly chosen.
string fnAIGetRandomTrespasser(string sID);
// upgrade the unit oUnit to a new unit sRes with the same mission,
// same nNum, etc.
void fnAIUpgradeUnit(object oUnit,string sRes);
// returns the team unit type # from the tag und25 would return 25
int fnAIGetUnitNumberFromTag(string sTag);
// This function should be called once before any of the other AI
// functions as it will populate the statistics and reduce the
// amount of processing that would otherwise be required for some
// of these.
void fnAISetupStatistics(string sID);
//////////////////////////////
// FUNCTIONS
//////////////////////////////
object fnAIGetLairStart(string sID)
{
object oWP=GetWaypointByTag(sID+"_START");
return oWP;
} // fnAIGetLairStart()
object fnAIGetLairChest(string sID)
{
object oOb=GetObjectByTag(sID+"_CHEST");
return oOb;
} // fnAIGetLairChest()
int fnAICountMembers(string sID)
{
int nRet=0;
object oMod=GetModule();
string sUnit;
sUnit="nAdvAIUnitT"+sID;
nRet=GetLocalInt(oMod,sUnit+"UC");
return nRet;
} // fnAICountMembers()
object fnAIGetMemberByType(string sID,string sTag,int bNotBusy=FALSE)
{
object oRet=OBJECT_INVALID;
string sUnit;
object oMod=GetModule();
object oUnit;
int nState;
int nL=1;
while(nL<MAX_AI_UNITS+1&&oRet==OBJECT_INVALID)
{ // get member
sUnit="oAdvAIUnit"+IntToString(nL);
oUnit=GetLocalObject(oMod,sUnit);
if (oUnit!=OBJECT_INVALID&&GetTag(oUnit)==sTag)
{ // busy
if (bNotBusy==FALSE) return oRet;
else { // see if busy
nState=GetLocalInt(oUnit,"nMState");
if (nState!=AI_GUARD&&nState!=AI_FOLLOW&&nState!=AI_HEAL&&nState!=AI_GUARD_LAIR&&nState!=AI_RAID) return oRet;
} // see if busy
} // busy
nL++;
} // get member
return oRet;
} // fnAIAIGetMembersByType()
object fnAIGetNonBusyMember(string sID,int bIncludeGuardLair=FALSE)
{
object oRet=OBJECT_INVALID;
string sUnit;
object oMod=GetModule();
object oUnit;
int nState;
int nL=1;
while(nL<MAX_AI_UNITS+1&&oRet==OBJECT_INVALID)
{ // get member
sUnit="oAdvAIUnit"+IntToString(nL);
oUnit=GetLocalObject(oMod,sUnit);
if (oUnit!=OBJECT_INVALID)
{ // unit
nState=GetLocalInt(oUnit,"nMState");
if (nState!=AI_GUARD&&nState!=AI_FOLLOW&&nState!=AI_HEAL&&nState!=AI_RAID)
{ // possible candidate
if (bIncludeGuardLair==FALSE) return oUnit;
else if (nState!=AI_GUARD_LAIR) return oUnit;
} // possible candidate
} // unit
nL++;
} // get member
return oRet;
} // fnAIGetNonBusyMember()
int fnAICountMemberType(string sID,string sTag)
{
int nRet=0;
object oMod=GetModule();
string sUnit;
object oUnit;
nRet=fnAIGetUnitNumberFromTag(GetTag(oUnit));
sUnit="nAdvAIUnitC"+sID+IntToString(nRet);
nRet=GetLocalInt(oMod,sUnit);
return nRet;
} // fnAICountMemberType()
int fnAIGetEmptyUnitNumber(string sID)
{
int nRet=0;
int nL=1;
string sUnit;
object oMod=GetModule();
while(nL<MAX_AI_UNITS+1&&nRet==0)
{ // find empty slot
sUnit="oAdvAIUnit"+IntToString(nL);
if (GetLocalObject(oMod,sUnit)==OBJECT_INVALID) nRet=nL;
nL++;
} // find empty slot
return nRet;
} // fnAIGetEmptyUnitNumber()
object fnAICreateUnit(string sID,string sRes,location lLoc,int nNum)
{
object oRet=OBJECT_INVALID;
object oMod=GetModule();
string sUnit="oAdvAIUnit"+sID+IntToString(nNum);
object oCreate=CreateObject(OBJECT_TYPE_CREATURE,sRes,lLoc);
//object oDM=GetFirstPC();
//while(oDM!=OBJECT_INVALID&&GetIsDM(oDM)!=TRUE)
//{
// oDM=GetNextPC();
//}
//if (GetIsDM(oDM)==TRUE) SendMessageToPC(oDM,GetName(oCreate)+" created in area "+GetName(GetArea(oCreate))+" RES="+sRes+" nNum="+IntToString(nNum));
SetLocalString(oCreate,"sTeamID",sID);
SetLocalObject(oMod,sUnit,oCreate);
SetLocalInt(oCreate,"nAIControlNum",nNum);
oRet=oCreate;
if (oCreate!=OBJECT_INVALID) PrintString(GetName(oCreate)+" spawned.");
return oRet;
} // fnAICreateUnit()
object fnAIGetWoundedUnit(string sID,int nPercent,int bIncludeRaid=FALSE)
{
object oRet=OBJECT_INVALID;
int nMax;
int nCur;
int nP;
int nL=1;
int nState;
string sUnit;
object oUnit;
float fP;
object oMod=GetModule();
while(nL<MAX_AI_UNITS+1&&oRet==OBJECT_INVALID)
{ // find wounded
sUnit="oAdvAIUnit"+IntToString(nL);
oUnit=GetLocalObject(oMod,sUnit);
if (oUnit!=OBJECT_INVALID)
{ // !OI
nMax=GetMaxHitPoints(oUnit);
nCur=GetCurrentHitPoints(oUnit);
if (nMax!=nCur)
{ // wounded
if ((bIncludeRaid==FALSE&&GetLocalInt(oUnit,"nMState")!=AI_RAID)||bIncludeRaid==TRUE)
{ // okay to use
fP=IntToFloat(nCur)/IntToFloat(nMax);
fP=fP*100;
nP=FloatToInt(fP);
if (nP<=nPercent) return oUnit;
} // okay to use
} // wounded
} // !OI
nL++;
} // find wounded
return oRet;
} // fnAIGetWoundedUnit()
string fnAIGetLargestTrespasser(string sID)
{
string sRet="NA";
object oMod=GetModule();
string sTresPrefix="nAITrespass"+sID+"_";
int nCount=0;
if (sID!="DWF"&&GetLocalInt(oMod,sTresPrefix+"DWF")>nCount) { nCount=GetLocalInt(oMod,sTresPrefix+"DWF"); sRet="DWF"; }
if (sID!="UND"&&GetLocalInt(oMod,sTresPrefix+"UND")>nCount) { nCount=GetLocalInt(oMod,sTresPrefix+"UND"); sRet="UND"; }
if (sID!="UNC"&&GetLocalInt(oMod,sTresPrefix+"UNC")>nCount) { nCount=GetLocalInt(oMod,sTresPrefix+"UNC"); sRet="UNC"; }
if (sID!="SPID"&&GetLocalInt(oMod,sTresPrefix+"SPID")>nCount) { nCount=GetLocalInt(oMod,sTresPrefix+"SPID"); sRet="SPID"; }
return sRet;
} // fnAIGetLargestTrespasser()
string fnAIGetRandomTrespasser(string sID)
{
string sRet="NA";
object oMod=GetModule();
int nCount=0;
int nR;
string sTresPrefix="nAITrespass"+sID+"_";
if (fnAIGetLargestTrespasser(sID)!="NA")
{ // there is a trespasser
while(sRet=="NA")
{ // get trespasser
nR=d4();
if (sID!="DWF"&&GetLocalInt(oMod,sTresPrefix+"DWF")>nCount&&nR==1) return "DWF";
else if (sID!="UND"&&GetLocalInt(oMod,sTresPrefix+"UND")>nCount&&nR==2) return "UND";
else if (sID!="UNC"&&GetLocalInt(oMod,sTresPrefix+"UNC")>nCount&&nR==3) return "UNC";
else if (sID!="SPID"&&GetLocalInt(oMod,sTresPrefix+"SPID")>nCount&&nR==4) return "SPID";
} // get trespasser
} // there is a trespasser
return sRet;
} // fnAIGetRandomTrespasser()
void fnAIUpgradeUnit(object oUnit,string sRes)
{
string sID=GetLocalString(oUnit,"sTeamID");
int nNum=GetLocalInt(oUnit,"nAIControlNum");
object oMod=GetModule();
string sUnit="oAdvAIUnit"+sID+IntToString(nNum);
int nMState=GetLocalInt(oUnit,"nMState");
object oDest=GetLocalObject(oUnit,"oDestWP");
int nParm=GetLocalInt(oUnit,"nParm");
int nRun=GetLocalInt(oUnit,"nRun");
object oNew=CreateObject(OBJECT_TYPE_CREATURE,sRes,GetLocation(oUnit));
DestroyObject(oUnit);
SetLocalString(oNew,"sTeamID",sID);
SetLocalInt(oNew,"nAIControlNum",nNum);
SetLocalInt(oNew,"nMState",nMState);
SetLocalObject(oNew,"oDestWP",oDest);
SetLocalInt(oNew,"nParm",nParm);
SetLocalInt(oNew,"nRun",nRun);
SetLocalObject(oMod,sUnit,oNew);
} // fnAIUpgradeUnit()
int fnAIGetUnitNumberFromTag(string sTag)
{
int nRet=0;
string sParse=GetStringRight(sTag,2);
if (StringToInt(GetStringLeft(sParse,1))==0) sParse=GetStringRight(sTag,1);
nRet=StringToInt(sParse);
return nRet;
} // fnAIGetUnitNumberFromTag()
void fnAISetupStatistics(string sID)
{
object oMod=GetModule();
int nL=0;
int nS;
string sUnit;
object oUnit;
int nUC=0;
int nD=0;
int nG=0;
int nO=0;
// clear statistics
while(nL<30)
{ // clear total
sUnit="nAdvAIUnitC"+sID+IntToString(nL);
DeleteLocalInt(oMod,sUnit);
nL++;
} // clear total
sUnit="nAdvAIUnitT"+sID;
DeleteLocalInt(oMod,sUnit+"D"); // defensive
DeleteLocalInt(oMod,sUnit+"G"); // guard
DeleteLocalInt(oMod,sUnit+"O"); // offensive
// get new statistics
nL=1;
while(nL<MAX_AI_UNITS+1)
{ // look at each unit
sUnit="oAdvAIUnit"+sID+IntToString(nL);
oUnit=GetLocalObject(oMod,sUnit);
if (oUnit!=OBJECT_INVALID)
{ // !OI
nS=GetLocalInt(oUnit,"nMState");
nUC++;
if (nS==AI_GUARD_LAIR||nS==AI_GUARD||nS==AI_HEAL) nD++;
if (nS==AI_GUARD) nG++;
if (nS==AI_RAID) nO++;
nS=fnAIGetUnitNumberFromTag(GetTag(oUnit));
sUnit="nAdvAIUnitC"+sID+IntToString(nS);
nS=GetLocalInt(oMod,sUnit);
nS++;
SetLocalInt(oMod,sUnit,nS);
} // !OI
nL++;
} // look at each unit
sUnit="nAdvAIUnitT"+sID;
SetLocalInt(oMod,sUnit+"D",nD);
SetLocalInt(oMod,sUnit+"G",nG);
SetLocalInt(oMod,sUnit+"O",nO);
SetLocalInt(oMod,sUnit+"UC",nUC);
} // fnAISetupStatistics()
//void main(){}