include "aiHunterCore.xs"; include "aiRMArmyControlCore.xs"; extern int gUnitID = -1; extern int gVillagerQuery = -1; extern int gWonderQuery = -1; extern int gTowerPlan = -1; extern int gXAttackCoords = -1; extern int gZAttackCoords = -1; extern int gCurrentAttackIndex = 0; extern int gNumberOfPathPoints = -1; extern int gHarassPlan = -1; extern int towerCount = 1; extern int giveResourcesInterval = 30; extern int giveResourcesAmount = 25; extern int gTowerLocationArray = -1; extern int gArmyIDArray = -1; extern int gTowerCreepIndex = 0; extern vector gTempTowerLocation = cInvalidVector; extern int gTowerUnitQuery = -1; extern int gCaravanQuery = -1; extern int gEconTCQuery = -1; extern const vector rallyPoint = vector(321,0,426); void initializeTowerCreeping(int count = -1) { gTowerLocationArray = xsArrayCreateVector(count, cInvalidVector, "Tower Locations"); gArmyIDArray = xsArrayCreateInt(count, -1, "Army IDs"); if(gTowerUnitQuery == -1) { gTowerUnitQuery = kbUnitQueryCreate("Tower Creep Query"); kbUnitQuerySetPlayerID(gTowerUnitQuery, cMyID); kbUnitQuerySetUnitType(gTowerUnitQuery, cUnitTypeUnitTypeBldgTower); kbUnitQuerySetState(gTowerUnitQuery, cUnitStateAlive); } } void addTowerArmyID(int id = -1) { xsArraySetInt(gArmyIDArray, gTowerCreepIndex, id); } void addTowerXCoord(int x = -1) { gTempTowerLocation = xsVectorSetX(gTempTowerLocation, x); } void addTowerZCoord(int z = -1) { gTempTowerLocation = xsVectorSetZ(gTempTowerLocation, z); xsArraySetVector(gTowerLocationArray, gTowerCreepIndex, gTempTowerLocation); gTowerCreepIndex = gTowerCreepIndex + 1; gTempTowerLocation = cInvalidVector; } rule checkLocationsForTowers active minInterval 15 { int count = xsArrayGetSize(gTowerLocationArray); for(i = 0; < count) { vector loc = xsArrayGetVector(gTowerLocationArray, i); if(loc != cInvalidVector) { kbUnitQuerySetPosition(gTowerUnitQuery, loc); kbUnitQuerySetMaximumDistance(gTowerUnitQuery, 5); kbUnitQueryResetResults(gTowerUnitQuery); kbUnitQueryExecute(gTowerUnitQuery); if(kbUnitQueryNumberResults(gTowerUnitQuery) > 0) { aiDestroyArmy(xsArrayGetInt(gArmyIDArray, i)); } } } } void setGiveResourcesInterval(int val=-1) { giveResourcesInterval = val; } void setGiveResourcesAmount(int val=-1) { giveResourcesAmount = val; } rule giveResources active minInterval 5 { kbAdjustResourceByID(cMyID, cResourceFood, giveResourcesAmount); kbAdjustResourceByID(cMyID, cResourceWood, giveResourcesAmount); kbAdjustResourceByID(cMyID, cResourceGold, giveResourcesAmount); kbAdjustResourceByID(cMyID, cResourceStone, giveResourcesAmount); xsSetRuleMinIntervalSelf(giveResourcesInterval); } rule checkForFailedAttacks active minInterval 15 { if(gFailedAttacks >= 2 && gFailedAttacks < 5) { kbAdjustResourceByID(cMyID, cResourceGold, 100); aiEcho("checkForFailedAttacks: granting resources because of too many failed attacks"); } else if(gFailedAttacks >= 8) { gMaxArmySize = 200; kbUnitQueryResetResults(gWonderQuery); kbUnitQueryExecute(gWonderQuery); vector baseLoc = kbUnitGetPosition(kbUnitQueryGetResult(gWonderQuery, 0)); xsArraySetInt(gXCoords, 0, xsVectorGetX(baseLoc)); xsArraySetInt(gZCoords, 0, xsVectorGetZ(baseLoc)); createAttackPlan(0); xsDisableSelf(); } } rule makeCaravansWork active minInterval 29 { if(gCaravanQuery == -1) { gCaravanQuery = kbUnitQueryCreate("Caravan Query"); kbUnitQuerySetPlayerID(gCaravanQuery, cMyID); kbUnitQuerySetUnitType(gCaravanQuery, cUnitTypeUnitTypeCaravan1); kbUnitQuerySetState(gCaravanQuery, cUnitStateAlive); } kbUnitQueryResetResults(gCaravanQuery); int count = kbUnitQueryExecute(gCaravanQuery); if(count < 1) return; if(gEconTCQuery == -1) { gEconTCQuery = kbUnitQueryCreate("AI Econ TC Query"); kbUnitQuerySetIgnoreKnockedOutUnits(gEconTCQuery, true); kbUnitQuerySetPlayerID(gEconTCQuery, cMyID); kbUnitQuerySetUnitType(gEconTCQuery, cUnitTypeUnitTypeBldgTownCenter); kbUnitQuerySetState(gEconTCQuery, cUnitStateAlive); } kbUnitQueryResetResults(gEconTCQuery); int tcs = kbUnitQueryExecute(gEconTCQuery); if(tcs < 1) return; int tcID = kbUnitQueryGetResult(gEconTCQuery, 0); for(i = 0; < count) { // get the first one int ID = kbUnitQueryGetResult(gCaravanQuery, i); if(kbUnitGetTargetUnitID(ID) == tcID) { //aiEcho("ALREADY ON THIS TC"); continue; } aiTaskUnitWork(ID, tcID); } } //============================================================================== // initializeArrays // // Call this function first to initialize the number of points you'll want. //============================================================================== void initializeAttackArrays(int count=-1) { aiEcho("initializeArrays: count " + count); gXAttackCoords = xsArrayCreateInt(count, -1, "X Attack Coords"); gZAttackCoords = xsArrayCreateInt(count, -1, "Z Attack Coords"); gNumberOfPathPoints = count; } //============================================================================== // addXCoord // // Always set the X coord before setting the Z. //============================================================================== void addXAttackCoord(int x=-1) { aiEcho("X: " + x); xsArraySetInt(gXAttackCoords, gCurrentAttackIndex, x); } //============================================================================== // addZCoord // // Always call this function after you set the X coord. //============================================================================== void addZAttackCoord(int z=-1) { aiEcho("Z: " + z); xsArraySetInt(gZAttackCoords, gCurrentAttackIndex, z); gCurrentAttackIndex = gCurrentAttackIndex + 1; if(gCurrentAttackIndex == gNumberOfPathPoints) { aiEcho("AJLKJSDAD"); gCurrentAttackIndex = 0; } } void setUnitIDToRepair(int id=-1) { gUnitID = id; gVillagerQuery = kbUnitQueryCreate("Villager Query"); kbUnitQuerySetPlayerID(gVillagerQuery, cMyID); kbUnitQuerySetUnitType(gVillagerQuery, cUnitTypeUnitTypeVillager1); kbUnitQuerySetState(gVillagerQuery, cUnitStateAlive); gWonderQuery = kbUnitQueryCreate("Wonder Query"); kbUnitQuerySetPlayerID(gWonderQuery, cMyID); kbUnitQuerySetUnitType(gWonderQuery, cUnitTypeUnitTypeBldgWonder); kbUnitQuerySetState(gWonderQuery, cUnitStateABQ); xsEnableRule("makeVillagersRepair"); //xsEnableRule("buildTowers"); } rule makeVillagersRepair inactive minInterval 5 { kbUnitQueryResetResults(gVillagerQuery); int villagers = kbUnitQueryExecute(gVillagerQuery); kbUnitQueryResetResults(gWonderQuery); int wonders = kbUnitQueryExecute(gWonderQuery); for(i=0; < villagers) { int vil = kbUnitQueryGetResult(gVillagerQuery, i); if(kbUnitGetArmyID(vil) == -1) { aiTaskUnitRepair(vil, kbUnitQueryGetResult(gWonderQuery, 0)); } } } rule buildTowers inactive minInterval 90 { int tower = kbFindBuilding(cUnitTypeUnitTypeBldgTower); kbUnitQueryResetResults(gWonderQuery); kbUnitQueryExecute(gWonderQuery); vector base = kbUnitGetPosition(kbUnitQueryGetResult(gWonderQuery, 0)); vector testVec = cInvalidVector; vector direction = xsVectorSet(-0.707, 0, -0.707); float spacingDistance = 30.0; switch(towerCount) { case 3: { testVec = xsVectorSetX(testVec, xsVectorGetX(base) + (xsVectorGetZ(direction) * -1 * spacingDistance)); testVec = xsVectorSetZ(testVec, xsVectorGetZ(base) + (xsVectorGetX(direction) * spacingDistance)); break; } case 4: { testVec = xsVectorSetX(testVec, xsVectorGetX(base) + (xsVectorGetZ(direction) * spacingDistance)); testVec = xsVectorSetZ(testVec, xsVectorGetZ(base) + (xsVectorGetX(direction) * -1 * spacingDistance)); break; } case 1: { testVec = xsVectorSetX(testVec, xsVectorGetX(base) + (xsVectorGetX(direction) * spacingDistance * 0.6) + (xsVectorGetZ(direction) * -1 * spacingDistance * 0.6)); testVec = xsVectorSetZ(testVec, xsVectorGetZ(base) + (xsVectorGetZ(direction) * spacingDistance * 0.65) + (xsVectorGetX(direction) * spacingDistance * 0.6)); break; } case 2: { testVec = xsVectorSetX(testVec, xsVectorGetX(base) + (xsVectorGetX(direction) * spacingDistance * 0.6) + (xsVectorGetZ(direction) * spacingDistance * 0.6)); testVec = xsVectorSetZ(testVec, xsVectorGetZ(base) + (xsVectorGetZ(direction) * spacingDistance * 0.6) + (xsVectorGetX(direction) * -1 * spacingDistance * 0.6)); break; } } int planID=aiPlanCreate("Tower Build", cPlanBuild); // What to build aiPlanSetVariableInt(planID, cBuildPlanBuildingTypeID, 0, tower); //Priority. aiPlanSetDesiredPriority(planID, 100); //Mil vs. Econ. aiPlanSetMilitary(planID, true); aiPlanSetEscrowID(planID, cEmergencyEscrowID); aiPlanAddUnitType(planID, kbFindUnit(cUnitTypeUnitTypeVillager1), 1, 1, 1); aiPlanSetVariableVector(planID, cBuildPlanCenterPosition, 0, testVec); aiPlanSetVariableFloat(planID, cBuildPlanCenterPositionDistance, 0, 5.0); /*aiPlanSetNumberVariableValues(planID, cBuildPlanInfluenceUnitTypeID, 2, false); aiPlanSetNumberVariableValues(planID, cBuildPlanInfluenceUnitDistance, 2, false); aiPlanSetNumberVariableValues(planID, cBuildPlanInfluenceUnitValue, 2, false); aiPlanSetNumberVariableValues(planID, cBuildPlanInfluenceUnitFalloff, 2, false); aiPlanSetNumberVariableValues(planID, cBuildPlanInfluenceUnitCap, 2, false); // Build near a max of 4 other houses aiPlanSetVariableInt(planID, cBuildPlanInfluenceUnitTypeID, 0, tower); aiPlanSetVariableFloat(planID, cBuildPlanInfluenceUnitDistance, 0, 20.0); aiPlanSetVariableFloat(planID, cBuildPlanInfluenceUnitValue, 0, 1000.0); aiPlanSetVariableInt(planID, cBuildPlanInfluenceUnitFalloff, 0, cBPIFalloffLinearInverse); aiPlanSetVariableInt(planID, cBuildPlanInfluenceUnitCap, 0, -1); aiPlanSetVariableVector(planID, cBuildPlanInfluencePosition, 0, kbUnitGetPosition(kbUnitQueryGetResult(gWonderQuery, 0))); aiPlanSetVariableFloat(planID, cBuildPlanInfluencePositionDistance, 0, 30.0); aiPlanSetVariableFloat(planID, cBuildPlanInfluencePositionValue, 0, 100.0); aiPlanSetVariableInt(planID, cBuildPlanInfluencePositionFalloff, 0, cBPIFalloffLinearInverse);*/ aiPlanSetActive(planID); gTowerPlan = planID; towerCount = towerCount + 1; } //============================================================================== // getPosition // // Return a vector from the X and Z coords passed in. //============================================================================== vector getAttackPosition(int index=-1) { vector point = cInvalidVector; point = xsVectorSetX(point, xsArrayGetInt(gXAttackCoords, index)); point = xsVectorSetY(point, 0); point = xsVectorSetZ(point, xsArrayGetInt(gZAttackCoords, index)); return(point); } //============================================================================== // createAttackPlan // // Create a plan to attack one of the specific coords. //============================================================================== void createHarassAttackPlan(int index=-1) { if(index == -1) return(); vector point = getAttackPosition(index); gHarassPlan = aiPlanCreate("Attack Plan", cPlanAttack); //Priority. aiPlanSetDesiredPriority(gHarassPlan, 90); //Attack. aiPlanSetAttack(gHarassPlan, true); aiPlanSetInitialPosition(gHarassPlan, point); aiPlanSetVariableVector(gHarassPlan, cAttackPlanAttackPoint, 0, point); //Military. aiPlanSetMilitary(gHarassPlan, true); aiPlanSetEscrowID(gHarassPlan, cMilitaryEscrowID); aiPlanAddUnitType(gHarassPlan, cUnitTypeLogicalTypeLandMilitary , 5, 5, 200); aiPlanSetActive(gHarassPlan); if(index == gNumberOfPathPoints - 1) { xsEnableRule("hitAndRun"); xsDisableRule("checkForHarassAttackPlans"); xsEnableRule("checkForHarassRetreatPlans"); } } rule enableHarassment inactive minInterval 60 { xsDisableSelf(); xsEnableRule("checkForHarassAttackPlans"); } rule checkForHarassAttackPlans inactive minInterval 10 { if(gHarassPlan == -1 || (aiPlanGetActive(gHarassPlan) == false && gCurrentAttackIndex < gNumberOfPathPoints)) { aiEcho("HONK"); createHarassAttackPlan(gCurrentAttackIndex); gCurrentAttackIndex = gCurrentAttackIndex + 1; } } rule checkForHarassRetreatPlans inactive minInterval 10 { if(gHarassPlan == -1 || (aiPlanGetActive(gHarassPlan) == false && gCurrentAttackIndex >= 0)) { aiEcho("HONK"); createHarassAttackPlan(gCurrentAttackIndex); if(gCurrentAttackIndex == 0) { xsEnableRule("checkForHarassAttackPlans"); xsDisableRule("checkForHarassRetreatPlans"); } else { gCurrentAttackIndex = gCurrentAttackIndex - 1; } } } rule hitAndRun inactive minInterval 20 { aiEcho("HitAndRun: cancelling plan"); aiPlanDestroy(gHarassPlan); gCurrentAttackIndex = gCurrentAttackIndex - 2; createHarassAttackPlan(gCurrentAttackIndex); gCurrentAttackIndex = gCurrentAttackIndex - 1; xsDisableSelf(); } void main() { kbAreaCalculate(); kbLookAtAllUnitsOnMap(); gMaxArmySize = 5; int planID = aiPlanCreate("Maintain Plan Villagers", cPlanTrain); aiPlanSetEscrowID(planID, cEmergencyEscrowID); aiEcho("VILLAGER " + kbFindUnit(cUnitTypeUnitTypeVillager1)); //Unit type. aiPlanSetVariableInt(planID, cTrainPlanUnitType, 0, kbFindUnit(cUnitTypeUnitTypeVillager1)); //Number. aiPlanSetVariableInt(planID, cTrainPlanNumberToMaintain, 0, 50); // Batch size aiPlanSetVariableInt(planID, cTrainPlanBatchSize, 0, 1); aiPlanSetActive(planID); planID = aiPlanCreate("Maintain Plan Priest", cPlanTrain); aiPlanSetEscrowID(planID, cEmergencyEscrowID); aiEcho("VILLAGER " + kbFindUnit(cUnitTypeAbstractPriest)); //Unit type. aiPlanSetVariableInt(planID, cTrainPlanUnitType, 0, kbFindUnit(cUnitTypeAbstractPriest)); //Number. aiPlanSetVariableInt(planID, cTrainPlanNumberToMaintain, 0, 50); // Batch size aiPlanSetVariableInt(planID, cTrainPlanBatchSize, 0, 1); aiPlanSetActive(planID); int gLandReservePlan = aiPlanCreate("Land Reserve Units", cPlanDefend); aiPlanAddUnitType(gLandReservePlan, cUnitTypeAbstractPriest , 0, 5, 200); // All mil units, high MAX value to suck up all excess aiEcho("asdf" + kbUnitGetCentroid(cUnitTypeUnitTypeBldgTower)); aiPlanSetVariableVector(gLandReservePlan, cDefendPlanDefendPoint, 0, kbUnitGetCentroid(cUnitTypeUnitTypeBldgTower)); aiPlanSetVariableFloat(gLandReservePlan, cDefendPlanEngageRange, 0, 30.0); // Loose aiPlanSetVariableBool(gLandReservePlan, cDefendPlanPatrol, 0, false); aiPlanSetVariableFloat(gLandReservePlan, cDefendPlanGatherDistance, 0, 20.0); aiPlanSetInitialPosition(gLandReservePlan, kbUnitGetCentroid(cUnitTypeUnitTypeBldgTower)); aiPlanSetUnitStance(gLandReservePlan, cUnitStanceDefensive); aiPlanSetVariableInt(gLandReservePlan, cDefendPlanRefreshFrequency, 0, 5); aiPlanSetVariableInt(gLandReservePlan, cDefendPlanAttackTypeID, 0, cUnitTypeUnit); // Only units aiPlanSetDesiredPriority(gLandReservePlan, 5); // Very very low priority, gather unused units. aiPlanSetActive(gLandReservePlan); } void useVillagersToGather(int unused = -1) { xsEnableRule("manageAttackingPlayerConvertedVillagers"); xsEnableRule("createGatherPlansForConvertedVillagers"); } rule manageAttackingPlayerConvertedVillagers inactive minInterval 8 { if(gVillagerQuery == -1) { gVillagerQuery = kbUnitQueryCreate("Villager Query"); kbUnitQuerySetPlayerID(gVillagerQuery, cMyID); kbUnitQuerySetUnitType(gVillagerQuery, cUnitTypeUnitTypeVillager1); kbUnitQuerySetState(gVillagerQuery, cUnitStateAlive); } kbUnitQueryResetResults(gVillagerQuery); int villagers = kbUnitQueryExecute(gVillagerQuery); for(i = 0; < villagers) { int vil = kbUnitQueryGetResult(gVillagerQuery, i); if(kbUnitGetActionType(vil) == 7) { aiTaskUnitMove(vil, rallyPoint); } } } rule createGatherPlansForConvertedVillagers inactive minInterval 20 { int plan = aiPlanCreate("Gather plan Stone", cPlanGather); aiPlanSetBaseID(plan, kbBaseGetMain(cMyID)); aiPlanSetVariableInt(plan, cGatherPlanResourceType, 0, cResourceStone); //aiPlanSetVariableInt(plan, cGatherPlanMaximumGatherDistance, 0, 500); aiPlanAddUnitType(plan, cUnitTypeUnitTypeVillager1, 200,200,200); aiPlanSetActive(plan); }