Advertisement
mikeyy

AIGlobals.lua

Jun 19th, 2011
558
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 54.78 KB | None | 0 0
  1. -- [MOD]  Many priorities have been changed to control what the AI purchases.
  2. -- Citidel upgrades have a custom priority function to match the built in custom priority function
  3. -- With that Citiadel upgrade priorities can dynamically change based on the world state (warrank, warscore, gold, etc)
  4. -- Most items have been zeroed to allow each character build to set priority by items it uses
  5. -- RandomItemWeights added to end of file.  These priorities are added to the globals when a build does not have custom items priorities.
  6.  
  7.  
  8. --[version .24] added following sections to make citadel upgrades more dynamic
  9. --[MOD] TE Common item priorities.
  10.  
  11. local allHeroes= {
  12.     hema01 = {DisplayName = 'Torch Bearer', HeroType = 'Assassin'},
  13.     hqueen = {DisplayName = 'Queen of Thorns', HeroType = 'General'},
  14.     hepa01 = {DisplayName = 'Unclean Beast', HeroType = 'Assassin'},
  15.     hvampire = {DisplayName = 'Lord Erebus', HeroType = 'General'},
  16.     hsedna = {DisplayName = 'Sedna', HeroType = 'General'},
  17.     hgsa01 = {DisplayName = 'Regulus', HeroType = 'Assassin'},
  18.     hoak = {DisplayName = 'Oak', HeroType = 'General'},
  19.     hrook = {DisplayName = 'Rook', HeroType = 'Assassin'},
  20.     hoculus = {DisplayName = 'Oculus', HeroType = 'General'},
  21.     hdemon = {DisplayName = 'Demon Assassin', HeroType = 'Assassin'},
  22. }
  23.  
  24.  
  25. local Game = import('/lua/game.lua')
  26. local Upgrades = import('/lua/common/CitadelUpgrades.lua').Upgrades
  27. local AIShop = import('/lua/sim/ai/AIShopUtilities.lua')
  28. --Utility functions for expanding PriorityFunction versatility
  29. ---- ShouldAssignHealer = function(unit, healer, assignee)
  30.     ---- if not assignee or assignee:IsDead() or not healer or healer:IsDead() then
  31.         ---- return false
  32.     ---- end
  33.     ---- if not assignee.AIHealers then
  34.         ---- return true
  35.     ---- else
  36.         ---- local healertype = healer:GetBlueprint().BlueprintId --unused; for healer type comp checks
  37.         ---- local maxhealers, currenthealers = 2, 0
  38.         ---- for army, curhealer in assignee.AIHealers do
  39.             ---- if curhealer and not curhealer:IsDead() then
  40.                 ---- currenthealers = currenthealers + 1
  41.             ---- end
  42.         ---- end
  43.         ---- return currenthealers < maxhealers
  44.     ---- end
  45. ---- end
  46.  
  47. ---- AssignHealer = function(unit, healer, assignee)
  48.     ---- if ShouldAssignHealer(unit, healer, assignee) then
  49.         ---- if not assignee.AIHealers then
  50.             ---- assignee.AIHealers = {}
  51.         ---- end
  52.         ---- assignee.AIHealers[unit:GetArmy()] = healer
  53.         ---- IssueGuard({healer}, assignee) --I don't recall the syntax, this may be wrong
  54.         ---- --add OnKilled callbacks to assignee and healer(?) here?
  55.         ---- return true
  56.     ---- else
  57.         ---- return false
  58.     ---- end
  59. ---- end
  60.  
  61.  
  62. function teamIdolCount (unit, item, shop)
  63.     local allyGenerals = {}
  64.     local myBrain = unit:GetAIBrain()
  65.  
  66.     for k, brain in ArmyBrains do
  67.         if brain.Score.HeroId and IsAlly(myBrain:GetArmyIndex(), brain:GetArmyIndex()) then
  68.             if allHeroes[brain.Score.HeroId].HeroType == 'General' then
  69.                 local heroUnit = brain:GetListOfUnits(categories.HERO, false)
  70.                 --WARN('General ' .. brain.Score.HeroId .. ' = ' .. allHeroes[brain.Score.HeroId].DisplayName)
  71.                 table.insert(allyGenerals,  heroUnit[1])
  72.             end
  73.         end
  74.     end
  75.  
  76.     local myCount = 0
  77.     for k, hero in allyGenerals do
  78.         if AIShop.UnitHasItem(hero, item, shop) then
  79.             myCount = myCount + 1
  80.         end
  81.     end
  82.  
  83.     return { Count = myCount, Generals = table.getn(allyGenerals) }
  84. end
  85.  
  86. function highGold(unit)
  87.     local goldTable = {}
  88.     local aiBrain = unit:GetAIBrain()
  89.  
  90.     --Make sure we have the most gold of the AIs on our team
  91.  
  92.     for k, brain in ArmyBrains do
  93.         if brain.Score.HeroId and IsAlly(aiBrain:GetArmyIndex(), brain:GetArmyIndex()) and brain.BrainController != 'Human' then
  94.             table.insert(goldTable, {Army = brain:GetArmyIndex(), Gold = brain.mGold  })
  95.         end
  96.     end
  97.     table.sort(goldTable, sort_down_by 'Gold' )
  98.  
  99.     if goldTable[1].Army == aiBrain:GetArmyIndex() then
  100.         return true
  101.     else
  102.         return false
  103.     end
  104. end
  105.  
  106. --Mithy: New system for determining which upgrade an AI should be saving for, if any
  107. --This is only run once per item or upgrade shopping check
  108.  
  109. --Map table for upgrades to save for, and from what rank / enemy rank
  110. --Rank is the own War Rank to begin saving for this upgrade
  111. --ERank an optional enemy War Rank at which to begin saving
  112. --EHas is an optional bool that tells the AI to save if the enemy has this upgrade
  113. -- all of these conditions are OR; any of them will trigger saving
  114. -- item cost mod (e.g. coin purse) is taken into account when determining how much to save
  115. SaveForUpgrades = {
  116.     [1] = { Name = 'CGoldIncome01', Rank = 2 },
  117.     [2] = { Name = 'CTroopNumber03', Rank = 6, ERank = 7, EHas = true },
  118.     [3] = { Name = 'CTroopNumber05', Rank = 6, ERank = 7, EHas = true },
  119.     [4] = { Name = 'CTroopNumber04', Rank = 7 },
  120.     [5] = { Name = 'CTroopNumber06', Rank = 9 },
  121. }
  122. --Table for holding upcoming upgrades
  123. local upgradeQueue = false
  124.  
  125. --Returns a number corresponding to this AI's current gold ranking among team AIs
  126. function GetGoldRank(unit, brain)
  127.     local goldTable = {}
  128.     for k, abrain in ArmyBrains do
  129.         if not abrain.TeamBrain and abrain.BrainController == 'AI' and IsAlly(brain:GetArmyIndex(), abrain:GetArmyIndex()) then
  130.             table.insert(goldTable, {Army = abrain:GetArmyIndex(), Gold = abrain.mGold})
  131.         end
  132.     end
  133.     if table.getn(goldTable) < 2 then
  134.         return 1
  135.     else
  136.         table.sort(goldTable, sort_down_by 'Gold')
  137.         return table.find(goldTable, brain:GetArmyIndex(), function(a, b) return a.Army == b end)
  138.     end
  139.     return false
  140. end
  141.  
  142. --Main function for handling save logic; returns false, or upgrade name and upgrade cost
  143. function SaveForUpgrade(unit, brain)
  144.     LOG("SaveForUpgrade: "..repr(brain.Nickname).." / "..repr(unit:GetUnitId()).." @ "..repr(GetMinute()))
  145.     local goldRank = GetGoldRank(unit, brain)
  146.     local warRank = brain.Score.WarRank
  147.     local enemyRank = GetEnemyTeamBrain(unit).Score.WarRank
  148.     LOG("\tGold Rank: "..repr(goldRank)..", War Rank: "..repr(warRank)..", Enemy War Rank: "..repr(enemyRank))
  149.  
  150.     --Deferred init for the upgrade queue, to allow other mods to hook SaveForUpgrades
  151.     if upgradeQueue == false then
  152.         LOG("\tInitializing upgrade queue..")
  153.         --Assign costs on startup
  154.         for num, upgrade in SaveForUpgrades do
  155.             upgrade.Cost = UpgradeCost(upgrade.Name)
  156.         end
  157.         --Then copy the map table to the queue
  158.         upgradeQueue = table.deepcopy(SaveForUpgrades)
  159.     end
  160.  
  161.     --Prune purchased upgrades
  162.     while TeamHasUpgrade(unit, upgradeQueue[1].Name) do
  163.         LOG("\tTeam has upgrade "..repr(upgradeQueue[1].Name)..", removing from queue..")
  164.         table.remove(upgradeQueue, 1)
  165.     end
  166.  
  167.     --Get a list of upgrades that we should be saving for now
  168.     local currentUpgrades = {}
  169.     LOG("\tUpgrades to save for:")
  170.     for num, data in upgradeQueue do
  171.         if (data.Rank and warRank >= data.Rank) or (data.ERank and enemyRank >= data.ERank) or (data.EHas and EnemyHasUpgrade(unit, data.Name)) then
  172.             LOG("\t\t"..repr(data.Name).." - "..repr(data.Cost))
  173.             table.insert(currentUpgrades, table.copy(data))
  174.         end
  175.     end
  176.     if table.getn(currentUpgrades) < 1 then
  177.         LOG("\t\t(none)")
  178.     end
  179.  
  180.     --Return which one this AI should save for, if any
  181.     local saveFor = currentUpgrades[goldRank]
  182.     if saveFor then
  183.         LOG("\tSaving for upgrade "..repr(saveFor.Name)..", cost "..repr(saveFor.Cost))
  184.         return saveFor.Name, saveFor.Cost
  185.     else
  186.         LOG("\tNot saving.")
  187.         return false
  188.     end
  189. end
  190.  
  191. function GetDeathMult()
  192.     return Game.GameData.DeathPenaltyMultiplier[ScenarioInfo.Options.DeathPenalty or 'Normal']
  193. end
  194.  
  195. function GetGoldMult()
  196.     return Game.GameData.GoldIncomeMultiplier[ScenarioInfo.Options.GoldIncome or 'Normal']
  197. end
  198.  
  199. function GetXPMult()
  200.     return Game.GameData.ExperienceMultiplier[ScenarioInfo.Options.ExperienceRate or 'Normal']
  201. end
  202.  
  203. function GetMinute()
  204.     return math.floor(GetGameTimeSeconds() / 60)
  205. end
  206.  
  207. function IsGeneral(unit)
  208.     return EntityCategoryContains(categories.GENERAL, unit)
  209. end
  210.  
  211. function IsAssassin(unit)
  212.     return EntityCategoryContains(categories.ASSASSIN, unit)
  213. end
  214.  
  215. --Returns AI difficulty level, 1 for Easy, 4 for Nightmare
  216. function GetAIDifficulty(unit)
  217.     return ScenarioInfo.ArmySetup[unit:GetAIBrain().Name].Difficulty
  218. end
  219.  
  220. function UpgradeCost(upgradeName)
  221.     if Upgrades.Tree[upgradeName] then
  222.         return Upgrades.Tree[upgradeName].Cost
  223.     else
  224.         WARN("AIGlobals.UpgradeCost -- Tried to get cost of non-existent upgrade '"..upgradeName.."'")
  225.         return 0
  226.     end
  227. end
  228.  
  229. --Returns a fractional modifier from 0 to 1 based on the provided demigod's gold reserves, starting at the minimum specified
  230. --amount of gold and ending at the min amount * rec multiplier.  If the rec multiplier is not specified, it defaults to 2.
  231. function GoldThreshold(unit, min, rec)
  232.     rec = min * (rec or 2)
  233.     return math.min(1, math.max(0, unit:GetGold() - min) / (rec - min))
  234. end
  235.  
  236. --Get our team's average hero level
  237. function GetAverageLevel(unit)
  238.     local levels, heroes = unit.Score.HeroLevel, 1
  239.     for k, brain in unit:GetAIBrain():GetAlliedArmies() do
  240.         if not brain.IsTeamArmy then
  241.             heroes = heroes + 1
  242.             levels = levels + brain.Score.HeroLevel
  243.         end
  244.     end
  245.     return math.floor( (levels / heroes) + 0.5 )
  246. end
  247.  
  248. --Get our team's total deaths
  249. function GetTeamDeaths(unit)
  250.     local deaths = unit.Score.HeroDeaths
  251.     for k, brain in unit:GetAIBrain():GetAlliedArmies() do
  252.         if not brain.IsTeamArmy then
  253.             deaths = deaths + brain.Score.HeroDeaths
  254.         end
  255.     end
  256.     return deaths
  257. end
  258.  
  259. --Get our team's citadel health fraction
  260. function GetCitadelHealth(unit)
  261.     local cithealth = false
  262.     local citadel = unit:GetAIBrain():GetStronghold()
  263.  
  264.     if citadel then
  265.         cithealth = citadel:GetHealth() / citadel:GetMaxHealth()
  266.     end
  267.  
  268.     return cithealth
  269. end
  270.  
  271. function GetEnemyTeamBrain(unit)
  272.     local unitbrain = unit:GetAIBrain()
  273.  
  274.     if not unitbrain.EnemyTeamBrain then
  275.         for k, brain in ArmyBrains do
  276.             if brain.TeamBrain and IsEnemy(unit:GetArmy(), brain:GetArmyIndex()) then
  277.                 unitbrain.EnemyTeamBrain = brain
  278.                 break
  279.             end
  280.         end
  281.     end
  282.  
  283.     return unitbrain.EnemyTeamBrain
  284. end
  285.  
  286. --Used to get info on enemy citadel upgrades
  287. function HasUpgradeByTeamBrain(brain, upgradeName)
  288.     local upgradesTable = brain:GetStronghold().Sync.Upgrades
  289.  
  290.     if upgradesTable then
  291.         for k,v in upgradesTable do
  292.             if v == upgradeName then
  293.                 return true
  294.             end
  295.         end
  296.     end
  297.  
  298.     return false
  299. end
  300.  
  301. --Check our team's upgrades
  302. function TeamHasUpgrade(unit, upgradeName)
  303.     local hasupgrade = false
  304.     local tBrain = unit:GetAIBrain():GetTeamArmy()
  305.  
  306.     if tBrain then
  307.         hasupgrade = HasUpgradeByTeamBrain(tBrain, upgradeName)
  308.     end
  309.  
  310.     return hasupgrade
  311. end
  312.  
  313. --Check enemy team's upgrades
  314. function EnemyHasUpgrade(unit, upgradeName)
  315.     local hasupgrade = false
  316.     local etBrain = GetEnemyTeamBrain(unit)
  317.  
  318.     if etBrain then
  319.         hasupgrade = HasUpgradeByTeamBrain(etBrain, upgradeName)
  320.     end
  321.  
  322.     return hasupgrade
  323. end
  324.  
  325. TeleportAbilities = {
  326.     'AchievementTeleport',
  327.     'Item_Consumable_010',
  328. }
  329.  
  330. StunBuffs = {
  331.     'Item_Artifact_020',
  332. }
  333.  
  334. DefaultDisables = {
  335.     'Purchase Base Item',
  336.     'Sell Item - Clickables',
  337.     'Sell Item - Equipment',
  338.     'Sell Item - Generals',
  339.     'Purchase Base Item - Use Sell Refund',
  340.     'Purchase Citadel Upgrade',
  341. }
  342.  
  343. HealthDisables = {
  344.     'Use Health Potion',
  345.     'Use Regeneration of the Seraphim',
  346.     'Use Heart of Life',
  347. }
  348.  
  349. EnergyDisables = {
  350.     'Use Energy Potion',
  351.     'Use Cape of Plentiful Mana',
  352.     'Use Blade of the Serpent',
  353.     'Use Purified Essence of Magic',
  354.     'Use Magus Rod',
  355.     'Use Heart of Life',
  356. }
  357.  
  358. ShopDisables = {
  359.     'Purchase Base Item',
  360.     'Purchase Base Item - Use Sell Refund',
  361.     'Purchase Citadel Upgrade',
  362. }
  363.  
  364. MoveDisables = {
  365.     'Move to healers',
  366.     'MoveToNearbyTower',
  367.     'Back Away from enemy tower',
  368.     'Back Away from combat',
  369.     'MoveToPortalSpawnInfantry',
  370.     'MoveToEnemyInfantry',
  371.     'Move - Squad defined location',
  372.     'Move - Infantry near Squad defined location',
  373.     'Move - Defense near Squad defined location',
  374.     'Teleport to Structure near Squad Location',
  375.     'Move To Squad Target',
  376.     'Move To Health Statue',
  377.     'Capture Closest Flag',
  378.     --'Capture Portal',
  379.     'Capture Anything',
  380.     'Teleport to Portal',
  381.     'Teleport to Tower',
  382.     'Structural Transfer',
  383. }
  384.  
  385. SprintDisables = {
  386.     'Sprint - Flee',
  387.     'Sprint - Attack',
  388. }
  389.  
  390. InvisibilityDisables = {
  391.     'Cloak of Invisibility - Flee',
  392. }
  393.  
  394. AttackDisables = {
  395.     'AttackClosestInfantry',
  396.     'Attack Closest Infantry with friendly Creep',
  397.     'Attack from back line',
  398.     'Attack Squad Target',
  399.     'Attack Closest Hero - Ranged Hero',
  400.     'Attack Closest Hero - Melee Hero',
  401.     'AttackClosestTower',
  402.     'Attack Closest Building',
  403.  
  404. }
  405.  
  406. FirstDepthDisables = {
  407.     'Two Second Wait',
  408.     'MoveToPortalSpawnInfantry',
  409.     'MoveToEnemyInfantry',
  410.     'Teleport to Health Statue',
  411.     'MoveToNearbyTower',
  412.     'Back Away from enemy tower',
  413.     'Back Away from combat',
  414.     'Use Staff of Renewal',
  415.     'Use Purified Essence of Magic',
  416. }
  417.  
  418. StatPrefix = 'AI Systems_'
  419.  
  420. MaximumActions = 400
  421.  
  422. --==== PING GLOBALS ==== --
  423. AIPingDuration = 31
  424. AIPingMaximumWeight = 37
  425. AIPingRadiusDefault = 24 * 24
  426. AIPingRadiusLane = 32 * 32
  427.  
  428. --==== MISC GLOBALS ==== --
  429. AISquadLocationDistance = 25
  430. AISquadLocationDistSq = 625
  431.  
  432. --=======================
  433. --AI Calculations tables
  434. --=======================
  435.  
  436. --This is a table we use to store out damage so that we can calculate
  437. --the amount of damage an ability will do only once;
  438. --ie - Foul Grasp does not have a single amount of damage; we calc it only once for all heroes
  439. AbilityDamage = {}
  440.  
  441. --------------------------------------------------------------------------------
  442. --ITEMS
  443. --------------------------------------------------------------------------------
  444. ItemWeights = {
  445.  
  446.     ----------------------------------------------
  447.     --CONSUMABLES
  448.     ----------------------------------------------
  449.  
  450.     --Health Potion
  451.     --Use: Heal 750 health.
  452.     Item_Health_Potion = {
  453.         --MaxPurchase = 1,
  454.         --sellpriority = 1,
  455.         PriorityFunction = function(unit, itemCount)
  456.             if unit:GetMaxHealth() > 3500 then
  457.                 return 0
  458.             end
  459.  
  460.             if itemCount == 0 then
  461.                 return 7
  462.             elseif itemCount == 1 then
  463.                 return 4
  464.             else
  465.                 return 0
  466.             end
  467.         end,
  468.     },
  469.  
  470.     --Robust Health Potion
  471.     --Use: Heal 3000 health.
  472.     Item_Large_Health_Potion = {
  473.         --MaxPurchase = 2,
  474.         --sellpriority = 1,
  475.         PriorityFunction = function(unit, itemCount)
  476.             if unit:GetMaxHealth() < 3500 then
  477.                 return 0
  478.             end
  479.  
  480.             if itemCount == 0 then
  481.                 return 7
  482.             elseif itemCount == 1 then
  483.                 return 4
  484.             else
  485.                 return 0
  486.             end
  487.         end,
  488.     },
  489.  
  490.     --Mana Potion
  491.     --Use: Restore 1000 Mana
  492.     Item_Mana_Potion = {
  493.         --MaxPurchase = 2,
  494.         --sellpriority = 1,
  495.         PriorityFunction = function(unit, itemCount)
  496.             if unit:GetMaxEnergy() > 4000 then
  497.                 return 0
  498.             end
  499.  
  500.             if itemCount == 0 then
  501.                 return 0
  502.             elseif itemCount == 1 then
  503.                 return 0
  504.             else
  505.                 return 0
  506.             end
  507.         end,
  508.     },
  509.  
  510.     --Robust Mana Potion
  511.     --Use: Restore 2500 Mana
  512.     Item_Large_Mana_Potion = {
  513.         --MaxPurchase = 2,
  514.         --sellpriority = 1,
  515.         PriorityFunction = function(unit, itemCount)
  516.             if unit:GetMaxEnergy() < 4000 then
  517.                 return 0
  518.             end
  519.  
  520.             if itemCount == 0 then
  521.                 return 0
  522.             elseif itemCount == 1 then
  523.                 return 0
  524.             else
  525.                 return 0
  526.             end
  527.         end,
  528.     },
  529.  
  530.     --Rejuvenation Elixir
  531.     --Use: Restore 750 health and 750 Mana.
  532.     Item_Rejuv_Elixir = {
  533.         --MaxPurchase = 1,
  534.         --sellpriority = 1,
  535.         PriorityFunction = function(unit, itemCount)
  536.             if unit:GetMaxEnergy() > 3000 or unit:GetMaxHealth() > 3000 then
  537.                 return 0
  538.             end
  539.  
  540.             if itemCount == 0 then
  541.                 return 0
  542.             elseif itemCount == 1 then
  543.                 return 0
  544.             else
  545.                 return 0
  546.             end
  547.         end,
  548.     },
  549.  
  550.     --Robust Rejuvenation Elixir
  551.     --Use: Restore 1875 health and 1875 Mana.
  552.     Item_Large_Rejuv_Elixir = {
  553.         --MaxPurchase = 2,
  554.         --sellpriority = 1,
  555.         PriorityFunction = function(unit, itemCount)
  556.             if unit:GetMaxEnergy() < 3000 and unit:GetMaxHealth() < 3000 then
  557.                 return 0
  558.             end
  559.  
  560.             if itemCount == 0 then
  561.                 return 0
  562.             elseif itemCount == 1 then
  563.                 return 0
  564.             else
  565.                 return 0
  566.             end
  567.         end,
  568.     },
  569.  
  570.     --Scroll of Teleporting
  571.     --Use: Teleport to targeted friendly structure.
  572.     --[version .24] changed priority for itemCount and added warrank conditional statements
  573.     Item_Consumable_010 = {
  574.         --sellpriority = 10,
  575.         --MaxPurchase = 2,
  576.         PriorityFunction = function(unit, itemCount)
  577.             if itemCount == 0 and unit:GetAIBrain().Score.WarRank > 1 then
  578.                 return  25
  579.             elseif itemCount == 0 then
  580.                 return 8
  581.             end
  582.             if itemCount == 1 and unit:GetAIBrain().Score.WarRank > 1 then
  583.                 return  10
  584.             elseif itemCount == 1 then
  585.                 return 0
  586.             end
  587.             if itemCount == 2 and unit:GetAIBrain().Score.WarRank >= 8 then
  588.                 return 40
  589.             elseif itemCount == 2 then
  590.                 return 0
  591.             end
  592.  
  593.             return 0
  594.         end,
  595.     },
  596.  
  597.     --Totem of Revelation
  598.     --Use: Place an observer ward that can reveal cloaked enemies. Can also reveal mines.
  599.     Item_Consumable_020 = {
  600.         Priority = 0,
  601.     },
  602.  
  603. --   --Capture Lock
  604. --   --Use: Selected ally flag cannot be captured by the enemy for 30 seconds.
  605.      --[version .24] changed priority for itemCount and added warrank conditional statements
  606.     Item_Consumable_030 = {
  607.         --MaxPurchase = 2,
  608.         --Priority = 10,
  609.         --sellpriority = 10,
  610.  
  611.         PriorityFunction = function(unit, itemCount)
  612.             if itemCount == 0 and unit:GetAIBrain().Score.WarRank >= 7 then
  613.                 return 40
  614.             elseif itemCount == 0 and GetEnemyTeamBrain(unit).Score.WarRank >= 8 then
  615.                 return 40
  616.             elseif itemCount == 1 and unit:GetAIBrain().Score.WarRank >= 7 then
  617.                 return 40
  618.             elseif itemCount == 1 and GetEnemyTeamBrain(unit).Score.WarRank >= 8 then
  619.                 return 40
  620.             elseif itemCount == 2 and unit:GetAIBrain().Score.WarRank >= 9 then
  621.                 return 40
  622.             elseif itemCount == 2 and GetEnemyTeamBrain(unit).Score.WarRank >= 9 then
  623.                 return 40
  624.             else
  625.                 return 0
  626.             end
  627.         end,
  628.     },
  629.  
  630.     --Sludge Slinger
  631.     --Use: Decreases target's attack speed.
  632.     Item_Consumable_040 = {
  633.         --MaxPurchase = 1,
  634.         Priority = 0,
  635.     },
  636.  
  637.     --Wand of Speed
  638.     --Use: Increase Base Run Speed by 30%.
  639.     Item_Consumable_050 = {
  640.         Priority = 0,
  641.     },
  642.  
  643.     --Targeting Dummy
  644.     --Use: Draws fire from towers of light when placed nearby.
  645.     Item_Consumable_060 = {
  646.         Priority = 0,
  647.     },
  648.  
  649.     --Warpstone
  650.     --Use: Warp to a nearby location.
  651.     Item_Consumable_070 = {
  652.         Priority = 0,
  653.     },
  654.  
  655.     --Universal Gadget
  656.     --Use: Heal an allied unit for 500 or damage an enemy unit for 500.
  657.     Item_Consumable_080 = {
  658.         Priority = 0,
  659.     },
  660.  
  661.     --Restorative Scroll
  662.     --Use: Any negative effects on your army are removed.
  663.     Item_Consumable_090 = {
  664.         --MaxPurchase = 1,
  665.         Priority = 0,
  666.         GeneralItem = true,
  667.     },
  668.  
  669.     --Hex Scroll
  670.     --Use: Weapon damage dealt by the targeted Demigod and their army reduced by 25% for 10 seconds.
  671.     Item_Consumable_100 = {
  672.         --MaxPurchase = 1,
  673.         Priority = 0,
  674.     },
  675.  
  676.     --Sigil of Vitality
  677.     --Use: Temporarily increase Maximum Health by 50% for 10 seconds.
  678.     Item_Consumable_110 = {
  679.         --sellpriority = 10,
  680.         --MaxPurchase = 2,
  681.         PriorityFunction = function(unit, itemCount)
  682.             if unit:GetMaxHealth() < 4000 then
  683.                 return 0
  684.             end
  685.  
  686.             if itemCount == 0 then
  687.                 return 8
  688.             elseif itemCount == 1 then
  689.                 return 0
  690.             else
  691.                 return 0
  692.             end
  693.         end,
  694.     },
  695.  
  696.     --Twig of Life
  697.     --Use: Your army restores 25% of their maximum Health.
  698.     Item_Consumable_120 = {
  699.         Priority = 0,
  700.         GeneralItem = true,
  701.     },
  702.  
  703.     --Warlord's Punisher
  704.     --Use: Cast a bolt of lightning at the target, dealing 250 damage and arcing to nearby enemies. Demigods struck also lose 400 Mana.
  705.     Item_Consumable_130 = {
  706.         Priority = 0,
  707.     },
  708.  
  709.     --Magus Rod
  710.     --Use: The cost of abilities is reduced by 50% for 5 seconds.
  711.     Item_Consumable_140 = {
  712.         Priority = 0,
  713.     },
  714.  
  715.     --Orb of Defiance
  716.     --Use: Become invulnerable for 5 seconds. Cannot move, attack or use abilities.
  717.     --+500 Health
  718.     --+500 Armor
  719.     Item_Consumable_150 = {
  720.         Priority = 0,
  721.     },
  722.  
  723.  
  724.  
  725.     --Parasite Egg
  726.     --Use: Infest target Demigod with a parasite. Whenever you deal damage to that Demigod, their army takes damage as well. The effects lasts 10 seconds.
  727.     --+30 Weapon Damage
  728.     --+10% Attack Speed
  729.     Item_Consumable_170 = {
  730.         Priority = 0,
  731.     },
  732.  
  733.     ----------------------------------------------
  734.     --BREASTPLATES
  735.     ----------------------------------------------
  736.  
  737.     --Scalemail
  738.     --+600 Armor
  739.     Item_Chest_010 = {
  740.         Priority = 20,
  741.     },
  742.  
  743.     --Banded Armor
  744.     --+500 Hit Points
  745.     Item_Chest_020 = {
  746.         Priority = 25,
  747.     },
  748.  
  749.     --Nimoth Chest Armor
  750.     --+1100 Armor
  751.     --+10% Dodge
  752.     Item_Chest_030 = {
  753.         Priority = 40,
  754.     },
  755.  
  756. --0.26.40 - dropped priority from 40 to 35
  757.     --Hauberk of Life
  758.     --+750 Hit Points
  759.     --+20 Hit Points per second
  760.     Item_Chest_040 = {
  761.         Priority = 35,
  762.     },
  763.  
  764.     --Armor of Vengeance
  765.     --+1300 Armor
  766.     --When struck by melee attacks, wearers of this mystical armor reflect 50 damage back to the attacker.
  767.     Item_Chest_050 = {
  768.         Priority = 0,
  769.     },
  770.  
  771.     --Platemail of the Crusader
  772.     --+25 Hit Points per second
  773.     --15% chance on hit to heal 600 Hit Points
  774.     Item_Chest_060 = {
  775.         Priority = 0,
  776.     },
  777.  
  778.     --Groffling's Warplate
  779.     --+850 Hit Points
  780.     --+1500 Armor
  781.     --Armor proc chance on hit to gain a damage absorb
  782.     Item_Chest_070 = {
  783.         Priority = 0,
  784.     },
  785.  
  786.     --Godplate
  787.     --+1300 Hit Points
  788.     --+1000 Armor
  789.     --When struck by melee attacks, wearers of this mystical armor reflect 60 damage back to the attacker.
  790.     Item_Chest_080 = {
  791.     PriorityFunction = function(unit, itemCount)
  792.         if itemCount == 1 then
  793.             return 50
  794.         end
  795.  
  796.         if unit:GetAIBrain().mGold  >= 10000 then
  797.             return 50
  798.         else
  799.             return 0
  800.         end
  801.     end,
  802.     },
  803.  
  804.     --Duelist's Cuirass
  805.     --+350 Armor
  806.     --+500 Health
  807.     --5% chance deal a critical strike for 1.5x damage
  808.     Item_Chest_090 = {
  809.         Priority = 0,
  810.     },
  811.  
  812.     ----------------------------------------------
  813.     --HELMS
  814.     ----------------------------------------------
  815.  
  816.     --Scaled Helm
  817.     --+750 Mana
  818.     Item_Helm_010 = {
  819.         Priority = 20,
  820.     },
  821.  
  822.     --Plate Visor
  823.     --+30 Mana per second
  824.     Item_Helm_020 = {
  825.         Priority = 0,
  826.     },
  827.  
  828.     --Plenor Battlecrown
  829.     --+1000 Mana
  830.     ---25% to ability cooldowns
  831.     Item_Helm_030 = {
  832.         Priority = 35,
  833.     },
  834.  
  835.     --Vlemish Faceguard
  836.     --Increases the Mana Regeneration of you and nearby allied Demigods by 40 Mana per second.
  837.     Item_Helm_040 = {
  838.         Priority = 50,
  839.     },
  840.  
  841.     --Vinling Helmet
  842.     --+1500 Mana
  843.     --+30 Mana per second
  844.     --15% chance on hit to restore 700 Mana.
  845.     Item_Helm_050 = {
  846.         Priority = 0,
  847.     },
  848.  
  849.     --Hungarling's Crown
  850.     --Reduces the cost of abilities for you and all nearby Demigods by 35%.
  851.     Item_Helm_060 = {
  852.         Priority = 0,
  853.     },
  854.  
  855.     --Theurgist's Cap
  856.     --+10 Health Regeneration
  857.     --+50% Mana Regeneration
  858.     --5% chance on being hit to reduce the target's Health Regeneration by 50% and Mana Regeneration by 50% for 10 seconds.
  859.     Item_Helm_070 = {
  860.         Priority = 0,
  861.     },
  862.  
  863.     ----------------------------------------------
  864.     --BOOTS
  865.     ----------------------------------------------
  866.  
  867.     --Footman's Sabatons
  868.     --+10% Dodge
  869.     Item_Boot_010 = {
  870.         Priority = 0,
  871.     },
  872.  
  873.     --Boots of Speed
  874.     --+15% Base Run Speed
  875.     Item_Boot_020 = {
  876.         Priority = 0,
  877.     },
  878.  
  879.     --Assassin's Footguards
  880.     --+30 Mana per second
  881.     --+15% Dodge
  882.     Item_Boot_030 = {
  883.         Priority = 0,
  884.     },
  885. --0.26.40 - updated incorrect stats for unbreakable
  886.     --Unbreakable Boots
  887.     --+600 HP
  888.     --+5 HPS
  889.     --+800 Mana
  890.     Item_Boot_040 = {
  891.         Priority = 39,
  892.     },
  893.  
  894.  
  895. --[[ --removed by pacov
  896.     --Unbreakable Boots
  897.     --+360 Hit Points
  898.     --+540 Armor
  899.     Item_Boot_040 = {
  900.         PriorityFunction = function(unit, itemCount)
  901.             if GetGameTimeSeconds() < 20 then
  902.                 return 39
  903.             else
  904.                 return 30
  905.             end
  906.      end,
  907.     },
  908. --]]
  909.  
  910.  
  911.     --Journeyman Treads
  912.     --+340 Armor
  913.     --+15% Base Run Speed
  914.     --20% chance on hit to increase Base Run Speed by 50% for 10 seconds.
  915.     Item_Boot_050 = {
  916.         Priority = 45,
  917.     },
  918.  
  919.     --Desperate Boots
  920.     --+500 Armor
  921.     --+10% Attack Speed
  922.     --Whenever health is under 20%, Evasion is increased by 20%.
  923.     Item_Boot_060 = {
  924.         Priority = 0,
  925.     },
  926.  
  927.     --Ironwalkers
  928.     --Whenever Movement Speed is under 4, Armor is increased by 1000.
  929.     --+ 100 Minion Armor
  930.     Item_Boot_070 = {
  931.         Priority = 0,
  932.     },
  933.  
  934.     ----------------------------------------------
  935.     --GLOVES
  936.     ----------------------------------------------
  937.  
  938.     --Gauntlets of Brutality
  939.     --+50 Weapon Damage
  940.     Item_Glove_010 = {
  941.         Priority = 0,
  942.     },
  943.  
  944.     --Gladiator Gloves
  945.     --+5% Attack Speed
  946.     Item_Glove_020 = {
  947.         Priority = 0,
  948.     },
  949.  
  950.     --Gauntlets of Despair
  951.     --+8% Attack Speed
  952.     --15% chance on hit to drain 100 mana.
  953.     Item_Glove_030 = {
  954.         Priority = 0,
  955.     },
  956.  
  957.     --Wyrmskin Handguards
  958.     --20% chance on hit to eviscerate the target dealing 150 damage and reducing their Attack Speed and Base Run Speed 25%.
  959.     Item_Glove_040 = {
  960.         Priority = 0,
  961.         --AssassinItem = true,
  962.     },
  963.  
  964.     --Doomspite Grips
  965.     --+50 Weapon Damage
  966.     --+15% Attack Speed
  967.     --20% chance on hit to perform a cleaving attack, damaging nearby enemies.
  968.     Item_Glove_050 = {
  969.         Priority = 0,
  970.     },
  971.  
  972.     --Gloves of Fell-Darkur
  973.     --+75 Weapon Damage
  974.     --+10% Attack Speed
  975.     --20% chance on hit to unleash a fiery blast, dealing 175 damage.
  976.     Item_Glove_060 = {
  977.         Priority = 0,
  978.     },
  979.  
  980.     --Slayer's Wraps
  981.     --5% chance to crit for double damage
  982.     Item_Glove_070 = {
  983.         Priority = 0,
  984.     },
  985.  
  986.     ----------------------------------------------
  987.     --RINGS
  988.     ----------------------------------------------
  989.  
  990.     --Bloodstone Ring
  991.     --+15% Life Steal
  992.     Item_Ring_020 = {
  993.         Priority = 0,
  994.     },
  995.  
  996.     --Nature's Reckoning
  997.     --15% chance on hit to strike nearby enemies with lightning for 250 damage
  998.     Item_Ring_030 = {
  999.         Priority = 0,
  1000.     },
  1001.  
  1002.     --Ring of the Ancients
  1003.     --+500 Armor
  1004.     --+30 Weapon Damage
  1005.     --Increases experience gained by 10%.
  1006.     Item_Ring_040 = {
  1007.         Priority = 0,
  1008.     },
  1009.  
  1010.     --Narmoth's Ring
  1011.     --+15% Life Steal
  1012.     --When struck by melee attacks, the wearer reflects 90 damage back to the attacker.
  1013.     Item_Ring_050 = {
  1014.         Priority = 0,
  1015.     },
  1016.  
  1017.     --Forest Band
  1018.     --5% on attack to heal your army for 250 health.
  1019.     Item_Ring_060 = {
  1020.         Priority = 0,
  1021.         GeneralItem = true,
  1022.     },
  1023.  
  1024.     ----------------------------------------------
  1025.     --GENERALS
  1026.     ----------------------------------------------
  1027.  
  1028. --0.26.40 - dropped priority from 10 to 0
  1029.     --Minotaur Captain Idol I
  1030.     --Use: Summons the least amount of Minotaur Captains.
  1031.     Item_Minotaur_Captain_010 = {
  1032.         Priority = 0,
  1033.         --MinionDesire = 0.1,
  1034.     },
  1035. --0.26.40 - dropped priority from 15 to 5
  1036.     --Minotaur Captain Idol II
  1037.     --Use: Summons a moderate amount of Minotaur Captains.
  1038.     Item_Minotaur_Captain_020 = {
  1039.         Priority = 5,
  1040.         --MinionDesire = 0.25,
  1041.     },
  1042. --0.26.40 - dropped priority from 20 to 10
  1043.     --Minotaur Captain Idol III
  1044.     --Use: Summons the most amount of Minotaur Captains.
  1045.     Item_Minotaur_Captain_030 = {
  1046.         Priority = 10,
  1047.         --MinionDesire = 0.5,
  1048.     },
  1049. --0.26.40 - dropped priority from 25 to 15
  1050.     --Minotaur Captain Idol IV
  1051.     --Use: Summons the most amount of Minotaur Captains and passive bonuses.
  1052.     Item_Minotaur_Captain_040 = {
  1053.         Priority = 15,
  1054.         --MinionDesire = 0.75,
  1055.     },
  1056. --0.26.40 - dropped priority from 15 to 0
  1057.     --Siege Archer Idol I
  1058.     --Use: Summons the least amount of Siege Archers.
  1059.     Item_Siege_Archer_010 = {
  1060.         Priority = 0,
  1061.         --MinionDesire = 0.1,
  1062.     },
  1063.  
  1064.     --Siege Archer Idol II
  1065.     --Use: Summons a moderate amount of Siege Archers.
  1066.     Item_Siege_Archer_020 = {
  1067.         Priority = 20,
  1068.         --MinionDesire = 0.25,
  1069.     },
  1070.  
  1071.     --Siege Archer Idol III
  1072.     --Use: Summons the most amount of Siege Archers.
  1073.     Item_Siege_Archer_030 = {
  1074.         Priority = 25,
  1075.         --MinionDesire = 0.5,
  1076.     },
  1077.  
  1078.     --Siege Archer Idol IV
  1079.     --Use: Summons the most amount of Siege Archers and passive bonuses.
  1080.     Item_Siege_Archer_040 = {
  1081.         Priority = 30,
  1082.         --MinionDesire = 0.75,
  1083.     },
  1084.  
  1085.     --High Priest Idol I
  1086.     --Use: Summons the least amount of High Priests.
  1087.     Item_High_Priest_010 = {
  1088.         PriorityFunction = function(unit, itemCount)
  1089.             if GetGameTimeSeconds() < 30 then
  1090.                 return 40  --Tie with clerics for random select by Hard AI or above
  1091.             else
  1092.                 return 35
  1093.             end
  1094.         end,
  1095.         },
  1096.  
  1097.     --High Priest Idol II
  1098.     --Use: Summons a moderate amount of High Priests.
  1099.     Item_High_Priest_020 = {
  1100.         Priority = 40,
  1101.         },
  1102.  
  1103.     --High Priest Idol III
  1104.     --Use: Summons the most amount of High Priests.
  1105.     Item_High_Priest_030 = {
  1106.         Priority = 45,
  1107.         },
  1108.  
  1109.     --High Priest Idol IV
  1110.     --Use: Summons the most amount of High Priests and passive bonuses.
  1111.     Item_High_Priest_040 = {
  1112.     PriorityFunction = function(unit, itemCount)
  1113.         local idolsCount = teamIdolCount(unit, 'Item_High_Priest_040', 'ugbshop09')
  1114.         if idolsCount.Count == 0 or idolsCount.Generals - idolsCount.Count > 1 then
  1115.             return 50  -- +5 from High Priest to allow replacement.
  1116.         else
  1117.             return 41  -- Below High Priest priority to ensure High Priest is selected over bishops when all but one own bishops.
  1118.                        -- Set to 4 lower as at 5 or more lower Bishop would be sold for High Priest.
  1119.         end
  1120.      end,
  1121.     },
  1122.  
  1123.     ----------------------------------------------
  1124.     --ARTIFACT ITEMS
  1125.     ----------------------------------------------
  1126.  
  1127.     --Heart of Life
  1128.     --Use: Restore 3000 health and 3000 mana over 10 seconds. Any damage will break this effect.
  1129.     --+15 Health Regeneration
  1130.     --+50% Mana Regeneration
  1131.     Item_Consumable_160 = {
  1132.         PriorityFunction = function(unit, itemCount)
  1133.             if itemCount == 1 then
  1134.                 return 100
  1135.             end
  1136.  
  1137.             if unit:GetAIBrain().mGold  >= 10000 then
  1138.  
  1139.                 return 0
  1140.             else
  1141.                 return 0
  1142.             end
  1143.      end,
  1144.     },
  1145.  
  1146.  
  1147.  
  1148.     --Bracelet of Rage
  1149.     --Use: Nearby allied units gain +300% Weapon Damage for 15 seconds.
  1150.     Item_Artifact_010 = {
  1151.     PriorityFunction = function(unit, itemCount)
  1152.         if itemCount == 1 then
  1153.             return 100
  1154.         end
  1155.  
  1156.         if unit:GetAIBrain().mGold  >= 10000 then
  1157.             return 0
  1158.         else
  1159.             return 0
  1160.         end
  1161.      end,
  1162.     },
  1163.  
  1164.     --Mage Slayer
  1165.     --+20% Life Steal
  1166.     --40% chance on hit to stun target for 0.4 seconds.
  1167.     Item_Artifact_020 = {
  1168.     PriorityFunction = function(unit, itemCount)
  1169.         if itemCount == 1 then
  1170.             return 50
  1171.         end
  1172.  
  1173.         if unit:GetAIBrain().mGold  >= 13000 then
  1174.  
  1175.             return 0
  1176.         else
  1177.             return 0
  1178.         end
  1179.      end,
  1180.     },
  1181.  
  1182.     --Cloak of Invisibility
  1183.     --Use: Turn invisible for 20 seconds.
  1184.     Item_Artifact_030 = {
  1185.     PriorityFunction = function(unit, itemCount)
  1186.         if itemCount == 1 then
  1187.             return 100
  1188.         end
  1189.  
  1190.         if unit:GetAIBrain().mGold  >= 10000 then
  1191.             return 0
  1192.         else
  1193.             return 0
  1194.         end
  1195.     end,
  1196.     },
  1197.  
  1198.     --Cloak of Flames
  1199.     --Use: Cast a ring of fire around yourself, damaging enemies for 600 damage over 10 seconds.
  1200.     --+50% Attack Speed
  1201.     Item_Artifact_040 = {
  1202.     PriorityFunction = function(unit, itemCount)
  1203.         if itemCount == 1 then
  1204.             return 100
  1205.         end
  1206.  
  1207.         if unit:GetAIBrain().mGold  >= 10000 then
  1208.  
  1209.             return 0
  1210.         else
  1211.             return 0
  1212.         end
  1213.      end,
  1214.     },
  1215.  
  1216.     --Cloak of Elfinkind
  1217.     --Use: Warp to a targeted location.
  1218.     --+25% Dodge
  1219.     --+20% Base Run Speed
  1220.     Item_Artifact_050 = {
  1221.     PriorityFunction = function(unit, itemCount)
  1222.         if itemCount == 1 then
  1223.             return 100
  1224.         end
  1225.  
  1226.         if unit:GetAIBrain().mGold  >= 10000 then
  1227.             return 0
  1228.         else
  1229.             return 0
  1230.         end
  1231.     end,
  1232.     },
  1233.  
  1234.     --Unmaker
  1235.     --Use: Deal +300% Weapon Damage for 15 seconds.
  1236.     --15% chance to increase attack speed by 30% for 5 seconds.
  1237.     Item_Artifact_060 = {
  1238.     PriorityFunction = function(unit, itemCount)
  1239.         if itemCount == 1 then
  1240.             return 100
  1241.         end
  1242.  
  1243.         if unit:GetAIBrain().mGold  >= 10000 then
  1244.             return 0
  1245.         else
  1246.             return 0
  1247.         end
  1248.      end,
  1249.     },
  1250.  
  1251.     --Deathbringer
  1252.     --Use: Silence target, preventing any abilities for 8 seconds.
  1253.     --+125 Weapon Damage
  1254.     --+70 Mana per second
  1255.     Item_Artifact_070 = {
  1256.     PriorityFunction = function(unit, itemCount)
  1257.         if itemCount == 1 then
  1258.             return 100
  1259.         end
  1260.  
  1261.         if unit:GetAIBrain().mGold  >= 10000 then
  1262.             return 0
  1263.         else
  1264.             return 0
  1265.         end
  1266.      end,
  1267.     },
  1268.  
  1269.     --Stormbringer
  1270.     --+3000 Mana
  1271.     ---25% to ability cooldowns
  1272.     --100% chance on hit to gain 20% of your damage in mana.
  1273.     Item_Artifact_080 = {
  1274.     PriorityFunction = function(unit, itemCount)
  1275.         if itemCount == 1 then
  1276.             return 100
  1277.         end
  1278.  
  1279.         if unit:GetAIBrain().mGold  >= 10000 then
  1280.             return 0
  1281.         else
  1282.             return 0
  1283.         end
  1284.      end,
  1285.     },
  1286.  
  1287.     --Girdle of the Giants
  1288.     --+2000 Hit Points
  1289.     --40% chance on hit to perform a cleaving attack, damaging nearby enemies.
  1290.     Item_Artifact_090 = {
  1291.     PriorityFunction = function(unit, itemCount)
  1292.         if itemCount == 1 then
  1293.             return 100
  1294.         end
  1295.  
  1296.         if unit:GetAIBrain().mGold  >= 16000 then
  1297.             return 0
  1298.         else
  1299.             return 0
  1300.         end
  1301.     end,
  1302.     },
  1303.  
  1304.     --Ashkandor
  1305.     --+30% Life Steal
  1306.     --+175 Weapon Damage
  1307.     Item_Artifact_100 = {
  1308.     PriorityFunction = function(unit, itemCount)
  1309.         if itemCount == 1 then
  1310.             return 100
  1311.         end
  1312.  
  1313.         if unit:GetAIBrain().mGold  >= 16000 then
  1314.             return 130
  1315.         else
  1316.             return 0
  1317.         end
  1318.     end,
  1319.     },
  1320.  
  1321.     --Orb of Veiled Storms
  1322.     --Use: Unleash a wave of pure force in an area, dealing 500 damage.
  1323.     --+80 Hit Points per second
  1324.     Item_Artifact_110 = {
  1325.     PriorityFunction = function(unit, itemCount)
  1326.         if itemCount == 1 then
  1327.             return 100
  1328.         end
  1329.  
  1330.         if unit:GetAIBrain().mGold  >= 10000 then
  1331.             return 0
  1332.         else
  1333.             return 0
  1334.         end
  1335.     end,
  1336.     },
  1337.  
  1338.     --Bulwark of the Ages
  1339.     --+2500 Armor
  1340.     --All damage reduced by 25%.
  1341.     Item_Artifact_120 = {
  1342.     PriorityFunction = function(unit, itemCount)
  1343.         if itemCount == 1 then
  1344.             return 100
  1345.         end
  1346.  
  1347.         if unit:GetAIBrain().mGold  >= 16000 then
  1348.             return 125
  1349.         else
  1350.             return 0
  1351.         end
  1352.     end,
  1353.     },
  1354.  
  1355.     --All Father's Ring
  1356.     --+1500 Hit Points
  1357.     --+2500 Mana
  1358.     --+1500 Armor
  1359.     --+10% Base Run Speed
  1360.     Item_Artifact_130 = {
  1361.     PriorityFunction = function(unit, itemCount)
  1362.         if itemCount == 1 then
  1363.             return 150
  1364.         end
  1365.  
  1366.         if unit:GetAIBrain().mGold  >= 25000 then
  1367.             return 150
  1368.         else
  1369.             return 0
  1370.         end
  1371.     end,
  1372.     },
  1373.  
  1374.     ----------------------------------------------
  1375.     --ARTIFACT POTIONS
  1376.     ----------------------------------------------
  1377.  
  1378.     --Enhanced Health Potion
  1379.     Item_Health_Potion_Art = {
  1380.         Priority = 0,
  1381.         --MaxPurchase = 1,
  1382.     },
  1383.  
  1384.     Item_Large_Health_Potion_Art = {
  1385.         Priority = 0,
  1386.         --MaxPurchase = 1,
  1387.     },
  1388.  
  1389.     Item_Mana_Potion_Art = {
  1390.         Priority = 0,
  1391.         --MaxPurchase = 1,
  1392.     },
  1393.  
  1394.     Item_Large_Mana_Potion_Art = {
  1395.         Priority = 0,
  1396.         --MaxPurchase = 1,
  1397.     },
  1398.  
  1399.     Item_Rejuv_Elixir_Art = {
  1400.         Priority = 0,
  1401.         --MaxPurchase = 1,
  1402.     },
  1403.  
  1404.     Item_Large_Rejuv_Elixir_Art = {
  1405.         Priority = 0,
  1406.         --MaxPurchase = 1,
  1407.     },
  1408.  
  1409. }
  1410.  
  1411. --AI sensor wants to shop
  1412. --Sensor asks FriendlyAsset for a sorted list of upgrades, SortCitadelUpgradePriorities(unit)
  1413. --FriendlyAsset asks AIshoputilities for GetUpgradesList()
  1414. --AIshoputilities gets the list of upgrades from AIglobals
  1415. CitadelUpgradeWeights = {
  1416.     --Fortified Structure - upgrades based on team fortress health, whether enemy has certain troops, warrank, and warscore (Fs1)
  1417.     --0.26.39 Commented out original code for cbuildhealth01 to raise the priority to get fs1 as soon as warscore 2 is hit.
  1418.     --This code means nothing unless the ai returns to base, so use HeroGOAP to send an order to the AI with the most goal to return at ws2.
  1419.     CBuildingHealth01 = {
  1420.         PriorityFunction = function(unit)
  1421. --0.26.40 Changed the priority level trigger from WarScore to WarRank for fs1
  1422.             if unit:GetAIBrain().Score.WarRank  >= 2 then
  1423.                 return 500
  1424.             else
  1425.                 return 0
  1426.             end
  1427.      end,
  1428.     },
  1429.  
  1430. --[[ --original code
  1431.     CBuildingHealth01 = {
  1432.         PriorityFunction = function(unit)
  1433.  
  1434.             if unit:GetAIBrain().Score.WarScore  >= 100 then
  1435.                 return 200
  1436.             else
  1437.                 return 0
  1438.             end
  1439.      end,
  1440.     },
  1441. --]]
  1442.     CBuildingHealth02 = {
  1443.     PriorityFunction = function(unit)
  1444.     --local priority = 0
  1445.         if GetCitadelHealth(unit) < 0.95 then
  1446.             return 500
  1447.         elseif EnemyHasUpgrade(unit, 'CTroopNumber04') then
  1448.             return 100
  1449.         elseif unit:GetAIBrain().Score.WarRank >= 7 or GetEnemyTeamBrain(unit).Score.WarRank >= 7 then
  1450.             return 5
  1451.         else
  1452.             return 0
  1453.         end
  1454.     end,
  1455.     },
  1456.  
  1457.     CBuildingHealth03 = {
  1458.     PriorityFunction = function(unit)
  1459.     --local priority = 0
  1460.         if GetCitadelHealth(unit) < 0.8 then
  1461.             return 500
  1462.         elseif EnemyHasUpgrade(unit, 'CTroopNumber04') then
  1463.             return 40
  1464.         elseif unit:GetAIBrain().Score.WarRank >= 10 or GetEnemyTeamBrain(unit).Score.WarRank >= 10 then
  1465.             return 5
  1466.         else
  1467.             return 0
  1468.         end
  1469.     end,
  1470.    },
  1471.  
  1472.     CBuildingHealth04 = {
  1473.     PriorityFunction = function(unit)
  1474.     --local priority = 0
  1475.         if GetCitadelHealth(unit) < 0.8 then
  1476.             return 500
  1477.         elseif EnemyHasUpgrade(unit, 'CTroopNumber04') then
  1478.             return 40
  1479.         elseif unit:GetAIBrain().Score.WarRank >= 10 or GetEnemyTeamBrain(unit).Score.WarRank >= 10 then
  1480.             return 5
  1481.         else
  1482.             return 0
  1483.         end
  1484.         end,
  1485.    },
  1486.  
  1487.     --Building Firepower - upgrades based on troop types possessed by team or enemy team, warrank, and citadel structure upgrades (trebuchet and Finger of God)
  1488.     CBuildingStrength01 = {
  1489.  
  1490.         Priority =  40,
  1491.     ---- PriorityFunction = function(unit)
  1492.         ---- if EnemyHasUpgrade(unit, 'CTroopNumber06') then
  1493.             ---- return 20
  1494.         ---- elseif TeamHasUpgrade(unit, 'CUpgradeStructure01') then
  1495.             ---- return 15
  1496.         ---- elseif unit:GetAIBrain().Score.WarRank >= 7 or GetEnemyTeamBrain(unit).Score.WarRank >= 7 then
  1497.             ---- return 5
  1498.         ---- else
  1499.             ---- return 0
  1500.         ---- end
  1501.     ---- end,
  1502.    },
  1503.  
  1504.     CBuildingStrength02 = {
  1505.     PriorityFunction = function(unit)
  1506.     --local priority = 0
  1507.         if EnemyHasUpgrade(unit, 'CTroopNumber06') then
  1508.             return 20
  1509.         elseif TeamHasUpgrade(unit, 'CUpgradeStructure01') then
  1510.             return 10
  1511.         elseif unit:GetAIBrain().Score.WarRank >= 9 or GetEnemyTeamBrain(unit).Score.WarRank >= 9 then
  1512.             return 10
  1513.         else
  1514.             return 0
  1515.         end
  1516.     end,
  1517. },
  1518.  
  1519.     CBuildingStrength03 = {
  1520.     PriorityFunction = function(unit)
  1521.     --local priority = 0
  1522.         if EnemyHasUpgrade(unit, 'CTroopNumber06') then
  1523.             return 20
  1524.         elseif TeamHasUpgrade(unit, 'CUpgradeStructure01') then
  1525.             return 10
  1526.         elseif unit:GetAIBrain().Score.WarRank >= 10 or GetEnemyTeamBrain(unit).Score.WarRank >= 10 then
  1527.             return 10
  1528.         else
  1529.             return 0
  1530.         end
  1531.     end,
  1532. },
  1533.  
  1534.     CBuildingStrength04 = {
  1535.     PriorityFunction = function(unit)
  1536.     --local priority = 0
  1537.         if EnemyHasUpgrade(unit, 'CTroopNumber06') then
  1538.             return 20
  1539.         elseif TeamHasUpgrade(unit, 'CUpgradeStructure01') then
  1540.             return 10
  1541.         elseif unit:GetAIBrain().Score.WarRank >= 10 or GetEnemyTeamBrain(unit).Score.WarRank >= 10 then
  1542.             return 5
  1543.         else
  1544.             return 0
  1545.         end
  1546.     end,
  1547. },
  1548.  
  1549.     --Currency - timed priorities
  1550.     CGoldIncome01 = {
  1551.         Priority = 500,
  1552.     },
  1553.     --0.26.39 Commented out original code for cgoldincome to; setting to static value of 500 so it is purchased every game
  1554.     --this might not seem logical, but I want the ai picking up cur1 and cur2 under all circumstances
  1555.     CGoldIncome02 = {
  1556.         Priority = 500,
  1557.     },
  1558.     --[[
  1559.     CGoldIncome02 = { --7/11 minute cutoff for normal AI on normal/high gold, 15/22 min for nightmare AI, starting pri 30/60
  1560.         PriorityFunction = function(unit)
  1561.             local mult = 4 * math.floor(GetMinute())
  1562.             local base = 30 * GetGoldMult() * (GetAIDifficulty(unit)/2)
  1563.             local priority = math.max(0, base - mult)
  1564.             --LOG("mithy: CitadelUpgradeWeights: CGoldIncome02: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": "..repr(base).." - "..repr(mult).." = "..repr(priority))
  1565.             return priority
  1566.         end,
  1567.     },
  1568.     --]]
  1569.     CGoldIncome03 = { --5/7 min for normal, 10/15 for nightmare, starting pri 20/40
  1570.         PriorityFunction = function(unit)
  1571.             local mult = 4 * math.floor(GetMinute())
  1572.             local base = 20 * GetGoldMult() * (GetAIDifficulty(unit)/2)
  1573.             local priority = math.max(0, base - mult)
  1574.             --LOG("mithy: CitadelUpgradeWeights: CGoldIncome03: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": "..repr(base).." - "..repr(mult).." = "..repr(priority))
  1575.             return priority
  1576.         end,
  1577.     },
  1578.  
  1579.  
  1580.     --Blacksmith - match enemy upgrades, ultra-prioritize if either team has giants
  1581.     CTroopStrength01 = {
  1582.     PriorityFunction = function(unit)
  1583.         if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  1584.             return 200
  1585.         elseif TeamHasUpgrade(unit, 'CTroopNumber03') or EnemyHasUpgrade(unit, 'CTroopStrength01') then
  1586.             return  35
  1587.         elseif unit:GetAIBrain().Score.WarRank >= 8 then
  1588.             return 10
  1589.         else
  1590.             return 0
  1591.         end
  1592.      end,
  1593. },
  1594.  
  1595.     CTroopStrength02 = {
  1596.     PriorityFunction = function(unit)
  1597.         if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  1598.             return 150
  1599.         elseif TeamHasUpgrade(unit, 'CTroopNumber05') or EnemyHasUpgrade(unit, 'CTroopStrength02') then
  1600.             return  35
  1601.         elseif unit:GetAIBrain().Score.WarRank >= 9 then
  1602.             return 5
  1603.         else
  1604.             return 0
  1605.         end
  1606.     end,
  1607. },
  1608.  
  1609.     CTroopStrength03 = {
  1610.     PriorityFunction = function(unit)
  1611.         if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  1612.             return 100
  1613.         elseif TeamHasUpgrade(unit, 'CTroopNumber04') or EnemyHasUpgrade(unit, 'CTroopStrength03') then
  1614.             return  35
  1615.         elseif unit:GetAIBrain().Score.WarRank >= 9 then
  1616.             return 5
  1617.         else
  1618.             return 0
  1619.         end
  1620.     end,
  1621. },
  1622.  
  1623.     CTroopStrength04 = {
  1624.     PriorityFunction = function(unit)
  1625.         if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  1626.             return 75
  1627.         elseif EnemyHasUpgrade(unit, 'CTroopStrength04') then
  1628.             return 35
  1629.         elseif unit:GetAIBrain().Score.WarRank >= 10 then
  1630.             return 5
  1631.         else
  1632.             return 0
  1633.         end
  1634.     end,
  1635. },
  1636.  
  1637.     --Armory - match enemy upgrades, ultra-prioritize if either team has giants
  1638.  
  1639.     CTroopArmor01 = {
  1640.     PriorityFunction = function(unit)
  1641.         if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  1642.             return 200
  1643.         elseif TeamHasUpgrade(unit, 'CTroopNumber03') or EnemyHasUpgrade(unit, 'CTroopArmor01') then
  1644.             return  35
  1645.         elseif unit:GetAIBrain().Score.WarRank >= 8 then
  1646.             return 15
  1647.         else
  1648.             return 0
  1649.         end
  1650.     end,
  1651. },
  1652.  
  1653.     CTroopArmor02 = {
  1654.     PriorityFunction = function(unit)
  1655.         if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  1656.             return 150
  1657.         elseif TeamHasUpgrade(unit, 'CTroopNumber05') or EnemyHasUpgrade(unit, 'CTroopArmor02') then
  1658.             return 35
  1659.         elseif unit:GetAIBrain().Score.WarRank >= 9 then
  1660.             return 5
  1661.         else
  1662.             return 0
  1663.         end
  1664.     end,
  1665. },
  1666.  
  1667.     CTroopArmor03 = {
  1668.     PriorityFunction = function(unit)
  1669.         if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  1670.             return 100
  1671.         elseif TeamHasUpgrade(unit, 'CTroopNumber04') or EnemyHasUpgrade(unit, 'CTroopArmor03') then
  1672.             return 35
  1673.         elseif unit:GetAIBrain().Score.WarRank >= 9 then
  1674.             return 5
  1675.         else
  1676.             return 0
  1677.         end
  1678.     end,
  1679. },
  1680.  
  1681.     CTroopArmor04 = {
  1682.     PriorityFunction = function(unit)
  1683.         if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  1684.             return 75
  1685.         elseif EnemyHasUpgrade(unit, 'CTroopArmor04') then
  1686.             return 35
  1687.         elseif unit:GetAIBrain().Score.WarRank >= 10 then
  1688.             return 5
  1689.         else
  1690.             return 0
  1691.         end
  1692.     end,
  1693. },
  1694.  
  1695.     --Experience  [MOD] TE Fixed so AI will purchase
  1696.     CPortalFrequency01 = {
  1697.         Priority =  50,
  1698.     ---- PriorityFunction = function(unit)
  1699.         ---- if TeamHasUpgrade(unit, 'CGoldIncome01') then
  1700.             ---- return 35
  1701.         ---- else
  1702.             ---- return 0
  1703.         ---- end
  1704.     ---- end,
  1705.     },
  1706.  
  1707. --0.26.40 - Set priority for experience 2-4 to ZERO
  1708.     CPortalFrequency02 = {
  1709.         Priority = 0,
  1710.     },
  1711.     CPortalFrequency03 = {
  1712.         Priority = 0,
  1713.     },
  1714.     CPortalFrequency04 = {
  1715.         Priority = 0,
  1716.     },
  1717.  
  1718. --[[  --original code
  1719.     CPortalFrequency02 = {
  1720.         PriorityFunction = function(unit)
  1721.             local mult = 3 * math.floor( (GetMinute() + GetAverageLevel(unit)) )
  1722.             local base = math.floor( 60 / GetXPMult() ) * (GetAIDifficulty(unit)/2)
  1723.             local priority = math.max(0, base - mult)
  1724.             --LOG("mithy: CitadelUpgradeWeights: CPortalFrequency02: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": "..repr(base).." - "..repr(mult).." = "..repr(priority))
  1725.             return priority
  1726.         end,
  1727.     },
  1728.     CPortalFrequency03 = {
  1729.         PriorityFunction = function(unit)
  1730.             local mult = 3 * math.floor( (GetMinute() + GetAverageLevel(unit)) )
  1731.             local base = math.floor( 45 / GetXPMult() ) * (GetAIDifficulty(unit)/2)
  1732.             local priority = math.max(0, base - mult)
  1733.             --LOG("mithy: CitadelUpgradeWeights: CPortalFrequency03: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": "..repr(base).." - "..repr(mult).." = "..repr(priority))
  1734.             return priority
  1735.         end,
  1736.     },
  1737.     CPortalFrequency04 = {
  1738.         PriorityFunction = function(unit)
  1739.             local mult = 3 * math.floor( (GetMinute() + GetAverageLevel(unit)) )
  1740.             local base = math.floor( 30 / GetXPMult() ) * (GetAIDifficulty(unit)/2)
  1741.             local priority = math.max(0, base - mult)
  1742.             --LOG("mithy: CitadelUpgradeWeights: CPortalFrequency04: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": "..repr(base).." - "..repr(mult).." = "..repr(priority))
  1743.             return priority
  1744.         end,
  1745.     },
  1746. --]]
  1747.  
  1748.     --Graveyard - priority based on death penalty, number of team deaths, average team level, and AI difficulty.
  1749.     CDeathPenalty01 = {
  1750.         PriorityFunction = function(unit)
  1751.             local mult = 4 * math.floor(GetTeamDeaths(unit) + GetAverageLevel(unit))
  1752.             local minimum = math.floor( 100 / GetDeathMult() / (GetAIDifficulty(unit)/2) )
  1753.             local priority = math.max(0, mult - minimum)
  1754.             --LOG("mithy: CitadelUpgradeWeights: CDeathPenalty01: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": " ..repr(mult).." - "..repr(minimum).." = "..repr(priority))
  1755.             return priority
  1756.         end,
  1757.     },
  1758.     CDeathPenalty02 = {
  1759.         PriorityFunction = function(unit)
  1760.             local mult = 4 * math.floor(GetTeamDeaths(unit) + GetAverageLevel(unit))
  1761.             local minimum = math.floor( 200 / GetDeathMult() / (GetAIDifficulty(unit)/2) )
  1762.             local priority = math.max(0, mult - minimum)
  1763.             --LOG("mithy: CitadelUpgradeWeights: CDeathPenalty02: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": " ..repr(mult).." - "..repr(minimum).." = "..repr(priority))
  1764.             return priority
  1765.         end,
  1766.     },
  1767.     CDeathPenalty03 = {
  1768.         PriorityFunction = function(unit)
  1769.             if GetDeathMult() >= 1 then
  1770.             local mult = 4 * math.floor(GetTeamDeaths(unit) + GetAverageLevel(unit))
  1771.                 local minimum = math.floor( 300 / GetDeathMult() / (GetAIDifficulty(unit)/2) )
  1772.                 local priority = math.max(0, mult - minimum)
  1773.                 --LOG("mithy: CitadelUpgradeWeights: CDeathPenalty03: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": " ..repr(mult).." - "..repr(minimum).." = "..repr(priority))
  1774.                 return priority
  1775.             else
  1776.                 return 0
  1777.             end
  1778.         end,
  1779.     },
  1780.  
  1781.     --Additional troops - AI will now attempt to match troop upgrades with their opponent even before WR 8
  1782.     --This keeps AI games from becoming too one-sided once one team gets priests+
  1783.     --Priests
  1784.     CTroopNumber03 = {
  1785.          PriorityFunction = function(unit)
  1786.             if EnemyHasUpgrade(unit, 'CTroopNumber03') or unit:GetAIBrain().Score.WarRank >= 8 then
  1787.                 return 500
  1788.             else
  1789.                 return 0
  1790.             end
  1791.         end,
  1792.     },
  1793.     --Angels
  1794.     CTroopNumber05 = {
  1795.          PriorityFunction = function(unit)
  1796.             if EnemyHasUpgrade(unit, 'CTroopNumber05') or unit:GetAIBrain().Score.WarRank >= 8 then
  1797.                 return 500
  1798.             else
  1799.                 return 0
  1800.             end
  1801.         end,
  1802.     },
  1803.     --Catapults
  1804.     CTroopNumber04 = {
  1805.          PriorityFunction = function(unit)
  1806.             if EnemyHasUpgrade(unit, 'CTroopNumber04') or unit:GetAIBrain().Score.WarRank >= 8 then
  1807.                 return 500
  1808.             else
  1809.                 return 0
  1810.             end
  1811.         end,
  1812.     },
  1813.     --Giants
  1814.     CTroopNumber06 = {
  1815.          PriorityFunction = function(unit)
  1816.             if EnemyHasUpgrade(unit, 'CTroopNumber06') or unit:GetAIBrain().Score.WarRank >= 8 then
  1817.                 return 500
  1818.             else
  1819.                 return 0
  1820.             end
  1821.         end,
  1822.     },
  1823.  
  1824. --Trebuchets - match, prioritize vs catapults+, take into account fort totals
  1825. CUpgradeStructure01 = {
  1826.     PriorityFunction = function(unit)
  1827.         local priority = 0
  1828.         local ourForts = unit:GetAIBrain():GetTeamArmy():GetListOfUnits(categories.FORT, false)
  1829.         if table.getn(ourForts) < 2 then
  1830.             return 0
  1831.         end
  1832.  
  1833.         local enemyForts = GetEnemyTeamBrain(unit):GetListOfUnits(categories.FORT, false)
  1834.         if EnemyHasUpgrade(unit, 'CTroopNumber04') and not TeamHasUpgrade(unit, 'CTroopNumber04') then
  1835.             priority = 15
  1836.         elseif EnemyHasUpgrade(unit, 'CUpgradeStructure02') then
  1837.             priority = 2 * table.getn(enemyForts)
  1838.         end
  1839.  
  1840.         return priority * table.getn(ourForts) * GoldThreshold(unit, UpgradeCost('CUpgradeStructure02'))
  1841.     end,
  1842. },
  1843.  
  1844. --Finger of God - match, prioritize vs catapults+
  1845.     CUpgradeStructure02 = {
  1846.     PriorityFunction = function(unit)
  1847.     --local priority = 0
  1848.         if EnemyHasUpgrade(unit, 'CUpgradeStructure02') or EnemyHasUpgrade(unit, 'CTroopNumber04') then
  1849.             return 100
  1850.         elseif GetEnemyTeamBrain(unit).Score.WarRank >= 9 then
  1851.             return 10
  1852.         else
  1853.             return 0
  1854.         end
  1855.    end,
  1856. },
  1857. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement