| 04-09-2011, 12:33 PM | #1 |
After all this community has given me, and due to my inactivity, I thought it would be a good idea to make my most valuable resource available to everyone here, on this site. That's right, this is and will stay a WC3C-exclusive resource. No exceptions allowed. This is an .ai template that eases the burden of AI scripting. It has been used as a base for the Melee AIs in my project (The Withering Kind) and in Kam's Beyond The Throne. (from version 3.9.4.2 to 3.9.4.4 at least, latest version's one is "streamlined" according to the release notes so I'm not sure it's the same) .ai scripts are pure JASS. This script is aimed at JASS/vJass coders that want to script quick 'n' dirty Melee AIs or that want to learn how to script AIs. Its features: (and also its non-features)
Differences with Blizzard's Melee AI: (and downsides)
JASS://=========================================================================== // // Michael Peppers's Melee AI template (v0.4.1) // - Automatized Tiering system added // - Clever Upgrading system! (clever, but not automatized...) // - Now the AI will handle ALL the worker creation stuff automatically // //=========================================================================== //--- // FYI, as long as you can try to make a complete template, you'll still have to make // most of the BuildPriorities and UpgradePriorities yourself... //--- //*************************************************************************** //* //* Global Variables //* //*************************************************************************** globals // Standard AI globals, DON'T TOUCH!! integer attackWave = 1 integer nextDelay = 0 //misc common.ai and standard global infos: //"attackWave" can be used to know the current attack wave //"nextDelay" is used to delay the attack waves //"take_exp" is a common.ai boolean global, can be used to store/retrieve the need of an expansion //If you need to know the current gold/wood harvesters, check "AddAttackUnit" in a AI Editor ".ai" file // Town Hall constant integer Hall = '' constant integer Mine = '' //Only with mines that have to be built (UD), in any other case = Hall constant integer HallTier2 = '' constant integer HallTier3 = '' // Workers constant integer GoldHarvester = '' constant integer WoodHarvester = '' //In most AIs = GoldHarvester // Highly volatile globals section // Buildings constant integer House = '' constant integer Altar = '' constant integer Barracks = '' constant integer Blacksmith = '' constant integer LumberMill = '' //In most AIs = Blacksmith constant integer Shop = '' //No shops = set to 0 constant integer CasterBarracks = '' constant integer Tower = '' constant integer SpecializedBarracks = '' //Workshop/Beastiary/AncientOfWind/SlaughterHouse etc. constant integer FlyingBarracks = '' // Units constant integer BasicMelee = '' constant integer BasicRanged = '' //I hope for my AI's sanity that BasicMelee + BasicRanged >= 5 food. =P constant integer T2Melee = '' //Specialized Melee, if it doesn't exist, T2MeleeExists MUST be set to false constant integer MainCaster = '' //Ala Sorceress constant integer SupportCaster = '' //Ala Priest constant integer OwnageMelee = '' //Ala Knight/Tauren/Abo etc. constant integer AirAir = '' //ala Gargoyle constant integer AirGround = '' //ala Gryphon constant integer SiegeRanged = '' constant integer MiscUnit1 = '' //Not used as of now constant integer MiscUnit2 = '' //Not used as of now // Upgrades constant integer AttackUpgrade1 = '' constant integer AttackUpgrade2 = '' constant integer DefenseUpgrade1 = '' constant integer DefenseUpgrade2 = '' constant integer BasicMeleeUpgrade = '' constant integer BasicRangedUpgrade = '' constant integer MainCasterUpgrade = '' constant integer SupportCasterUpgrade = '' constant integer LumberHarvestUpgrade = '' constant integer BuildingDefenseUpgrade = '' constant integer MiscUpgrade1 = '' constant integer MiscUpgrade2 = '' constant integer MiscUpgrade3 = '' constant integer MiscUpgrade4 = '' constant integer MiscUpgrade5 = '' constant integer MiscUpgrade6 = '' constant integer MiscUpgrade7 = '' constant integer MiscUpgrade8 = '' constant integer MiscUpgrade9 = '' constant integer MiscUpgrade10 = '' constant integer MiscUpgrade11 = '' constant integer MiscUpgrade12 = '' //Not used as of now //End of highly volatile globals =P // Heroes constant integer Heroes = 4 //Number of heroes in the racial altar constant integer H1 = '' constant integer H2 = '' //Set to 0 if it doesn't exists, shouldn't cause problems, though constant integer H3 = '' //Read above constant integer H4 = '' //Idem // Hero Skills // First Hero constant integer H1A1 = '' constant integer H1A2 = '' constant integer H1A3 = '' constant integer H1U = '' // Second Hero constant integer H2A1 = '' constant integer H2A2 = '' constant integer H2A3 = '' constant integer H2U = '' // Third Hero constant integer H3A1 = '' constant integer H3A2 = '' constant integer H3A3 = '' constant integer H3U = '' // Fourth Hero (yes, the AI supports 4 racial heroes =D) constant integer H4A1 = '' constant integer H4A2 = '' constant integer H4A3 = '' constant integer H4U = '' // Food Conditions for assaults constant integer Food4Attack = 80 //Food usage needed for assaulting Main Bases constant integer Food4Exp = 42 //Food usage needed for creating Expansions // Harvest priorities constant integer GoldGuys1 = 5 //How many people will gather gold at the 1st mine constant integer WoodGuys1 = 5 //How many people will gather wood at the base constant integer GoldGuys2 = 0 //How many people will gather gold at the 2nd mine, 0 to disable constant integer WoodGuys2 = 0 //How many other people will gather wood at the base, 0 to disable //Automatized housing values constant integer HousesToBuild = 2 //How many houses will the AI build at a time constant integer MaxFoodUsedByUnit = 5 //The food value of the most expensive unit, food-wise constant integer MaxFood = 100 //The maximum number of food that can be produced //Automatized tiering values constant integer GoldForT2 = 600 //When this Gold value is reached, the AI will go to T2 constant integer WoodForT2 = 400 //When this Wood value is reached, the AI will go to T2 constant integer GoldForT3 = 800 //When this Gold value is reached, the AI will go to T3 constant integer WoodForT3 = 600 //When this Wood value is reached, the AI will go to T3 // Misc stuff constant boolean WantName = true constant boolean WantDifficultyInName = true constant string Name = "Test" constant boolean IsAmphibious = false //Naga-like race? constant boolean WannaKeepBasicMelee = false //Self-explainatory, I hope =) constant integer KeepBasicMeleeFoodCap = 54 //As soon as the AI surpasses this food cap it will stop training basic melee units constant boolean T2MeleeExists = true //No T2 Melee? = set to false constant integer MinimumForceBasicMelee = 4 //Use wisely: 2 food each = 4, 3 food each = 3 constant integer MinimumForceBasicRanged = 3 //Use wisely: 2 food each = 4, 3 food each = 3 constant integer MinimumForceT2Melee = 3 constant integer MinimumForceOwnageMelee = 3 constant integer AIHasT2Melee = 52 //When this food cap is reached, the AI will use T2Melee too (if enabled) in Minimum Attack constant integer AIHasOwnageMelee = 90 //When this food cap is reached, the AI will use OwnageMelee too in Minimum Attack // Difficulty-dependant variables (to change them, look in "main") integer MinesToOwn = 0 //(2 for Newb AI, 3 for Normal, 4 for Insane) string array DifficultyName //"(Easy)", "(Normal)", "(Insane)" // Conditions (Do not touch!!! These are changed by "UpdateConditions" anyway...) boolean KeepBasicMelee = true boolean CanAttack = false //Has enough units to help allies/launch small attacks? endglobals //*************************************************************************** //* //* Utility Functions //* //*************************************************************************** //HallCount Replicates and enhances common.ai's TownCountEx function, to make it work with custom halls =D function HallCount takes integer unitid, boolean done returns integer local integer have_qty if (not done) then set have_qty = GetUnitCount(unitid) if unitid == Hall then set have_qty = have_qty + GetUnitCount(HallTier2) + GetUnitCount(HallTier3) elseif unitid == HallTier2 then set have_qty = have_qty + GetUnitCount(HallTier3) endif else set have_qty = GetUnitCountDone(unitid) if unitid == Hall then set have_qty = have_qty + GetUnitCountDone(HallTier2) + GetUnitCountDone(HallTier3) elseif unitid == HallTier2 then set have_qty = have_qty + GetUnitCountDone(HallTier3) endif endif return have_qty endfunction //=========================================================================== function CheckLastCommand takes boolean pop returns integer local integer cmd = GetLastCommand() if (pop) then call PopLastCommand() endif return cmd endfunction //=========================================================================== function CheckLastCommandData takes boolean pop returns integer local integer data = GetLastData() if (pop) then call PopLastCommand() endif return data endfunction //=========================================================================== function BuildExpansion takes boolean build_it returns nothing if build_it and HallsCompleted(Hall) then call SetBuildExpa(HallCount(Hall, false) + 1, Hall) endif endfunction //*************************************************************************** //* //* Basic Options //* //*************************************************************************** //=========================================================================== function InitOptions takes nothing returns nothing call SetMeleeAI() call SetDefendPlayer(true) call SetRandomPaths(false) call SetTargetHeroes(true) call SetPeonsRepair(true) call SetHeroesFlee(true) call SetHeroesBuyItems(true) call SetUnitsFlee(true) call SetGroupsFlee(true) call SetWatchMegaTargets(true) call SetIgnoreInjured(true) call SetHeroesTakeItems(true) call SetSlowChopping(false) call SetCaptainChanges(true) call SetSmartArtillery(true) endfunction //*************************************************************************** //* //* Conditions //* //*************************************************************************** //=========================================================================== // Updates the values of all preset conditions //=========================================================================== function UpdateConditions takes nothing returns nothing if (not WannaKeepBasicMelee) then set KeepBasicMelee = (FoodCap() < KeepBasicMeleeFoodCap) endif if T2MeleeExists then set CanAttack = (GetUnitCountDone(BasicMelee) >= MinimumForceBasicMelee or GetUnitCountDone(T2Melee) >= MinimumForceT2Melee) and GetUnitCountDone(BasicRanged) >= MinimumForceBasicRanged else set CanAttack = (GetUnitCountDone(BasicMelee) >= MinimumForceBasicMelee or GetUnitCountDone(OwnageMelee) >= MinimumForceOwnageMelee) and GetUnitCountDone(BasicRanged) >= MinimumForceBasicRanged endif endfunction //*************************************************************************** //* //* Heroes //* //*************************************************************************** function SetSkills takes nothing returns nothing set skill[ 1] = H1A1 set skill[ 2] = H1A2 set skill[ 3] = H1A3 set skill[ 4] = H1A1 set skill[ 5] = H1A2 set skill[ 6] = H1U set skill[ 7] = H1A3 set skill[ 8] = H1A1 set skill[ 9] = H1A2 set skill[10] = H1A3 if hero_id == H1 then call SetSkillArray(1, H1) elseif hero_id2 == H1 then call SetSkillArray(2, H1) elseif hero_id3 == H1 then call SetSkillArray(3, H1) endif if Heroes > 1 then set skill[ 1] = H2A1 set skill[ 2] = H2A2 set skill[ 3] = H2A3 set skill[ 4] = H2A1 set skill[ 5] = H2A2 set skill[ 6] = H2U set skill[ 7] = H2A3 set skill[ 8] = H2A1 set skill[ 9] = H2A2 set skill[10] = H2A3 if hero_id == H2 then call SetSkillArray(1, H2) elseif hero_id2 == H2 then call SetSkillArray(2, H2) elseif hero_id3 == H2 then call SetSkillArray(3, H2) endif endif if Heroes > 2 then set skill[ 1] = H3A1 set skill[ 2] = H3A2 set skill[ 3] = H3A3 set skill[ 4] = H3A1 set skill[ 5] = H3A2 set skill[ 6] = H3U set skill[ 7] = H3A3 set skill[ 8] = H3A1 set skill[ 9] = H3A2 set skill[10] = H3A3 if hero_id == H3 then call SetSkillArray(1, H3) elseif hero_id2 == H3 then call SetSkillArray(2, H3) elseif hero_id3 == H3 then call SetSkillArray(3, H3) endif endif if Heroes > 3 then set skill[ 1] = H4A1 set skill[ 2] = H4A2 set skill[ 3] = H4A3 set skill[ 4] = H4A1 set skill[ 5] = H4A2 set skill[ 6] = H4U set skill[ 7] = H4A3 set skill[ 8] = H4A1 set skill[ 9] = H4A2 set skill[10] = H4A3 if hero_id == H4 then call SetSkillArray(1, H4) elseif hero_id2 == H4 then call SetSkillArray(2, H4) elseif hero_id3 == H4 then call SetSkillArray(3, H4) endif endif endfunction function PickRacialHero takes nothing returns nothing local integer first local integer second local integer third local integer last local integer array heroes set heroes[1] = H1 set heroes[2] = H2 set heroes[3] = H3 set heroes[4] = H4 if Heroes > 3 then if VersionCompatible(VERSION_FROZEN_THRONE) then set last = 4 else set last = 3 endif else set last = Heroes endif if last >= 1 then set first = GetRandomInt(1,last) if last >= 2 then set second = GetRandomInt(1,last-1) if last >= 3 then set third = GetRandomInt(1,last-2) else set third = 3 endif else set second = 2 endif endif set hero_id = heroes[first] set heroes[first] = heroes[last] set hero_id2 = heroes[second] set heroes[second] = heroes[last-1] set hero_id3 = heroes[third] endfunction //*************************************************************************** //* //* Building and Harvesting //* //*************************************************************************** //=========================================================================== // Specifies building priorities for workers //=========================================================================== function BuildPriorities takes nothing returns nothing local integer mine = TownWithMine() local boolean twoharvs = false call InitBuildArray() call MeleeTownHall(0, Hall) call MeleeTownHall(1, Hall) if Hall != Mine and GetGold() < 1500 then //In case of a custom mine call SecondaryTown(mine, 1, Mine) endif call SetBuildUnit(GoldGuys1, GoldHarvester) if GoldHarvester != WoodHarvester then set twoharvs = true endif if HallCount(HallTier2, false) == 0 and GetGold() >= GoldForT2 and GetWood() >= WoodForT2 then call SetBuildUnit(1, HallTier2) elseif HallCount(HallTier3, false) == 0 and GetGold() >= GoldForT3 and GetWood() >= WoodForT3 then call SetBuildUnit(1, HallTier3) endif if FoodCap() < MaxFood and FoodCap() <= (FoodUsed() + MaxFoodUsedByUnit) and GetUnitCount(House) < (GetUnitCountDone(House) + HousesToBuild) and HallCount(Hall, false) <= (HallCount(Hall, true) + (1 + (HallCount(HallTier2, false) - HallCount(HallTier2, true)))) then call SetBuildUnit(GetUnitCount(House) + 1, House) endif if twoharvs = true then call SetBuildUnit(WoodGuys1 - 1, WoodHarvester) else call SetBuildUnit(GoldGuys1 + (WoodGuys1 - 1), WoodHarvester) endif call SetBuildUnit(1, Altar) call SetBuildUnit(1, Barracks) if twoharvs = true then call SetBuildUnit(WoodGuys1, WoodHarvester) else call SetBuildUnit(GoldGuys1 + WoodGuys1, WoodHarvester) endif call SetBuildUnit(1, hero_id) if KeepBasicMelee then call SetBuildUnit(3, BasicMelee) endif call SetBuildUnit(1, Blacksmith) call SetBuildUnit(2, BasicRanged) if Blacksmith != LumberMill then call SetBuildUnit(1, LumberMill) endif call SetBuildUnit(3, BasicRanged) if KeepBasicMelee then call SetBuildUnit(5, BasicMelee) endif if Shop != 0 then call SetBuildUnit(1, Shop) endif call SetBuildUnit(5, BasicRanged) call BuildExpansion(GetMinesOwned() < MinesToOwn) if WoodGuys2 > 0 then if twoharvs = true then call SetBuildUnit(WoodGuys1 + WoodGuys2, WoodHarvester) else call SetBuildUnit(GoldGuys1 + WoodGuys1 + WoodGuys2, WoodHarvester) endif endif call SetBuildUnit(1, Tower) call SetBuildUnit(1, CasterBarracks) if MeleeDifficulty() != MELEE_NEWBIE and Heroes > 1 then //2 heroes? kthxbai call SetBuildUnit(1, hero_id2) else //Adding some cannon fodder, >= 5 food in total, I hope... if KeepBasicMelee then call SetBuildUnit(6, BasicMelee) else call SetBuildUnit(1, BasicMelee) endif call SetBuildUnit(6, BasicRanged) endif call SetBuildUnit(2, Tower) if T2MeleeExists then call SetBuildUnit(3, T2Melee) endif if T2MeleeExists then call SetBuildUnit(4, T2Melee) if (not KeepBasicMelee) then call SetBuildUnit(6, T2Melee) endif endif call SetBuildUnit(1, SupportCaster) call SetBuildUnit(3, Tower) call SetBuildUnit(1, MainCaster) call SetBuildUnit(1, SpecializedBarracks) if GoldGuys2 > 0 then if twoharvs = true then call SetBuildUnit(GoldGuys1 + GoldGuys2, GoldHarvester) else if WoodGuys2 > 0 then call SetBuildUnit(GoldGuys1 + GoldGuys2 + WoodGuys1 + WoodGuys2, GoldHarvester) else call SetBuildUnit(GoldGuys1 + GoldGuys2 + WoodGuys1, GoldHarvester) endif endif endif call SetBuildUnit(2, SiegeRanged) call SetBuildUnit(5, OwnageMelee) if (not KeepBasicMelee) then call SetBuildUnit(6, OwnageMelee) endif if MeleeDifficulty() == MELEE_INSANE and Heroes > 2 then //3 heroes? 1337sauce call SetBuildUnit(1, hero_id3) if (not KeepBasicMelee) then call SetBuildUnit(7, OwnageMelee) else call SetBuildUnit(6, OwnageMelee) endif endif call SetBuildUnit(1, FlyingBarracks) call SetBuildUnit(3, AirGround) call SetBuildUnit(3, AirAir) endfunction function UpgradePriorities takes nothing returns nothing //Blacksmith upgrades if GetUnitCountDone(Blacksmith) > 0 then if HallCount(HallTier3, true) > 0 then call SetBuildUpgr(3, AttackUpgrade1) call SetBuildUpgr(3, AttackUpgrade2) call SetBuildUpgr(3, DefenseUpgrade1) call SetBuildUpgr(3, DefenseUpgrade2) call SetBuildUpgr(3, BuildingDefenseUpgrade) call SetBuildUpgr(2, LumberHarvestUpgrade) elseif HallCount(HallTier2, true) > 0 then call SetBuildUpgr(2, AttackUpgrade1) call SetBuildUpgr(2, AttackUpgrade2) call SetBuildUpgr(2, DefenseUpgrade1) call SetBuildUpgr(2, DefenseUpgrade2) call SetBuildUpgr(2, BuildingDefenseUpgrade) call SetBuildUpgr(1, LumberHarvestUpgrade) else call SetBuildUpgr(1, AttackUpgrade1) call SetBuildUpgr(1, AttackUpgrade2) call SetBuildUpgr(1, DefenseUpgrade1) call SetBuildUpgr(1, DefenseUpgrade2) call SetBuildUpgr(1, BuildingDefenseUpgrade) endif endif //Barracks upgrades if GetUnitCountDone(Barracks) > 0 then if GetUnitCountDone(BasicMelee) > 2 then call SetBuildUpgr(1, BasicMeleeUpgrade) endif if HallCount(HallTier2, true) > 0 and GetUnitCountDone(BasicRanged) > 2 and GetUnitCountDone(Blacksmith) > 0 then call SetBuildUpgr(1, BasicRangedUpgrade) endif if HallCount(HallTier3, true) > 0 and GetUnitCountDone(OwnageMelee) > 2 and GetUnitCountDone(Blacksmith) > 0 and GetUnitCountDone(CasterBarracks) > 0 then call SetBuildUpgr(1, MiscUpgrade3) endif endif //CasterBarracks upgrades if GetUnitCountDone(CasterBarracks) > 0 then if HallCount(HallTier3, true) > 0 then if GetUnitCountDone(MainCaster) > 0 then call SetBuildUpgr(2, MainCasterUpgrade) endif if GetUnitCountDone(SupportCaster) > 0 then call SetBuildUpgr(2, SupportCasterUpgrade) endif if GetUnitCountDone(Shop) > 0 and GetUnitCountDone(T2Melee) > 2 then call SetBuildUpgr(1, MiscUpgrade2) endif else if GetUnitCountDone(MainCaster) > 0 then call SetBuildUpgr(1, MainCasterUpgrade) endif if GetUnitCountDone(SupportCaster) > 0 then call SetBuildUpgr(1, SupportCasterUpgrade) endif endif if GetUnitCountDone(T2Melee) > 2 then call SetBuildUpgr(1, MiscUpgrade1) endif endif //FlyingBarracks upgrades if GetUnitCountDone(FlyingBarracks) > 0 then if HallCount(HallTier3, true) > 0 then if GetUnitCountDone(CasterBarracks) > 0 then if GetUnitCountDone(Blacksmith) > 0 and GetUnitCountDone(AirGround) > 0 then call SetBuildUpgr(1, MiscUpgrade5) endif if GetUnitCountDone(Shop) > 0 then if GetUnitCountDone(AirAir) > 0 then call SetBuildUpgr(1, MiscUpgrade4) endif if GetUnitCountDone(AirGround) > 0 then call SetBuildUpgr(1, MiscUpgrade6) endif endif endif endif endif //SpecializedBarracks upgrades if GetUnitCountDone(SpecializedBarracks) > 0 then if HallCount(HallTier3, true) > 0 then if GetUnitCountDone(Blacksmith) > 0 and GetUnitCountDone(SiegeRanged) > 0 then call SetBuildUpgr(1, MiscUpgrade7) endif if GetUnitCountDone(CasterBarracks) > 0 and GetUnitCountDone(MiscUnit1) > 0 then call SetBuildUpgr(1, MiscUpgrade9) endif if GetUnitCountDone(Shop) > 0 and GetUnitCountDone(MiscUnit2) > 0 then call SetBuildUpgr(1, MiscUpgrade10) endif endif endif //Misc upgrades if HallCount(Hall, true) > 0 then if HallCount(HallTier2, true) > 0 and GetUnitCountDone(Shop) > 0 then call SetBuildUpgr(1, MiscUpgrade8) endif if GetUnitCountDone(Shop) > 0 then call SetBuildUpgr(1, MiscUpgrade11) endif endif endfunction function GuysAtWork takes nothing returns nothing local integer mine loop call UpdateConditions() call ClearHarvestAI() set mine = TownWithMine() call HarvestGold(mine + 0, GoldGuys1) call HarvestWood(0, WoodGuys1) if GoldGuys2 != 0 and GetMinesOwned() >= 2 then call HarvestGold(mine + 1, GoldGuys2) endif if WoodGuys2 != 0 then call HarvestWood(0, WoodGuys2) endif call BuildPriorities() call UpgradePriorities() call Sleep(2) endloop endfunction //*************************************************************************** //* //* Attacking //* //*************************************************************************** //=========================================================================== // Returns true if the minimum forces for an attack exist //=========================================================================== function HaveMinimumAttackers takes nothing returns boolean // Check for attack wave limit if (attackWave > 2) then return false endif return CanAttack endfunction //=========================================================================== // Assigns units to attack based on the given attack group //=========================================================================== function PrepareAttackGroup takes integer groupID returns nothing // Attack Group #1: Minimum Attack if (groupID == 1) then call SetAssaultGroup(GetUnitCountDone(hero_id), -1, hero_id) call SetAssaultGroup(GetUnitCountDone(BasicRanged), -1, BasicRanged) call SetAssaultGroup(GetUnitCountDone(BasicMelee), -1, BasicMelee) if (FoodCap() >= AIHasOwnageMelee) then call SetAssaultGroup(MinimumForceOwnageMelee, MinimumForceOwnageMelee, OwnageMelee) endif if (FoodCap() >= AIHasT2Melee) and T2MeleeExists then call SetAssaultGroup(MinimumForceT2Melee, MinimumForceT2Melee, T2Melee) endif // Attack Group #2: All Units elseif (groupID == 2) then call SetAssaultGroup(GetUnitCountDone(hero_id), -1, hero_id) if Heroes > 1 then //Just in case =) call SetAssaultGroup(GetUnitCountDone(hero_id2), -1, hero_id2) if Heroes > 2 then call SetAssaultGroup(GetUnitCountDone(hero_id3), -1, hero_id3) endif endif call SetAssaultGroup(GetUnitCountDone(BasicRanged), -1, BasicRanged) call SetAssaultGroup(GetUnitCountDone(BasicMelee), -1, BasicMelee) call SetAssaultGroup(GetUnitCountDone(OwnageMelee), -1, OwnageMelee) call SetAssaultGroup(GetUnitCountDone(SupportCaster), -1, SupportCaster) call SetAssaultGroup(GetUnitCountDone(MainCaster), -1, MainCaster) if T2MeleeExists then call SetAssaultGroup(GetUnitCountDone(T2Melee), -1, T2Melee) endif call SetAssaultGroup(GetUnitCountDone(AirGround), -1, AirGround) call SetAssaultGroup(GetUnitCountDone(AirAir), -1, AirAir) call SetAssaultGroup(GetUnitCountDone(SiegeRanged), -1, SiegeRanged) call SetAssaultGroup(GetUnitCountDone(MiscUnit1), -1, MiscUnit1) call SetAssaultGroup(GetUnitCountDone(MiscUnit2), -1, MiscUnit2) endif endfunction //=========================================================================== // Prepares an attack group based on the current attack wave //=========================================================================== function PrepareForces takes nothing returns nothing if (attackWave == 1) then call PrepareAttackGroup(1) elseif (attackWave == 2) then call PrepareAttackGroup(2) endif endfunction //=========================================================================== // Sleep delays for each attack wave //=========================================================================== function AttackWaveDelay takes integer inWave returns nothing if (inWave < nextDelay) then return endif if (inWave == 1) then call Sleep(2) endif set nextDelay = inWave + 1 endfunction //=========================================================================== // Advances attack wave counter //=========================================================================== function AttackWaveUpdate takes nothing returns nothing call AttackWaveDelay(attackWave) set attackWave = attackWave + 1 if (attackWave > 2) then set attackWave = 2 set nextDelay = attackWave + 1 endif endfunction //=========================================================================== // Basic attack functionality //=========================================================================== function AttackTarget takes unit target, boolean addAlliance returns nothing if (target == null) then return endif if (addAlliance) then call SetAllianceTarget(target) endif call FormGroup(3, true) call AttackMoveKillA(target) if (not addAlliance) then call SetAllianceTarget(null) endif endfunction //=========================================================================== // Initiates an attack based on target priorities //=========================================================================== function LaunchAttack takes nothing returns nothing local unit target = null local boolean setAlly = true // Don't launch any attack while town is threatened if (TownThreatened()) then call Sleep(2) return endif // Target Priority #1 = Helping an ally Assault/Defence if (target == null) then set target = GetAllianceTarget() if (target != null) then set setAlly = false endif endif // Target Priority #2 = Preparing an expansion if FoodUsed() >= Food4Exp then if (target == null) then set target = GetExpansionFoe() endif endif // Target Priority #3 = Woot, MegaTarget? (MegaTarget is the enemy's main) if FoodUsed() >= Food4Attack then if (target == null) then set target = GetMegaTarget() endif // Target Priority #4 = Either enemy expansions or an enemy base if (target == null) then set target = GetEnemyExpansion() if (target == null) then call StartGetEnemyBase() loop exitwhen (not WaitGetEnemyBase()) call SuicideSleep(1) endloop set target = GetEnemyBase() endif endif endif // Target Priority #5 = Small creep camps if FoodUsed() < Food4Attack then if target == null then set target = GetCreepCamp(0, 9, false) endif endif // Target Priority #6 = Huge creep camps if FoodUsed() >= Food4Attack then if (target == null) then set target = GetCreepCamp(10, 100, true) endif endif // Target Priority #7 = Goblin Zeppelin // if ((GetUnitCount('nzep') < 1)) then // if (target == null) then // call PurchaseZeppelin() // return // endif // endif // Attack the target and increment attack wave if (target != null) then call AttackTarget(target, setAlly) call AttackWaveUpdate() else // If no target was found, sleep a bit before trying again call Sleep(20) endif endfunction //=========================================================================== // Determines all attacking assignments //=========================================================================== function AttackAssignment takes nothing returns nothing local integer n = 0 call StaggerSleep(0, 2) if (attackWave == 1) then call AttackWaveDelay(0) endif loop call UpdateConditions() if (HaveMinimumAttackers() and not CaptainRetreating()) then if n == 2 then call Sleep(2) set n = 0 else set n = n + 1 call RemoveInjuries() call InitAssaultGroup() call PrepareForces() call LaunchAttack() endif else call Sleep(2) endif endloop endfunction //*************************************************************************** //* //* Main Entry Point //* //*************************************************************************** //=========================================================================== function main takes nothing returns nothing set ai_player = Player(GetAiPlayer()) set MinesToOwn = 1 + MeleeDifficulty() set DifficultyName[1] = "(Easy)" set DifficultyName[2] = "(Normal)" set DifficultyName[3] = "(Insane)" if WantName then if WantDifficultyInName then call SetPlayerName(ai_player, Name + " " + DifficultyName[MeleeDifficulty()]) else call SetPlayerName(ai_player, Name) endif endif call InitOptions() call PickRacialHero() call SetSkills() call CreateCaptains() call StandardAI(function SkillArrays, function GuysAtWork, function AttackAssignment) if IsAmphibious then call SetAmphibious() endif call PlayGame() endfunction |
| 06-18-2011, 03:26 PM | #2 |
If there's no one able/willing to moderate this, may I suggest sticking this resource into the "Triggers & Scripts" section? |
| 06-18-2011, 06:20 PM | #3 | |
Quote:
No contributory comment, sorry, I'm a dummy when it comes to JASS, vJass, and even GUI. (And other coding languages) I just felt the need to comment, because you seem to have put quite a lot of effort into this. :3 |
| 06-18-2011, 07:26 PM | #4 |
You bet! =D I spent countless hours making it this as automatized as possible with my limited JASS skills, but it's been an investment more than a loss of time. Aaand... off for saturday night! |
| 07-15-2011, 04:39 PM | #5 |
Update! I noticed I forgot to implement a functionality: now the AI will create harvesters automatically using the number variables for them, instead of hardcoded numbers... dumb me, the infrastructure for this was all set, but it seems like I never got around to make use of it. This means that the version number has been bumped up. (Now it's v0.4.1) (And you believe me when I say that the AI I'm coding with this has took me less than 1 hour to set up and now I'm testing it?) |
