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