Advertisement
Guest User

Mithy

a guest
Sep 2nd, 2010
511
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.06 KB | None | 0 0
  1. --AIGlobals.lua
  2. local Game = import('/lua/game.lua')
  3. local Upgrades = import('/lua/common/CitadelUpgrades.lua').Upgrades
  4.  
  5.  
  6. --Utility functions for expanding PriorityFunction versatility
  7. function GetDeathMult()
  8.     return Game.GameData.DeathPenaltyMultiplier[ScenarioInfo.Options.DeathPenalty or 'Normal']
  9. end
  10.  
  11. function GetGoldMult()
  12.     return Game.GameData.GoldIncomeMultiplier[ScenarioInfo.Options.GoldIncome or 'Normal']
  13. end
  14.  
  15. function GetXPMult()
  16.     return Game.GameData.ExperienceMultiplier[ScenarioInfo.Options.ExperienceRate or 'Normal']
  17. end
  18.  
  19. function GetMinute()
  20.     return math.floor(GetGameTimeSeconds() / 60)
  21. end
  22.  
  23. function IsGeneral(unit)
  24.     return EntityCategoryContains(categories.GENERAL, unit)
  25. end
  26.  
  27. function IsAssassin(unit)
  28.     return EntityCategoryContains(categories.ASSASSIN, unit)
  29. end
  30.  
  31. function UpgradeCost(upgradeName)
  32.     if Upgrades.Tree[upgradeName] then
  33.         return Upgrades.Tree[upgradeName].Cost
  34.     else
  35.         WARN("AIGlobals.UpgradeCost -- Tried to get cost of non-existent upgrade '"..upgradeName.."'")
  36.         return 0
  37.     end
  38. end
  39.  
  40. --Returns a fractional modifier from 0 to 1 based on the provided demigod's gold reserves, starting at the minimum specified
  41. --amount of gold and ending at the min amount * rec multiplier.  If the rec multiplier is not specified, it defaults to 2.
  42. function GoldThreshold(unit, min, rec)
  43.     rec = min * (rec or 2)
  44.     return math.min(1, math.max(0, unit:GetGold() - min) / (rec - min))
  45. end
  46.  
  47. --Get our team's average hero level
  48. function GetAverageLevel(unit)
  49.     local levels, heroes = unit.Score.HeroLevel, 1
  50.     for k, brain in unit:GetAIBrain():GetAlliedArmies() do
  51.         if not brain.IsTeamArmy then
  52.             heroes = heroes + 1
  53.             levels = levels + brain.Score.HeroLevel
  54.         end
  55.     end
  56.     return math.floor( (levels / heroes) + 0.5 )
  57. end
  58.  
  59. --Get our team's total deaths
  60. function GetTeamDeaths(unit)
  61.     local deaths = unit.Score.HeroDeaths
  62.     for k, brain in unit:GetAIBrain():GetAlliedArmies() do
  63.         if not brain.IsTeamArmy then
  64.             deaths = deaths + brain.Score.HeroDeaths
  65.         end
  66.     end
  67.     return deaths
  68. end
  69.  
  70. --Get our team's citadel health fraction
  71. function GetCitadelHealth(unit)
  72.     local cithealth = false
  73.     local citadel = unit:GetAIBrain():GetStronghold()
  74.  
  75.     if citadel then
  76.         cithealth = citadel:GetHealth() / citadel:GetMaxHealth()
  77.     end
  78.  
  79.     return cithealth
  80. end
  81.  
  82. function GetEnemyTeamBrain(unit)
  83.     local unitbrain = unit:GetAIBrain()
  84.  
  85.     if not unitbrain.EnemyTeamBrain then
  86.         for k, brain in ArmyBrains do
  87.             if brain.TeamBrain and IsEnemy(unit:GetArmy(), brain:GetArmyIndex()) then
  88.                 unitbrain.EnemyTeamBrain = brain
  89.             end
  90.         end
  91.     end
  92.  
  93.     return unitbrain.EnemyTeamBrain
  94. end
  95.  
  96. --Used to get info on enemy citadel upgrades
  97. function HasUpgradeByTeamBrain(brain, upgradeName)
  98.     local upgradesTable = brain:GetStronghold().Sync.Upgrades
  99.  
  100.     if upgradesTable then
  101.         for k,v in upgradesTable do
  102.             if v == upgradeName then
  103.                 return true
  104.             end
  105.         end
  106.     end
  107.  
  108.     return false
  109. end
  110.  
  111. --Check our team's upgrades
  112. function TeamHasUpgrade(unit, upgradeName)
  113.     local hasupgrade = false
  114.     local tBrain = unit:GetAIBrain():GetTeamArmy()
  115.  
  116.     if tBrain then
  117.         hasupgrade = HasUpgradeByTeamBrain(tBrain, upgradeName)
  118.     end
  119.  
  120.     return hasupgrade
  121. end
  122.  
  123. --Check enemy team's upgrades
  124. function EnemyHasUpgrade(unit, upgradeName)
  125.     local hasupgrade = false
  126.     local etBrain = GetEnemyTeamBrain(unit)
  127.  
  128.     if etBrain then
  129.         local hasupgrade = HasUpgradeByTeamBrain(etBrain, upgradeName)
  130.     end
  131.  
  132.     return hasupgrade
  133. end
  134.  
  135.  
  136.  
  137. --Try to get the AI to respond to pings a bit more reliably
  138. AIPingMaximumWeight = 90 # 37
  139.  
  140.  
  141.  
  142.  
  143. --Citadel Upgrade priorities
  144. CitadelUpgradeWeights = {
  145.     # Fortified Structure - prioritize on enemy catapults and citadel health
  146.     CBuildingHealth01 = {
  147.         PriorityFunction = function(unit)
  148.             if unit:GetAIBrain().Score.WarScore >= 300 then
  149.                 return 250
  150.             else
  151.                 return 0
  152.             end
  153.         end,
  154.     },
  155.     CBuildingHealth02 = {
  156.         PriorityFunction = function(unit)
  157.             local priority = 0
  158.             if GetCitadelHealth(unit) < 0.98 then
  159.                 priority = 600
  160.             elseif EnemyHasUpgrade(unit, 'CTroopNumber04') then
  161.                 priority = 100
  162.             elseif unit:GetAIBrain().Score.WarRank >= 7 or GetEnemyTeamBrain(unit).Score.WarRank >= 7 then
  163.                 priority = 10
  164.             end
  165.             return priority * GoldThreshold(unit, UpgradeCost('CBuildingHealth02'))
  166.         end,
  167.     },
  168.     CBuildingHealth03 = {
  169.         PriorityFunction = function(unit)
  170.             local priority = 0
  171.             if GetCitadelHealth(unit) < 0.9 then
  172.                 priority = 600
  173.             elseif EnemyHasUpgrade(unit, 'CTroopNumber04') then
  174.                 priority = 15
  175.             elseif unit:GetAIBrain().Score.WarRank >= 8 or GetEnemyTeamBrain(unit).Score.WarRank >= 8 then
  176.                 priority = 5
  177.             end
  178.             return priority * GoldThreshold(unit, UpgradeCost('CBuildingHealth03'))
  179.         end,
  180.     },
  181.     CBuildingHealth04 = {
  182.         PriorityFunction = function(unit)
  183.             local priority = 0
  184.             if GetCitadelHealth(unit) < 0.8 then
  185.                 priority = 600
  186.             elseif EnemyHasUpgrade(unit, 'CTroopNumber04') then
  187.                 priority = 15
  188.             elseif unit:GetAIBrain().Score.WarRank >= 10 or GetEnemyTeamBrain(unit).Score.WarRank >= 10 then
  189.                 priority = 5
  190.             end
  191.             return priority * GoldThreshold(unit, UpgradeCost('CBuildingHealth04'))
  192.         end,
  193.     },
  194.  
  195.     # Building Firepower - prioritize by enemy giants, then by structure upgrades, then war rank
  196.     CBuildingStrength01 = {
  197.         PriorityFunction = function(unit)
  198.             local priority = 0
  199.             if EnemyHasUpgrade(unit, 'CTroopNumber06') then
  200.                 priority = 250
  201.             elseif TeamHasUpgrade(unit, 'CUpgradeStructure01') then
  202.                 priority = 10
  203.             elseif unit:GetAIBrain().Score.WarRank >= 7 or GetEnemyTeamBrain(unit).Score.WarRank >= 7 then
  204.                 priority = 15
  205.             end
  206.             return priority * GoldThreshold(unit, UpgradeCost('CBuildingStrength01'))
  207.         end,
  208.     },
  209.     CBuildingStrength02 = {
  210.         PriorityFunction = function(unit)
  211.             local priority = 0
  212.             if EnemyHasUpgrade(unit, 'CTroopNumber06') then
  213.                 priority = 225
  214.             elseif TeamHasUpgrade(unit, 'CUpgradeStructure01') then
  215.                 priority = 10
  216.             elseif unit:GetAIBrain().Score.WarRank >= 8 or GetEnemyTeamBrain(unit).Score.WarRank >= 8 then
  217.                 priority = 10
  218.             end
  219.             return priority * GoldThreshold(unit, UpgradeCost('CBuildingStrength02'))
  220.         end,
  221.     },
  222.     CBuildingStrength03 = {
  223.         PriorityFunction = function(unit)
  224.             local priority = 0
  225.             if EnemyHasUpgrade(unit, 'CTroopNumber06') then
  226.                 priority = 200
  227.             elseif TeamHasUpgrade(unit, 'CUpgradeStructure01') then
  228.                 priority = 10
  229.             elseif unit:GetAIBrain().Score.WarRank >= 9 or GetEnemyTeamBrain(unit).Score.WarRank >= 9 then
  230.                 priority = 5
  231.             end
  232.             return priority * GoldThreshold(unit, UpgradeCost('CBuildingStrength03'))
  233.         end,
  234.     },
  235.     CBuildingStrength04 = {
  236.         PriorityFunction = function(unit)
  237.             local priority = 0
  238.             if EnemyHasUpgrade(unit, 'CTroopNumber06') then
  239.                 priority = 175
  240.             elseif TeamHasUpgrade(unit, 'CUpgradeStructure01') then
  241.                 priority = 10
  242.             elseif unit:GetAIBrain().Score.WarRank >= 10 or GetEnemyTeamBrain(unit).Score.WarRank >= 10 then
  243.                 priority = 5
  244.             end
  245.             return priority * GoldThreshold(unit, UpgradeCost('CBuildingStrength04'))
  246.         end,
  247.     },
  248.  
  249.     # Currency - timed priorities
  250.     CGoldIncome01 = {
  251.         Priority = 200,
  252.     },
  253.     CGoldIncome02 = { --12 / 18 minute cutoff
  254.         PriorityFunction = function(unit)
  255.             local mult = math.floor(GetMinute() * 8)
  256.             local base = 100 * GetGoldMult()
  257.             local priority = math.max(0, base - mult)
  258.             --LOG("mithy: CitadelUpgradeWeights: CGoldIncome02: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": "..repr(base).." - "..repr(mult).." = "..repr(priority))
  259.             return priority
  260.         end,
  261.     },
  262.     CGoldIncome03 = { --10 / 15 minute cutoff
  263.         PriorityFunction = function(unit)
  264.             local mult = math.floor(GetMinute() * 6)
  265.             local base = 60 * GetGoldMult()
  266.             local priority = math.max(0, base - mult)
  267.             --LOG("mithy: CitadelUpgradeWeights: CGoldIncome03: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": "..repr(base).." - "..repr(mult).." = "..repr(priority))
  268.             return priority
  269.         end,
  270.     },
  271.  
  272.     # Blacksmith - match enemy upgrades, ultra-prioritize if either team has giants
  273.     CTroopStrength01 = {
  274.        PriorityFunction = function(unit)
  275.             if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  276.                 return 450
  277.             elseif TeamHasUpgrade(unit, 'CTroopNumber03') or EnemyHasUpgrade(unit, 'CTroopStrength01') then
  278.                 return 25
  279.             elseif unit:GetAIBrain().Score.WarRank >= 7 then
  280.                 return 10
  281.             else
  282.                 return 0
  283.             end
  284.         end,
  285.     },
  286.     CTroopStrength02 = {
  287.         PriorityFunction = function(unit)
  288.             if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  289.                 return 425
  290.             elseif TeamHasUpgrade(unit, 'CTroopNumber05') or EnemyHasUpgrade(unit, 'CTroopStrength02') then
  291.                 return 15
  292.             elseif unit:GetAIBrain().Score.WarRank >= 8 then
  293.                 return 5
  294.             else
  295.                 return 0
  296.             end
  297.         end,
  298.     },
  299.     CTroopStrength03 = {
  300.         PriorityFunction = function(unit)
  301.             if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  302.                 return 400
  303.             elseif TeamHasUpgrade(unit, 'CTroopNumber04') or EnemyHasUpgrade(unit, 'CTroopStrength03') then
  304.                 return 15
  305.             elseif unit:GetAIBrain().Score.WarRank >= 9 then
  306.                 return 5
  307.             else
  308.                 return 0
  309.             end
  310.         end,
  311.     },
  312.     CTroopStrength04 = {
  313.         PriorityFunction = function(unit)
  314.             if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  315.                 return 375
  316.             elseif EnemyHasUpgrade(unit, 'CTroopStrength04') then
  317.                 return 10
  318.             elseif unit:GetAIBrain().Score.WarRank >= 10 then
  319.                 return 5
  320.             else
  321.                 return 0
  322.             end
  323.         end,
  324.     },
  325.  
  326.     # Armory - match enemy upgrades, ultra-prioritize if either team has giants
  327.     CTroopArmor01 = {
  328.        PriorityFunction = function(unit)
  329.             if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  330.                 return 475
  331.             elseif TeamHasUpgrade(unit, 'CTroopNumber03') or EnemyHasUpgrade(unit, 'CTroopArmor01') then
  332.                 return 25
  333.             elseif unit:GetAIBrain().Score.WarRank >= 7 then
  334.                 return 15
  335.             else
  336.                 return 0
  337.             end
  338.         end,
  339.     },
  340.     CTroopArmor02 = {
  341.         PriorityFunction = function(unit)
  342.             if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  343.                 return 450
  344.             elseif TeamHasUpgrade(unit, 'CTroopNumber05') or EnemyHasUpgrade(unit, 'CTroopArmor02') then
  345.                 return 20
  346.             elseif unit:GetAIBrain().Score.WarRank >= 8 then
  347.                 return 5
  348.             else
  349.                 return 0
  350.             end
  351.         end,
  352.     },
  353.     CTroopArmor03 = {
  354.         PriorityFunction = function(unit)
  355.             if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  356.                 return 425
  357.             elseif TeamHasUpgrade(unit, 'CTroopNumber04') or EnemyHasUpgrade(unit, 'CTroopArmor03') then
  358.                 return 15
  359.             elseif unit:GetAIBrain().Score.WarRank >= 9 then
  360.                 return 5
  361.             else
  362.                 return 0
  363.             end
  364.         end,
  365.     },
  366.     CTroopArmor04 = {
  367.         PriorityFunction = function(unit)
  368.             if TeamHasUpgrade(unit, 'CTroopNumber06') or EnemyHasUpgrade(unit, 'CTroopNumber06') then
  369.                 return 400
  370.             elseif EnemyHasUpgrade(unit, 'CTroopArmor04') then
  371.                 return 10
  372.             elseif unit:GetAIBrain().Score.WarRank >= 10 then
  373.                 return 5
  374.             else
  375.                 return 0
  376.             end
  377.         end,
  378.     },
  379.  
  380.     # Experience - always get I, priorities for II-IV based on average team level, xp game setting, and time elapsed.
  381.     CPortalFrequency01 = {
  382.         Priority = 200,
  383.     },
  384.     CPortalFrequency02 = {
  385.         PriorityFunction = function(unit)
  386.             local mult = math.floor( (GetMinute() + GetAverageLevel(unit)) ) * 3
  387.             local base = math.floor( 90 / GetXPMult() )
  388.             local priority = math.max(0, base - mult)
  389.             --LOG("mithy: CitadelUpgradeWeights: CPortalFrequency02: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": "..repr(base).." - "..repr(mult).." = "..repr(priority))
  390.             return priority
  391.         end,
  392.     },
  393.     CPortalFrequency03 = {
  394.         PriorityFunction = function(unit)
  395.             local mult = math.floor( (GetMinute() + GetAverageLevel(unit)) ) * 3
  396.             local base = math.floor( 75 / GetXPMult() )
  397.             local priority = math.max(0, base - mult)
  398.             --LOG("mithy: CitadelUpgradeWeights: CPortalFrequency03: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": "..repr(base).." - "..repr(mult).." = "..repr(priority))
  399.             return priority
  400.         end,
  401.     },
  402.     CPortalFrequency04 = {
  403.         PriorityFunction = function(unit)
  404.             local mult = math.floor( (GetMinute() + GetAverageLevel(unit)) ) * 3
  405.             local base = math.floor( 60 / GetXPMult() )
  406.             local priority = math.max(0, base - mult)
  407.             --LOG("mithy: CitadelUpgradeWeights: CPortalFrequency04: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": "..repr(base).." - "..repr(mult).." = "..repr(priority))
  408.             return priority
  409.         end,
  410.     },
  411.  
  412.     # Graveyard - priority based on death penalty, number of team deaths, and average team level.
  413.     CDeathPenalty01 = {
  414.         PriorityFunction = function(unit)
  415.             local mult = math.floor( (2*GetTeamDeaths(unit) + GetAverageLevel(unit)) ) * 4
  416.             local minimum = math.floor( 80 / GetDeathMult() )
  417.             local priority = math.max(0, mult - minimum)
  418.             --LOG("mithy: CitadelUpgradeWeights: CDeathPenalty01: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": " ..repr(mult).." - "..repr(minimum).." = "..repr(priority))
  419.             return priority
  420.         end,
  421.     },
  422.     CDeathPenalty02 = {
  423.         PriorityFunction = function(unit)
  424.             local mult = math.floor( (2*GetTeamDeaths(unit) + GetAverageLevel(unit)) ) * 4
  425.             local minimum = math.floor( 160 / GetDeathMult() )
  426.             local priority = math.max(0, mult - minimum)
  427.             --LOG("mithy: CitadelUpgradeWeights: CDeathPenalty02: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": " ..repr(mult).." - "..repr(minimum).." = "..repr(priority))
  428.             return priority
  429.         end,
  430.     },
  431.     CDeathPenalty03 = {
  432.         PriorityFunction = function(unit)
  433.             if GetDeathMult() >= 1 then
  434.                 local mult = math.floor( (2*GetTeamDeaths(unit) + GetAverageLevel(unit)) ) * 4
  435.                 local minimum = math.floor( 240 / GetDeathMult() )
  436.                 local priority = math.max(0, mult - minimum)
  437.                 --LOG("mithy: CitadelUpgradeWeights: CDeathPenalty03: "..repr(unit:GetAIBrain():GetTeamArmy().Name)..": " ..repr(mult).." - "..repr(minimum).." = "..repr(priority))
  438.                 return priority
  439.             else
  440.                 return 0
  441.             end
  442.         end,
  443.     },
  444.  
  445.     # Additional troops - AI will now attempt to match troop upgrades with their opponent even before WR 8
  446.     # This keeps AI games from becoming too one-sided once one team gets priests+
  447.     # Priests
  448.     CTroopNumber03 = {
  449.          PriorityFunction = function(unit)
  450.             if EnemyHasUpgrade(unit, 'CTroopNumber03') then
  451.                 return 500
  452.             elseif unit:GetAIBrain().Score.WarRank >= 8 then
  453.                 return 90
  454.             else
  455.                 return 0
  456.             end
  457.         end,
  458.     },
  459.     # Angels
  460.     CTroopNumber05 = {
  461.          PriorityFunction = function(unit)
  462.             if EnemyHasUpgrade(unit, 'CTroopNumber05') then
  463.                 return 500
  464.             elseif unit:GetAIBrain().Score.WarRank >= 8 then
  465.                 return 80
  466.             else
  467.                 return 0
  468.             end
  469.         end,
  470.     },
  471.     # Catapults
  472.     CTroopNumber04 = {
  473.          PriorityFunction = function(unit)
  474.             if EnemyHasUpgrade(unit, 'CTroopNumber04') then
  475.                 return 500
  476.             elseif unit:GetAIBrain().Score.WarRank >= 8 then
  477.                 return 70
  478.             else
  479.                 return 0
  480.             end
  481.         end,
  482.     },
  483.     # Giants
  484.     CTroopNumber06 = {
  485.          PriorityFunction = function(unit)
  486.             if EnemyHasUpgrade(unit, 'CTroopNumber06') then
  487.                 return 500
  488.             elseif unit:GetAIBrain().Score.WarRank >= 8 then
  489.                 return 50
  490.             else
  491.                 return 0
  492.             end
  493.         end,
  494.     },
  495.     # Trebuchets - match, prioritize vs catapults+
  496.     CUpgradeStructure01 = {
  497.          PriorityFunction = function(unit)
  498.             local priority = 0
  499.             if EnemyHasUpgrade(unit, 'CUpgradeStructure01') or EnemyHasUpgrade(unit, 'CTroopNumber04') then
  500.                 priority = 100
  501.             elseif GetEnemyTeamBrain(unit).Score.WarRank >= 8 then
  502.                 priority = 10
  503.             end
  504.             return priority * GoldThreshold(unit, UpgradeCost('CUpgradeStructure01') * 2)
  505.         end,
  506.     },
  507.     # Finger of God - match, prioritize vs catapults+
  508.     CUpgradeStructure02 = {
  509.          PriorityFunction = function(unit)
  510.             local priority = 0
  511.             if EnemyHasUpgrade(unit, 'CUpgradeStructure02') or EnemyHasUpgrade(unit, 'CTroopNumber04') then
  512.                 priority = 100
  513.             elseif GetEnemyTeamBrain(unit).Score.WarRank >= 9 then
  514.                 priority = 10
  515.             end
  516.             return priority * GoldThreshold(unit, UpgradeCost('CUpgradeStructure02') * 2)
  517.         end,
  518.     },
  519. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement