//============================================================================== /* C:\work\Spartan\main\age4\age4-dev\age4w\ai\CORE\Age2_BarracksRush_Hardcore.xs This file is auto-generated. Edits will be lost when the file is regenerated. */ //============================================================================== include "aiHeader.xs"; // Gets global vars, function forward declarations include "aiUtil.xs"; // Misc. shared AI utility functions include "aiEcon.xs"; // All of the AI's econ functionality include "aiMilitary.xs"; // All of the AI's military functionality include "aiNavy.xs"; // All of the AI's naval functionality include "aiEventHandlers.xs"; // Event handler methods for the AI include "aiMain.xs"; // The bulk of the AI include "aiSkirmish.xs"; // Skirmish Hall specific overrides extern int gPriestArmy = -1; extern int gFollowPlan = -1; //============================================================================== // initUnitPicker() // // Initialize the unit picker and give it a set of units to try and build. // This is for land units only. //============================================================================== mutable int initUnitPicker(string name="BUG", int numberTypes=1, int minUnits=10, int maxUnits=20, int minPop=-1, int maxPop=-1, int numberBuildings=1, bool guessEnemyUnitType=false) { //aiEcho("Initializing unit picker"); // Ensure that we have a most hated enemy when we start this plan mostHatedEnemy(); //Create it. int upID=kbUnitPickCreate(name); if (upID < 0) return(-1); //Default init. //aiEcho("kbUnitPickResetAll " + upID); kbUnitPickResetAll(upID); kbUnitPickSetPreferenceWeight(upID, 1.0); kbUnitPickSetCombatEfficiencyWeight(upID, 1.0); /*if (gSPC == false) kbUnitPickSetCombatEfficiencyWeight(upID, 2.0); // Changed from 1.0 to dilute the power of the preference weight. else kbUnitPickSetCombatEfficiencyWeight(upID, 1.0); // Leave it at 1.0 to avoid messing up SPC balance*/ kbUnitPickSetCostWeight(upID, 0.0); //Desired number units types, buildings. kbUnitPickSetDesiredNumberUnitTypes(upID, numberTypes, numberBuildings, true); //Min/Max units and Min/Max pop. kbUnitPickSetMinimumNumberUnits(upID, minUnits); // Sets "need" level on attack plans kbUnitPickSetMaximumNumberUnits(upID, maxUnits); // Sets "max" level on attack plans, sets "numberToMaintain" on train plans for primary unit, // half that for secondary, 1/4 for tertiary, etc. kbUnitPickSetMinimumPop(upID, minPop); // Not sure what this does... kbUnitPickSetMaximumPop(upID, maxPop); // If set, overrides maxNumberUnits for how many of the primary unit to maintain. //Default to land units. kbUnitPickSetEnemyPlayerID(upID, aiGetMostHatedPlayerID()); kbUnitPickSetAttackUnitType(upID, cUnitTypeLogicalTypeLandPickerChoice); kbUnitPickSetGoalCombatEfficiencyType(upID, cUnitTypeLogicalTypeLandPickerTarget); // [5/13/2009 CJS] May need to flip out unit types... // Set the default target types and weights, for use until we've seen enough actual units. // kbUnitPickAddCombatEfficiencyType(upID, cUnitTypeLogicalTypeLandMilitary, 1.0); //kbUnitPickAddCombatEfficiencyType(upID, gEconUnit, 0.2); // We need to build units that can kill settlers efficiently. //kbUnitPickAddCombatEfficiencyType(upID, cUnitTypeGrInfClubman, 0.2); // Major component //kbUnitPickAddCombatEfficiencyType(upID, cUnitTypeGrInfHoplite, 0.4); // Bigger component //kbUnitPickAddCombatEfficiencyType(upID, cUnitTypeGrInfHypaspist, 0.1); // Minor component //kbUnitPickAddCombatEfficiencyType(upID, cUnitTypeGrCavPodromos, 0.1); // Minor component kbUnitPickSetDefaultCombatEfficiency(upID, cUnitTypeAbstractPriest, 1.0); setUnitPickerPreference(upID); // Set generic preferences for this civ //xsEnableRule("artilleryMonitor"); //xsEnableRule("nativeMonitor"); //Done. return(upID); } //============================================================================== /* preInit() This function is called in main() before any of the normal initialization happens. Use it to override default values of variables as needed for personality or scenario effects. */ //============================================================================== void preInit(void) { aiEcho("preInit() PRIEST starting."); getDataFromBiases(); setDefaultAIVariables(); btTargetAge1ArmyCount = 0; btBiasInf = -0.5; btBiasCav = -0.5; btBiasArcher = -0.5; btBiasArt = -0.5; } //============================================================================== /* postInit() This function is called in main() after the normal initialization is complete. Use it to override settings and decisions made by the startup logic. */ //============================================================================== void postInit(void) { aiEcho("postInit() starting."); skirmishPostInit(); } /*rule checkForAttack active minInterval 10 { if(gFollowPlan == -1) { int planCount = aiPlanGetNumber(cPlanMission, cPlanStateWorking, true); if (planCount > 0) { for(i = 0; < planCount) { int plan = aiPlanGetIDByIndex(cPlanMission, cPlanStateWorking, true, i); int temp = aiPlanGetNumberUnits(plan + 1, cUnitTypeAbstractPriest); aiEcho("ASLKDJASD " + temp); if(temp > 4) { gFollowPlan = plan + 1; aiPlanSetRequiresAllNeedUnits(gFollowPlan, false); aiEcho("found a plan with PRIESTS"); } } } } if(gFollowPlan != -1) { if(aiPlanGetActive(gFollowPlan) == false) { gFollowPlan = -1; gPriestArmy = -1; aiEcho("plan no longer active"); return; } if(gPriestArmy == -1) { int priests = aiPlanGetNumberUnits(gFollowPlan, cUnitTypeAbstractPriest); gPriestArmy = aiPlanCreate("Priest Army Units", cPlanDefend); // add specific priests so that we don't scoop up the egyptian starting ra. //aiPlanAddUnitType(gPriestArmy, cUnitTypeUnitTypePriest1, 10, 15, 15); //aiPlanAddUnitType(gPriestArmy, cUnitTypeUnitTypePriest2, 10, 15, 15); //aiPlanAddUnitType(gPriestArmy, cUnitTypeUnitTypePriest4, 10, 15, 15); aiPlanAddUnitType(gPriestArmy, cUnitTypeAbstractPriest, priests, priests, priests); aiPlanSetVariableVector(gPriestArmy, cDefendPlanDefendPoint, 0, kbBaseGetMilitaryGatherPoint(cMyID, kbBaseGetMainID(cMyID))); if (kbBaseGetMilitaryGatherPoint(cMyID, kbBaseGetMainID(cMyID)) == cInvalidVector) { if (getUnit(cUnitTypeAIStart, cMyID) >= 0) // If no mil gather point, but there is a start block, use it. aiPlanSetVariableVector(gPriestArmy, cDefendPlanDefendPoint, 0, kbUnitGetPosition(getUnit(cUnitTypeAIStart, cMyID))); else aiPlanSetVariableVector(gPriestArmy, cDefendPlanDefendPoint, 0, kbUnitGetCentroid(cUnitTypeLogicalTypeLandMilitary)); } if (aiPlanGetVariableVector(gPriestArmy, cDefendPlanDefendPoint, 0) == cInvalidVector) // If all else failed, use the average location. aiPlanSetVariableVector(gPriestArmy, cDefendPlanDefendPoint, 0, kbUnitGetCentroid(cUnitTypeLogicalTypeLandMilitary)); aiPlanSetVariableFloat(gPriestArmy, cDefendPlanEngageRange, 0, cvDefenseReflexRadiusPassive); // Loose aiPlanSetRequiresAllNeedUnits(gPriestArmy, true); aiPlanSetVariableFloat(gPriestArmy, cDefendPlanGatherDistance, 0, cvDefenseReflexRadiusPassive - 10.0); aiPlanSetInitialPosition(gPriestArmy, kbBaseGetLocation(cMyID, kbBaseGetMainID(cMyID))); aiPlanSetUnitStance(gPriestArmy, cUnitStanceDefensive); aiPlanSetVariableInt(gPriestArmy, cDefendPlanRefreshFrequency, 0, 5); aiPlanSetVariableInt(gPriestArmy, cDefendPlanAttackTypeID, 0, cUnitTypeUnit); // Only units aiPlanSetDesiredPriority(gPriestArmy, 85); // Very very low priority, gather unused units. aiPlanSetActive(gPriestArmy); aiPlanSetNoMoreUnits(gPriestArmy, true); aiEcho("made a plan for PRIESTS to follow an attack"); } } if(gPriestArmy != -1 && gFollowPlan != -1) { // set the defend position to the positions of the first unit in the army //aiPlanSetVariableVector(gPriestArmy, cDefendPlanDefendPoint, 0, kbUnitGetPosition(aiPlanGetUnitByIndex(gFollowPlan, 0))); aiPlanSetVariableVector(gPriestArmy, cDefendPlanDefendPoint, 0, kbBaseGetMilitaryGatherPoint(cMyID, kbBaseGetMainID(cMyID))); } }*/ //============================================================================== // rule autoExploreEnemyBases // // Cheat and show the AI where all of the enemy bases are. //============================================================================== rule autoExploreEnemyBases active minInterval 5 { float totalTime = xsGetTime() / 1000.0; static bool revealed = false; if (btRevealEnemyBases == false) { xsDisableSelf(); return; } if (totalTime >= cTimeToRevealEnemyBases) { if (revealed == false) { Vector pos = aiCheatReveal(); if (xsVectorIsValid(pos)) { findEnemyBase(pos); } revealed = true; } else { aiCheatUnreveal(); xsDisableSelf(); } } } //============================================================================== // setupBuildingInfo() // // Called when we age up--setup the buildings we want for the current age. This // controls the forecast values and what the AI attempts to build automatically. // Some things (like farms and dropsites) are built elsewhere, even though // they're listed in here (for forecast info) //============================================================================== void setupBuildingInfo() { // Create arrays if needed initializeAndClearBuildingArrays(); int secondaryFactory = cUnitTypeUnitTypeBldgArcheryRange; int templeID = cUnitTypeUnitTypeBldgTemple; if(kbGetCiv()==gEgyptianCivID) { secondaryFactory = cUnitTypeUnitTypeBldgStables; } if(kbGetCiv()==gPersianCivID) { templeID = cUnitTypeUnitTypeBldgAcademy; } int currentVillCount = getVillagerCountForBuildOrder(); int bt = 0; int offset = 0; switch (kbGetAge()) { case cAge1: { if(btDifficulty > cStrongDifficulty) { bt = kbFindBuilding(cUnitTypeUnitTypeBldgBarracks); offset = addBuildingToList(bt, 1, cEconomyEscrowID, cAgeStateEarly, true, offset); } break; } case cAge2: { if(btDifficulty > cStrongDifficulty) { bt = kbFindBuilding(cUnitTypeUnitTypeBldgBarracks); offset = addBuildingToList(bt, currentVillCount / 12, cMilitaryEscrowID, cAgeStateEarly, true, offset); bt = kbFindBuilding(secondaryFactory); offset = addBuildingToList(bt, currentVillCount / 12, cMilitaryEscrowID, cAgeStateEarly, true, offset); } else if(btDifficulty > cWeakDifficulty) { bt = kbFindBuilding(cUnitTypeUnitTypeBldgBarracks); offset = addBuildingToList(bt, currentVillCount / 20, cMilitaryEscrowID, cAgeStateEarly, true, offset); bt = kbFindBuilding(secondaryFactory); offset = addBuildingToList(bt, currentVillCount / 20, cMilitaryEscrowID, cAgeStateMid, true, offset); } else { bt = kbFindBuilding(cUnitTypeUnitTypeBldgBarracks); offset = addBuildingToList(bt, 1, cMilitaryEscrowID, cAgeStateEarly, true, offset); bt = kbFindBuilding(secondaryFactory); offset = addBuildingToList(bt, 1, cMilitaryEscrowID, cAgeStateMid, true, offset); } break; } default: { if(btDifficulty > cStrongDifficulty) { if(kbGetCiv()==gEgyptianCivID) { bt = kbFindBuilding(cUnitTypeUnitTypeBldgTemple2); offset = addBuildingToList(bt, 2, cMilitaryEscrowID, cAgeStateEarly, true, offset); bt = kbFindBuilding(cUnitTypeUnitTypeBldgTemple3); offset = addBuildingToList(bt, 2, cMilitaryEscrowID, cAgeStateMid, true, offset); } else { bt = kbFindBuilding(templeID); offset = addBuildingToList(bt, currentVillCount / 9, cMilitaryEscrowID, cAgeStateEarly, true, offset); } bt = kbFindBuilding(cUnitTypeUnitTypeBldgBarracks); offset = addBuildingToList(bt, currentVillCount / 20, cMilitaryEscrowID, cAgeStateMid, true, offset); } else if(btDifficulty > cWeakDifficulty) { if(kbGetCiv()==gEgyptianCivID) { bt = kbFindBuilding(cUnitTypeUnitTypeBldgTemple2); offset = addBuildingToList(bt, 2, cMilitaryEscrowID, cAgeStateEarly, true, offset); } else { bt = kbFindBuilding(templeID); offset = addBuildingToList(bt, currentVillCount / 15, cMilitaryEscrowID, cAgeStateEarly, true, offset); } bt = kbFindBuilding(cUnitTypeUnitTypeBldgBarracks); offset = addBuildingToList(bt, currentVillCount / 20, cMilitaryEscrowID, cAgeStateMid, true, offset); } else { bt = kbFindBuilding(templeID); offset = addBuildingToList(bt, currentVillCount / 20, cMilitaryEscrowID, cAgeStateEarly, true, offset); bt = kbFindBuilding(cUnitTypeUnitTypeBldgBarracks); offset = addBuildingToList(bt, 1, cMilitaryEscrowID, cAgeStateMid, true, offset); } break; } } setupStandardBuildingInfo(offset, currentVillCount); } //============================================================================== // setUnitPickerPreference() // // Updates the unit picker biases. //============================================================================== void setUnitPickerPreference(int upID = -1) { // Add the main unit lines if (upID < 0) return; kbUnitPickSetPreferenceFactor(upID, cUnitTypeAbstractInfantry, 0.5 + (btBiasInf / 2.0)); // Range 0.0 to 1.0 kbUnitPickSetPreferenceFactor(upID, cUnitTypeAbstractArtillery, 0.5 + (btBiasArt / 2.0)); kbUnitPickSetPreferenceFactor(upID, cUnitTypeAbstractCavalry, 0.5 + (btBiasCav / 2.0)); kbUnitPickSetPreferenceFactor(upID, cUnitTypeAbstractArcher, 0.5 + (btBiasArcher / 2.0)); kbUnitPickSetPreferenceFactor(upID, cUnitTypeAbstractPriest, 1.0); // don't make ra if(kbGetCiv() == gEgyptianCivID) { kbUnitPickSetPreferenceFactor(upID, cUnitTypeUnitTypePriest3, -1.0); } }