From 29b832b5063fa8e69fb45cd5c549023329de6073 Mon Sep 17 00:00:00 2001 From: Aaron Song <31906374+AaronSong321@users.noreply.github.com> Date: Sat, 8 May 2021 02:13:26 +0100 Subject: [PATCH] Fix courier system; Add ember_spirit; (#47) Forbid silence ability usage on item channeling enemies (meteor_hammer); Change juggernaut ability level up; Fix troll_warlord ultimate; Forbid location ability usage on invulnerable units (ember_spirit, puck); Fix arc_warden GetBot; Fix bane, beastmaster, centaur, hoodwink abilities; Decrease the frequency of bounty_hunter, treant querying enemies 1600 away from npcBot to reduce warning in the console; Change chen, bounty_hunter ability; Restrict occasions for casting winter_wyvern_cold_embrace; Add puck draft; Change CourierSystem.lua to let every bot get access to the courier; Change some item purchase solution to save their money; Commit local dictionary for dota vocabulary Fix brewmaster cannot move while primal_split; Use glyph when target is quickly losing health; Forbid furion use sprout at himself while invisible and not attacked; Forbid obsidian_destroyer, shadow_demon use imprisonment ability on severely disabled enemies; Add beastmaster_hawk_bomb_dive; Try not to use tango at trees inside enemy towers' attack range; Add ember_spirit; Add beastmaster_hawk_dive minion use; Improve templar_assassin_psionic_trap; Fix bots stuck because of repeatedly using ring_of_basilius or buckler; Add pudge use rot when channeling; Add shadow_demon_soul_catcher, provide shadow_demon better cast target of disruption and demonic_purge; Fix newly-added glyph usage; Fix drow_ranger use split_shot at target; Fix bugs in omniknight shard ability; Fix bugs in item purchase when reloading; Remove consumable purchase for heros who want to buy bottle; Enable skeleton_king buy Aghanim's shard when antimage is on enemy team; Fix abilities in ember_spirit, pudge, hoodwink; Recall courier when hero's inventory is full; Fix tipos in change log Add tide_hunter, magnataur cancel ultimate when there are no enemies around; Forbid enchantress, drow_ranger, obsidian_destroyer, silencer cast attack ability on ethereal or magic immune targets or when totally blinded; Fix bug when lich try to cast frost_armour on enemy; Add armlet of mordiggian usage; Don't heal target under ancient_apparition_ice_blast (including armlet and power treads); Fix bugs in chen, leshrac, and omniknight; Add bane cancel nightmare; Fix errors when npcMostDangerousEnemy is unassigned; Add tusk use snowball with friends and scroll before timeout; Forbid winter_wyvern_cold_embrace cast on friends with time sensitive modifiers (e.g. bkb, fv_chronosphere), applies to snowball as well; Add ability information of basic levels; Antimage, ember_spirit now only dodge dodge-worth abilities (stun, strong disable, massive damage); Add bane try to cancel brain_snap and ult when target has linken's sphere, lotus_orb, or antimage_counterspell active; Heroes can use any blink (agi/str/int); Add ursa use enrage when disabled; Remove a pair of unused local; Fix errors in magnataur, sniper; Fix incorrect scepter usage of chen, clinkz, doom, enchantress; Cancel axe_culling_blade when target gains health suddenly; Add alchemist throw concoction earlier when enemies have stun or silence; Improve antimage blink location when attacking enemies; Improve winter_wyvern_cold_embrace target; Temporarily remove all buckler and ring_of_basilius purchase; Add announcement of discord; Fix spectre try to use spectral_dagger at creeps; Fix some errors in earth_spirit; Avoid using ultimate abilities at non-hero units; Add unerlord_dark_rift cancel and scepter; Add alchemist use scepter; [dev-only] Add coroutine-style consider call; Add life_stealer scepter; Add lina shard; Better obsidian_destroyer_imprisonment behavior at allies; Add fear, hynopsis, root detect, and forbid certain abilities at these negative modifiers; Fix arc_warden_tempest_double try to use abilities while mana is not enough; Fix treant_natures_grasp use at target unit (can only target location); Co-authored-by: adamqqq --- .gitignore | 2 + ability_item_usage_abaddon.lua | 167 +- ability_item_usage_abyssal_underlord.lua | 69 +- ability_item_usage_alchemist.lua | 68 +- ability_item_usage_ancient_apparition.lua | 6 +- ability_item_usage_antimage.lua | 78 +- ability_item_usage_arc_warden.lua | 37 +- ability_item_usage_axe.lua | 67 +- ability_item_usage_bane.lua | 54 +- ability_item_usage_batrider.lua | 11 +- ability_item_usage_beastmaster.lua | 10 +- ability_item_usage_bounty_hunter.lua | 69 +- ability_item_usage_brewmaster.lua | 52 +- ability_item_usage_bristleback.lua | 16 +- ability_item_usage_broodmother.lua | 62 - ability_item_usage_centaur.lua | 48 +- ability_item_usage_chen.lua | 96 +- ability_item_usage_clinkz.lua | 56 +- ability_item_usage_crystal_maiden.lua | 72 +- ability_item_usage_dark_seer.lua | 48 +- ability_item_usage_dazzle.lua | 89 +- ability_item_usage_death_prophet.lua | 21 +- ability_item_usage_disruptor.lua | 12 +- ability_item_usage_doom_bringer.lua | 24 +- ability_item_usage_dragon_knight.lua | 29 +- ability_item_usage_drow_ranger.lua | 137 +- ability_item_usage_earth_spirit.lua | 21 +- ability_item_usage_earthshaker.lua | 25 +- ability_item_usage_elder_titan.lua | 12 +- ability_item_usage_ember_spirit.lua | 1116 ++++------ ability_item_usage_enchantress.lua | 119 +- ability_item_usage_enigma.lua | 139 +- ability_item_usage_faceless_void.lua | 13 +- ability_item_usage_furion.lua | 24 +- ability_item_usage_generic.lua | 164 +- ability_item_usage_gyrocopter.lua | 9 +- ability_item_usage_hoodwink.lua | 60 +- ability_item_usage_huskar.lua | 8 +- ability_item_usage_jakiro.lua | 51 +- ability_item_usage_juggernaut.lua | 14 +- ability_item_usage_keeper_of_the_light.lua | 10 +- ability_item_usage_kunkka.lua | 51 +- ability_item_usage_legion_commander.lua | 16 +- ability_item_usage_leshrac.lua | 16 +- ability_item_usage_lich.lua | 72 +- ability_item_usage_life_stealer.lua | 83 +- ability_item_usage_lina.lua | 86 +- ability_item_usage_lion.lua | 14 +- ability_item_usage_luna.lua | 50 +- ability_item_usage_lycan.lua | 4 +- ability_item_usage_magnataur.lua | 56 +- ability_item_usage_medusa.lua | 2 +- ability_item_usage_mirana.lua | 8 +- ability_item_usage_monkey_king.lua | 3 +- ability_item_usage_naga_siren.lua | 33 +- ability_item_usage_necrolyte.lua | 9 +- ability_item_usage_night_stalker.lua | 6 +- ability_item_usage_nyx_assassin.lua | 9 +- ability_item_usage_obsidian_destroyer.lua | 105 +- ability_item_usage_ogre_magi.lua | 16 +- ability_item_usage_omniknight.lua | 15 +- ability_item_usage_phantom_assassin.lua | 32 +- ability_item_usage_phantom_lancer.lua | 8 +- ability_item_usage_puck.lua | 301 ++- ability_item_usage_pudge.lua | 84 +- ability_item_usage_pugna.lua | 6 +- ability_item_usage_queenofpain.lua | 16 +- ability_item_usage_rattletrap.lua | 138 ++ ability_item_usage_razor.lua | 4 +- ability_item_usage_riki.lua | 8 +- ability_item_usage_shadow_demon.lua | 216 +- ability_item_usage_shadow_shaman.lua | 12 +- ability_item_usage_shredder.lua | 14 +- ability_item_usage_silencer.lua | 167 +- ability_item_usage_skeleton_king.lua | 13 +- ability_item_usage_skywrath_mage.lua | 16 +- ability_item_usage_slardar.lua | 18 +- ability_item_usage_slark.lua | 13 +- ability_item_usage_sniper.lua | 9 +- ability_item_usage_spectre.lua | 4 +- ability_item_usage_spirit_breaker.lua | 27 +- ability_item_usage_sven.lua | 17 +- ability_item_usage_templar_assassin.lua | 29 +- ability_item_usage_terrorblade.lua | 28 +- ability_item_usage_tidehunter.lua | 60 +- ability_item_usage_tinker.lua | 4 +- ability_item_usage_treant.lua | 48 +- ability_item_usage_troll_warlord.lua | 17 +- ability_item_usage_tusk.lua | 85 +- ability_item_usage_undying.lua | 20 +- ability_item_usage_ursa.lua | 33 +- ability_item_usage_vengefulspirit.lua | 29 +- ability_item_usage_venomancer.lua | 13 +- ability_item_usage_warlock.lua | 21 +- ability_item_usage_weaver.lua | 8 +- ability_item_usage_windrunner.lua | 5 +- ability_item_usage_winter_wyvern.lua | 38 +- ability_item_usage_zuus.lua | 14 +- bot_beastmaster.lua | 27 +- bot_brewmaster.lua | 21 +- bot_earth_spirit.lua | 1 - bot_elder_titan.lua | 1 - bot_ember_spirit.lua | 9 + bot_lone_druid.lua | 2 - bot_razor.lua | 48 + bot_templar_assassin.lua | 51 +- bot_undying.lua | 7 +- bot_weaver.lua | 4 + bot_zuus.lua | 4 + changelog/changelog_en.txt | 50 +- changelog/changelog_zh_cn.txt | 6 +- dev/DEV_ability_item_usage_normal2.lua | 9 +- dev/DEV_ability_item_usage_skeleton_king.lua | 3 +- hero_selection.lua | 15 +- item_purchase_abaddon.lua | 14 +- item_purchase_abyssal_underlord.lua | 10 +- item_purchase_alchemist.lua | 17 +- item_purchase_ancient_apparition.lua | 4 +- item_purchase_arc_warden.lua | 8 +- item_purchase_bane.lua | 5 +- item_purchase_batrider.lua | 9 +- item_purchase_beastmaster.lua | 2 - item_purchase_bloodseeker.lua | 4 +- item_purchase_brewmaster.lua | 1 - item_purchase_bristleback.lua | 2 +- item_purchase_broodmother.lua | 5 +- item_purchase_chen.lua | 2 +- item_purchase_crystal_maiden.lua | 2 +- item_purchase_dark_seer.lua | 5 +- item_purchase_dazzle.lua | 9 +- item_purchase_death_prophet.lua | 3 +- item_purchase_disruptor.lua | 5 +- item_purchase_doom_bringer.lua | 13 +- item_purchase_dragon_knight.lua | 3 +- item_purchase_drow_ranger.lua | 3 +- item_purchase_earth_spirit.lua | 1 - item_purchase_earthshaker.lua | 3 +- item_purchase_ember_spirit.lua | 18 +- item_purchase_enchantress.lua | 5 +- item_purchase_enigma.lua | 9 +- item_purchase_gyrocopter.lua | 3 +- item_purchase_hoodwink.lua | 3 +- item_purchase_invoker.lua | 7 +- item_purchase_jakiro.lua | 9 +- item_purchase_juggernaut.lua | 2 +- item_purchase_keeper_of_the_light.lua | 3 +- item_purchase_legion_commander.lua | 1 - item_purchase_leshrac.lua | 8 +- item_purchase_lich.lua | 4 +- item_purchase_life_stealer.lua | 8 +- item_purchase_lina.lua | 4 +- item_purchase_lion.lua | 7 +- item_purchase_mirana.lua | 7 +- item_purchase_naga_siren.lua | 2 +- item_purchase_necrolyte.lua | 5 +- item_purchase_nevermore.lua | 1 - item_purchase_night_stalker.lua | 2 +- item_purchase_nyx_assassin.lua | 12 +- item_purchase_obsidian_destroyer.lua | 5 +- item_purchase_ogre_magi.lua | 6 +- item_purchase_omniknight.lua | 10 +- item_purchase_oracle.lua | 7 +- item_purchase_phantom_assassin.lua | 9 +- item_purchase_phantom_lancer.lua | 1 - item_purchase_pudge.lua | 11 +- item_purchase_pugna.lua | 40 +- item_purchase_queenofpain.lua | 7 +- item_purchase_riki.lua | 2 +- item_purchase_shadow_demon.lua | 5 +- item_purchase_shadow_shaman.lua | 3 +- item_purchase_shredder.lua | 2 +- item_purchase_silencer.lua | 7 +- item_purchase_skeleton_king.lua | 12 +- item_purchase_skywrath_mage.lua | 7 +- item_purchase_sniper.lua | 1 - item_purchase_spectre.lua | 2 +- item_purchase_templar_assassin.lua | 5 +- item_purchase_tidehunter.lua | 9 +- item_purchase_tiny.lua | 5 +- item_purchase_treant.lua | 14 +- item_purchase_troll_warlord.lua | 9 +- item_purchase_tusk.lua | 6 +- item_purchase_undying.lua | 3 +- item_purchase_ursa.lua | 10 +- item_purchase_vengefulspirit.lua | 10 +- item_purchase_venomancer.lua | 9 +- item_purchase_warlock.lua | 24 +- item_purchase_weaver.lua | 2 +- item_purchase_windrunner.lua | 8 +- item_purchase_winter_wyvern.lua | 6 +- item_purchase_witch_doctor.lua | 4 +- item_purchase_zuus.lua | 4 +- mode_farm_generic.lua | 86 +- mode_push_tower_bot_generic.lua | 4 +- mode_push_tower_mid_generic.lua | 4 +- mode_push_tower_top_generic.lua | 4 +- mode_retreat_antimage.lua | 21 + mode_retreat_furion.lua | 21 + mode_rune_generic.lua | 38 +- mode_side_shop_generic.lua | 60 +- mode_team_roam_generic.lua | 535 +++-- mode_ward_generic.lua | 19 +- team_desires.lua | 2 +- util/AbilityAbstraction.lua | 1973 ++++++++++++++++-- util/AbilityInformation.lua | 0 util/CourierSystem.lua | 34 +- util/ItemPurchaseSystem.lua | 282 ++- util/ItemUsageSystem.lua | 280 ++- util/NewMinionUtil.lua | 10 +- util/PushUtility.lua | 59 +- util/RoleUtility.lua | 1 - utility.lua | 4 +- 212 files changed, 5767 insertions(+), 3857 deletions(-) create mode 100644 ability_item_usage_rattletrap.lua create mode 100644 bot_ember_spirit.lua create mode 100644 bot_razor.lua create mode 100644 mode_retreat_antimage.lua create mode 100644 mode_retreat_furion.lua create mode 100644 util/AbilityInformation.lua diff --git a/.gitignore b/.gitignore index b36a9257..fc4cff47 100644 --- a/.gitignore +++ b/.gitignore @@ -41,4 +41,6 @@ luac.out LICENSE .vscode +.DS_Store .idea + diff --git a/ability_item_usage_abaddon.lua b/ability_item_usage_abaddon.lua index 0b1fc350..9d85babb 100644 --- a/ability_item_usage_abaddon.lua +++ b/ability_item_usage_abaddon.lua @@ -76,6 +76,13 @@ end local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} + +local attackRange +local health +local healthPercent +local mana +local manaPercent + local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -117,8 +124,7 @@ Consider[1]=function() -- TODO: lv 25 AOE mist coil local Damage = ability:GetAbilityDamage(); local SelfDamage = ability:GetSpecialValueInt("self_damage"); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( CastRange+150, false, BOT_MODE_NONE ); for _,hero in pairs (allys) do @@ -232,6 +238,150 @@ Consider[1]=function() -- TODO: lv 25 AOE mist coil end + +-- local function MistCoilAuxilliaryCanCast(t) +-- if AbilityExtensions:IsOnSameTeam(npcBot, t) then +-- return AbilityExtensions:AllyCanCast(t) +-- else +-- return AbilityExtensions:NormalCanCast(t, true, DAMAGE_TYPE_MAGICAL) +-- end +-- end + +-- local function MistCoilPrimaryCanCast(t) +-- if AbilityExtensions:IsOnSameTeam(npcBot, t) then +-- return AbilityExtensions:AllyCanCast(t) +-- else +-- return AbilityExtensions:NormalCanCast(t, true, DAMAGE_TYPE_MAGICAL) and not AbilityExtensions:HasModifier("modifier_antimage_counterspell") +-- end +-- end + +-- local function NormalMistCoil() +-- local ability=AbilitiesReal[1] + +-- if not ability:IsFullyCastable() then +-- return BOT_ACTION_DESIRE_NONE +-- end + +-- local abilityLevel = ability:GetLevel() +-- local castRange = ability:GetCastRange() +-- local castPoint = ability:GetCastPoint() +-- local manaCost = ability:GetManaCost() +-- local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, castRange) +-- local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) +-- local friends = AbilityExtensions:GetNearbyHeroes(npcBot, 1200, true) +-- local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) +-- local targettableFriends = AbilityExtensions:Remove(friends, npcBot) + +-- local hasBorrowedTime = npcBot:HasModifier("modifier_abaddon_borrowed_time") +-- local hasAphoticShield = npcBot:HasModifier("modifier_abaddon_aphotic_shield") + +-- local damage = ability:GetDamage() +-- local selfDamage = npcBot:GetActualIncomingDamage(damage * ability:GetSpecialValueInt("self_damage") / 100, DAMAGE_TYPE_PURE) +-- local function ChangeDesireBasedOnMyBuff(desire) +-- if hasBorrowedTime then +-- if healthPercent <= 0.75 then +-- desire = desire * 2 +-- else +-- desire = desire * 1.5 +-- end +-- else +-- if hasAphoticShield and healthPercent >= 0.6 then +-- desire = desire * 1.2 +-- else +-- desire = desire - RemapValClamped(health, selfDamage*1.1, selfDamage*4, 0.8, 0) +-- end +-- end +-- end + +-- local function ProtectFriends() +-- local protectFriends = AbilityExtensions:Filter(targettableFriends, function(t) return AbilityExtensions:MayNotBeIllusion(t) and MistCoilPrimaryCanCast(t) and AbilityExtensions:GetMaxHealth(t) <= 0.7 and t:GetHealth() <= health * 2 end) +-- AbilityExtensions:ForEach(protectFriends, function(t) +-- local desire = RemapValClamped(t:GetHealth(), 100, 800, BOT_ACTION_DESIRE_HIGH, BOT_ACTION_DESIRE_VERYLOW) +-- desire = ChangeDesireBasedOnMyBuff(desire) +-- if AbilityExtensions:IsSeverelyDisabledOrSlowed(t) then +-- desire = desire * 1.5 +-- end +-- coroutine.yield(Clamp(desire, 0, 0.8), t) +-- end) +-- end + +-- if AbilityExtensions:IsAttackingEnemies(npcBot) then +-- AbilityExtensions:ForEach(realEnemies, function(t) +-- if AbilityExtensions:GetHealthPercent(t) <= 0.6 and MistCoilPrimaryCanCast(t) then +-- local actualDamage = t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) +-- local desire = RemapValClamped(t:GetHealth(), actualDamage*1.1, actualDamage*8, BOT_ACTION_DESIRE_HIGH, BOT_ACTION_DESIRE_VERYLOW) +-- desire = ChangeDesireBasedOnMyBuff(desire) +-- coroutine.yield(Clamp(desire, 0, 0.8), t) +-- end +-- end) +-- ProtectFriends() +-- elseif AbilityExtensions:IsLaning(npcBot) then +-- if friendCount == 1 and health > selfDamage + 0.6 * npcBot:GetMaxHealth() and manaPercent > 0.3 + manaCost then +-- local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, 900) +-- local weakCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) return t:GetHealth() <= t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) end) +-- weakCreeps = AbilityExtensions:Filter(weakCreeps, function(t) return t:WasRecentlyDamagedByCreep(1.7) and t:GetAttackRange() >= 450 and GetUnitToLocationDistanceSqr(npcBot, t) > 300^2 end) +-- AbilityExtensions:ForEach(weakCreeps, function(t) +-- coroutine.yield(BOT_ACTION_DESIRE_MODERATE, t) +-- end) +-- end +-- elseif AbilityExtensions:IsRetreating(npcBot) then +-- if not npcBot:WasRecentlyDamagedByAnyHero(0.7) and AbilityExtensions:IsSeverelyDisabledOrSlowed(npcBot) then +-- if npcBot:HasModifier("modifier_abaddon_borrowed_time") then +-- local attackEnemies = AbilityExtensions:Filter(realEnemies, function(t) return MistCoilPrimaryCanCast(t) and t:GetHealth() <= 800 end) +-- AbilityExtensions:ForEach(attackEnemies, function(t) +-- return RemapValClamped(t:GetHealth(), 100, 800, BOT_ACTION_DESIRE_VERYHIGH, BOT_ACTION_DESIRE_LOW) +-- end) +-- end +-- end +-- else +-- ProtectFriends() +-- end +-- return 0 +-- end + +-- local function AOEMistCoil() +-- local ability=AbilitiesReal[1] + +-- if not ability:IsFullyCastable() then +-- return BOT_ACTION_DESIRE_NONE +-- end + +-- local abilityLevel = ability:GetLevel() +-- local castRange = ability:GetCastRange() +-- local castPoint = ability:GetCastPoint() +-- local manaCost = ability:GetManaCost() +-- local damage = ability:GetDamage() +-- local selfDamage = npcBot:GetActualIncomingDamage(damage * ability:GetSpecialValueInt("self_damage") / 100, DAMAGE_TYPE_PURE) +-- local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, castRange) +-- local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) +-- local friends = AbilityExtensions:GetNearbyHeroes(npcBot, 1200, true) +-- local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) +-- local targettableFriends = AbilityExtensions:Remove(friends, npcBot) +-- local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, 900) +-- local friendCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, npcBot:GetAttackRange()+150, false) +-- local weakCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) return t:GetHealth() < t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) end) +-- local weakestCreep = utility.GetWeakestUnit(weakCreeps) +-- local forbiddenCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) +-- return t:GetHealth() > t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) and t:GetHealth() <= t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) + AbilityExtensions:AttackOnceDamage(npcBot, t) * (0.9+#enemyCreeps*0.1) +-- end) +-- if #friendCreeps == 0 then +-- forbiddenCreeps = {} +-- end + +-- local hasBorrowedTime = npcBot:HasModifier("modifier_abaddon_borrowed_time") +-- local hasAphoticShield = npcBot:HasModifier("modifier_abaddon_aphotic_shield") + +-- end + +-- Consider[1] = function() +-- local ability25 = npcBot:GetAbilityByName("special_bonus_unique_abaddon_4") +-- if ability25:IsTrained() then +-- return NormalMistCoil() +-- else +-- return AOEMistCoil() +-- end +-- end + Consider[2]=function() local abilityNumber=2 -------------------------------------- @@ -246,8 +396,7 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( CastRange+300, false, BOT_MODE_NONE ); local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) @@ -269,7 +418,7 @@ Consider[2]=function() end end if( npcBot:GetActiveMode() == BOT_MODE_ATTACK or - npcBot:GetActiveMode() == BOT_DEFEND_ALLY or + npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or ManaPercentage>0.4) then for _,npcTarget in pairs( allys ) @@ -403,7 +552,7 @@ Consider[4]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or npcBot:HasModifier("modifier_ice_blast") then return BOT_ACTION_DESIRE_NONE, 0; end @@ -415,6 +564,7 @@ Consider[4]=function() return BOT_ACTION_DESIRE_NONE end + AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) function AbilityUsageThink() @@ -429,6 +579,11 @@ function AbilityUsageThink() AttackRange=npcBot:GetAttackRange() ManaPercentage=npcBot:GetMana()/npcBot:GetMaxMana() HealthPercentage=npcBot:GetHealth()/npcBot:GetMaxHealth() + attackRange = npcBot:GetAttackRange() + health = npcBot:GetHealth() + healthPercent = AbilityExtensions:GetHealthPercent(npcBot) + mana = npcBot:GetMana() + manaPercent = AbilityExtensions:GetManaPercent(npcBot) cast=ability_item_usage_generic.ConsiderAbility(AbilitiesReal,Consider) ---------------------------------debug-------------------------------------------- diff --git a/ability_item_usage_abyssal_underlord.lua b/ability_item_usage_abyssal_underlord.lua index 2962e650..9ea99541 100644 --- a/ability_item_usage_abyssal_underlord.lua +++ b/ability_item_usage_abyssal_underlord.lua @@ -328,6 +328,29 @@ Consider[2]=function() --Location AOE Example end +local function FindNearbyTeleportTarget(target) + local isEnemy = not AbilityExtensions:IsOnSameTeam(npcBot, target) + local castDelay = AbilitiesReal[4]:GetSpecialValueInt("cast_delay") + local creeps = target:GetNearbyCreeps(600, isEnemy) + creeps = AbilityExtensions:Filter(creeps, function(t) return not t:WasRecentlyDamagedByAnyHero(3) and #t:GetNearbyHeroes(500, true, BOT_MODE_NONE) == 0 end) + creeps = AbilityExtensions:Max(creeps, function(t) return t:GetHealth() end) + local buildings = AbilityExtensions:Concat(target:GetNearbyTowers(700, isEnemy), target:GetNearbyBarracks(700, isEnemy)) + buildings = AbilityExtensions:Filter(buildings, function(t) return t:HasModifier("modifier_backdoor_protection_active") and t:GetHealth() >= 100 or t:GetHealth() >= 300 and not t:WasRecentlyDamagedByAnyHero(castDelay-2) or t:GetHealth() >= 800 or t:HasModifier("modifier_fountain_glyph") end) + buildings = AbilityExtensions:Max(buildings, function(t) return AbilityExtensions:GetBuildingPhysicalHealth(t) end) + local hero + if AbilityExtensions:HasScepter(npcBot) then + local friends = target:GetNearbyHeroes(900, isEnemy, BOT_MODE_NONE) + friends = AbilityExtensions:Filter(friends, function(t) return t:NotRetreating(t) and AbilityExtensions:AllyCanCast(t) and AbilityExtensions:GetHealthPercent(t) >= 0.5 and not t:IsSeverelyDisabled(t) end) + friends = AbilityExtensions:FilterNot(friends, function(t) return t:IsIllusion() and t:GetModifierRemainingDuration("modifier_illusion") <= castDelay end) + hero = target:Max(friends, function(t) return t:GetHealth() end) + end + return buildings or hero or creeps +end + +local darkRiftOriginalTarget +local trackOriginalTargetPosition +local darkRiftChosenTarget + Consider[4]=function() local abilityNumber=4 @@ -336,7 +359,7 @@ Consider[4]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or npcBot:HasModifier("modifier_abyssal_underlord_dark_rift") then return BOT_ACTION_DESIRE_NONE, 0; end @@ -351,12 +374,11 @@ Consider[4]=function() local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - -- If we're seriously retreating, see if we can land a stun on someone who's damaged us recently if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) then - if ( npcBot:WasRecentlyDamagedByAnyHero( 2.0 ) ) + if ( npcBot:WasRecentlyDamagedByAnyHero( 2.0 ) and AbilityExtensions:GetHealthPercent(npcBot) >= 0.25 ) then - return BOT_ACTION_DESIRE_MODERATE, GetAncient(GetTeam()):GetLocation(); + return BOT_ACTION_DESIRE_MODERATE, GetAncient(GetTeam()):GetLocation(), "Location" end end @@ -366,13 +388,17 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then - if ( #enemys==0 and #creeps==0 and #allys>=2 and GetUnitToUnitDistance( npcEnemy, npcBot ) > 3000 ) + if ( #enemys==0 and #allys>=2 and GetUnitToUnitDistance( npcEnemy, npcBot ) > 3000 ) then - return BOT_ACTION_DESIRE_HIGH, npcEnemy:GetExtrapolatedLocation(CastPoint); + local target = FindNearbyTeleportTarget(npcEnemy) + if target ~= nil then + darkRiftOriginalTarget = npcEnemy + return BOT_ACTION_DESIRE_HIGH, target, "Target" + end end end end @@ -380,9 +406,36 @@ Consider[4]=function() return BOT_ACTION_DESIRE_NONE, 0; end +local darkRiftCancelRange = 1200^2 +Consider[5] = function() + local ability = AbilitiesReal[5] + if not ability:IsFullyCastable() or ability:IsHidden() then + return 0 + end + local target = AbilityExtensions:GetTargetIfGood(npcBot) + if darkRiftChosenTarget then + if darkRiftOriginalTarget:IsAlive() then + if GetUnitToUnitDistanceSqr(darkRiftChosenTarget, darkRiftOriginalTarget) >= darkRiftCancelRange then + coroutine.yield(BOT_ACTION_DESIRE_MODERATE) + end + else + if GetUnitToLocationDistanceSqr(darkRiftChosenTarget, trackOriginalTargetPosition) >= darkRiftCancelRange and (target == nil or target:CanBeSeen() and GetUnitToLocationDistanceSqr(darkRiftChosenTarget, target) >= darkRiftCancelRange) then + coroutine.yield(BOT_ACTION_DESIRE_HIGH) + elseif AbilityExtensions:IsRetreating(npcBot) then + coroutine.yield(BOT_ACTION_DESIRE_MODERATE) + end + end + end + return 0 +end + AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) function AbilityUsageThink() - + if npcBot:HasModifier("modifier_abyssal_underlord_dark_rift") then + if darkRiftOriginalTarget and darkRiftOriginalTarget:IsAlive() and darkRiftOriginalTarget:CanBeSeen() then + trackOriginalTargetPosition = darkRiftOriginalTarget:GetLocation() + end + end -- Check if we're already using an ability if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() ) then diff --git a/ability_item_usage_alchemist.lua b/ability_item_usage_alchemist.lua index 76cd2392..ab075e5d 100644 --- a/ability_item_usage_alchemist.lua +++ b/ability_item_usage_alchemist.lua @@ -299,7 +299,7 @@ function Consider2() then local npcEnemy = npcBot:GetTarget(); - if ( npcEnemy ~= nil ) + if ( npcEnemy ~= nil ) and npcEnemy:IsHero() then if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange + 75*#allys) then @@ -392,6 +392,7 @@ Consider[4]=function() local CastPoint = ability:GetCastPoint(); local allys = npcBot:GetNearbyHeroes( CastRange+200, false, BOT_MODE_NONE ); + local enemys = npcBot:GetNearbyHeroes(1200, true, BOT_MODE_NONE) -- use at myself when chemical rage is not available local useTable = {} if not npcBot:HasModifier("modifier_alchemist_chemical_rage") and not npcBot:HasModifier("modifier_alchemist_berserk_potion") then @@ -535,7 +536,7 @@ Consider[6]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -548,10 +549,17 @@ Consider[6]=function() end end end - - if(TimeSinceCast>=5) - then - return BOT_ACTION_DESIRE_HIGH+0.1,enemys[1] + + if TimeSinceCast >= 4 or TimeSinceCast >= 3 and enemys[1]:GetStunDuration(true) >= 2 then + return BOT_ACTION_DESIRE_VERYHIGH,enemys[1] + end + if TimeSinceCast >= 2.5 then + local silencer = AbilityExtensions:Count(enemys, function(t) + return AbilityExtensions:MayNotBeIllusion(t) and t:HasSilence() + end) + if silencer > 0 then + return BOT_ACTION_DESIRE_HIGH, enemys[1] + end end -- throw when I'm hurt @@ -565,6 +573,40 @@ Consider[6]=function() end AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) +local function HasRealScepter(t) + return t:HasScepter() or t:HasModifier("modifier_item_ultimate_scepter") or t:HasModifier("modifier_item_ultimate_scepter_consumed_alchemist") +end + +local function GetNonScepterFriends() + local friends = GetTeamPlayers(GetTeam()) + return AbilityExtensions:FilterNot(friends, function(t) return HasRealScepter(t) end) +end + +local function GetFeedScepterDesire(t) + if npcBot == t then + return 0.1 + end + if HasRealScepter(t) then + return 0 + end + local tb = t.itemInformationTable + local scepterIndex = AbilityExtensions:IndexOf(tb, function(tp) return tp.name == "item_ultimate_scepter" or tp.name == "item_recipe_ultimate_scepter" end) + if scepterIndex == -1 then + return 0.02 + elseif scepterIndex == 1 then + return 0 + end + local desire = RemapValClamped(scepterIndex, 2, 4, 0.8, 0.2) + return desire +end + +local function CheckFeedScepter() + local friends = GetNonScepterFriends() + friends = AbilityExtensions:Filter(friends, function(t) return t:IsAlive() and AbilityExtensions:AllyCanCast(t) and GetUnitToUnitDistance(t, npcBot) <= 1400 end) + AbilityExtensions:ForEach(friends, function(t) coroutine.yield(GetFeedScepterDesire(t), t) end) +end +CheckFeedScepter = AbilityExtensions:EveryManySeconds(1, CheckFeedScepter) + function AbilityUsageThink() -- Check if we're already using an ability @@ -584,7 +626,19 @@ function AbilityUsageThink() then ability_item_usage_generic.PrintDebugInfo(AbilitiesReal,cast) end - ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + local index, target, castType = ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + if index == nil then + local scepter = AbilityExtensions:GetAvailableItem(npcBot, "item_ultimate_scepter") + if scepter and not AbilityExtensions:IsMuted(npcBot) then + local desirePairs = AbilityExtensions:ResumeUntilReturn(CheckFeedScepter) + if AbilityExtensions:CalledOnThisFrame(desirePairs) then + local bestDesire = AbilityExtensions:Max(desirePairs, function(t) return t[1] end) + if bestDesire[1] ~= 0 then + npcBot:Action_UseAbilityOnEntity(scepter, bestDesire[2]) + end + end + end + end end function CourierUsageThink() diff --git a/ability_item_usage_ancient_apparition.lua b/ability_item_usage_ancient_apparition.lua index 84ffe08e..dcfd6343 100644 --- a/ability_item_usage_ancient_apparition.lua +++ b/ability_item_usage_ancient_apparition.lua @@ -15,11 +15,7 @@ local Talents ={} local Abilities ={} local AbilitiesReal ={} -ability_item_usage_generic.InitAbility(Abilities,AbilitiesReal,Talents) - --- utility.PrintAbilityName(Abilities) -local abilityName = { "ancient_apparition_cold_feet", "ancient_apparition_ice_vortex", "ancient_apparition_chilling_touch", "ancient_apparition_ice_blast", "ancient_apparition_ice_blast_release" } -local abilityIndex = utility.ReverseTable(abilityName) +ability_item_usage_generic.InitAbility(Abilities,AbilitiesReal,Talents) local AbilityToLevelUp= diff --git a/ability_item_usage_antimage.lua b/ability_item_usage_antimage.lua index be9c2af7..168b7dee 100644 --- a/ability_item_usage_antimage.lua +++ b/ability_item_usage_antimage.lua @@ -90,13 +90,37 @@ function GetComboMana() return ability_item_usage_generic.GetComboMana(AbilitiesReal) end -local function GetIncomingDodgeableProjectiles() - local incProj = npcBot:GetIncomingTrackingProjectiles() or {} - return AbilityExtensions:Filter(incProj, function(t) - return not t.is_attack and not AbilityExtensions:IgnoreAbilityBlock(p.ability) and t.caster:GetTeam() ~= npcBot:GetTeam() - end) +local function GetBlinkAttackLocation(enemy) + local attackDistance = enemy:GetBoundingRadius() + npcBot:GetBoundingRadius() + if AbilityExtensions:HasPhasedMovement(enemy) or AbilityExtensions:HasUnobstructedMovement(enemy) then + attackDistance = npcBot:GetAttackRange() + end + local enemyNextStep = enemy:GetLocation() + Vector(math.cos(enemy:GetFacing()), math.sin(enemy:GetFacing())) * attackDistance + local distanceFromNextStep = GetUnitToLocationDistance(npcBot, enemyNextStep) + local blinkRadius = AbilitiesReal[2]:GetSpecialValueInt("blink_range") + if AbilityExtensions:HasPhasedMovement(enemy) or AbilityExtensions:HasUnobstructedMovement(enemy) then + + end + if blinkRadius <= distanceFromNextStep then + return AbilityExtensions:GetPointFromLineByDistance(npcBot:GetLocation(), enemy:GetLocation(), blinkRadius) + else + return enemyNextStep + end end +local function TooDangerousToBlinkNear(npc) + local enoughHealth = AbilityExtensions:GetHealthPercent(npcBot) >= AbilityExtensions:GetHealthPercent(npc) + 0.2 and npcBot:GetHealth() >= npc:GetHealth() * 0.8 + local isVeryDangerous = npc:HasModifier("modifier_medusa_stone_gaze") or npc:HasModifier("modifier_faceless_void_chronosphere_selfbuff") or npc:HasModifier("modifier_monkey_king_fur_army_soldier_in_position") or AbilityExtensions:IsInvulnerable(npc) + if isVeryDangerous then + return true + end + local isDangerous = npc:HasModifier("modifier_batrider_firefly") or npc:HasModifier("modifier_winter_wyvern_arctic_burn_flight") or npc:IsMagicImmune() + if isDangerous and not enoughHealth then + return true + end + return false +end + Consider[2]=function() local abilityNumber=2 -------------------------------------- @@ -104,7 +128,7 @@ Consider[2]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotTeleport(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end @@ -124,7 +148,10 @@ Consider[2]=function() then if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana and GetUnitToUnitDistance(npcBot,WeakestEnemy) > 200) then - return BOT_ACTION_DESIRE_HIGH,utility.GetUnitsTowardsLocation(npcBot,WeakestEnemy,CastRange+200); + if TooDangerousToBlinkNear(WeakestEnemy) then + return 0 + end + return BOT_ACTION_DESIRE_HIGH, GetBlinkAttackLocation(WeakestEnemy) end end end @@ -162,7 +189,10 @@ Consider[2]=function() then if ( CanCast[abilityNumber]( npcEnemy ) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange + 75*#allys and GetUnitToUnitDistance(npcBot,npcEnemy) > 200) then - return BOT_ACTION_DESIRE_MODERATE, utility.GetUnitsTowardsLocation(npcBot,npcEnemy,CastRange+200); + if TooDangerousToBlinkNear(npcEnemy) then + return 0 + end + return BOT_ACTION_DESIRE_MODERATE, GetBlinkAttackLocation(npcEnemy) end end end @@ -170,10 +200,10 @@ Consider[2]=function() end -- use blink to dodge ability - local projectiles = GetIncomingDodgeableProjectiles() + local projectiles = AbilityExtensions:GetIncomingDodgeWorthProjectiles(npcBot) local castPoint = ability:GetCastPoint() local defaultProjectileVelocity = 1500 - if #projectiles ~= 0 and not AbilityToLevelUp[3]:IsFullyCastable() then + if #projectiles ~= 0 and not AbilitiesReal[3]:IsFullyCastable() and not npcBot:HasModifier("modifier_antimage_counterspell") then for _, projectile in pairs(projectiles) do if GetUnitToLocationDistance(npcBot, projectile.location) > castPoint * defaultProjectileVelocity then local escapeLocation = utility.GetUnitsTowardsLocation(npcBot, projectile.location, 400) @@ -226,10 +256,10 @@ Consider[3]=function() then if CanCast[abilityNumber]( npcTarget ) and GetUnitToUnitDistance(npcBot,npcTarget) < 600 then - local incProj = npcBot:GetIncomingTrackingProjectiles() + local incProj = AbilityExtensions:GetIncomingDodgeWorthProjectiles(npcBot) for _,p in pairs(incProj) do - if GetUnitToLocationDistance(npcBot, p.location) <= 300 and p.is_attack == false and not AbilityExtensions:IgnoreAbilityBlock(p.ability) then + if GetUnitToLocationDistance(npcBot, p.location) <= 300 then return BOT_ACTION_DESIRE_HIGH end end @@ -285,7 +315,6 @@ Consider[5]=function() if npcBot:GetActiveMode() ~= BOT_MODE_RETREAT then local targets = npcBot:GetNearbyHeroes(CastRange+400,true,BOT_MODE_NONE) - local filter = function(t) return CanCast[abilityNumber](t) end local goodTargets = {} for _,t in pairs(targets) do if AbilityExtensions:MustBeIllusion(npcBot, t) then @@ -322,29 +351,6 @@ Consider[5]=function() end end - --if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) - --then - -- for i,npcEnemy in pairs(enemys) - -- do - -- if ( CanCast[abilityNumber]( npcEnemy ) ) - -- then - -- local enemys = npcEnemy:GetNearbyHeroes(Radius,false,BOT_MODE_NONE) - -- local Damage=(npcEnemy:GetMaxMana()-npcEnemy:GetMana())*DamagePercent - -- local ManaPercentageEnemy=npcEnemy:GetMana()/npcEnemy:GetMaxMana() - -- if(enemys~=nil) - -- then - -- Damage=Damage*(1+0.2*#enemys) - -- end - -- - -- if(npcEnemy:GetHealth()<=npcEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL)) - -- then - -- return BOT_ACTION_DESIRE_HIGH,npcEnemy; - -- end - -- end - -- end - --end - - -- Check for a channeling enemy for _,npcEnemy in pairs( enemys ) do if ( npcEnemy:IsChanneling() and CanCast[abilityNumber]( npcEnemy )) diff --git a/ability_item_usage_arc_warden.lua b/ability_item_usage_arc_warden.lua index 0ae9baa4..1460cc7b 100644 --- a/ability_item_usage_arc_warden.lua +++ b/ability_item_usage_arc_warden.lua @@ -14,7 +14,7 @@ require(GetScriptDirectory() .. "/ability_item_usage_generic") local AbilityExtensions = require(GetScriptDirectory().."/util/AbilityAbstraction") local debugmode=false -local npcBot = nil; +local npcBot = GetBot() local Talents ={} local Abilities ={} local AbilitiesReal ={} @@ -114,7 +114,8 @@ Consider[1]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or npcBot:GetMana() < ability:GetManaCost() or not ability:IsCooldownReady() then + -- tempest double doesn't check ability:IsFullyCastable(), so manual check is required here return BOT_ACTION_DESIRE_NONE, 0; end @@ -149,17 +150,17 @@ Consider[1]=function() -------------------------------------- --protect myself local enemys2 = npcBot:GetNearbyHeroes( 400, true, BOT_MODE_NONE ); - -- --[[ If we're seriously retreating, see if we can land a stun on someone who's damaged us recently - -- if ( (npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH) or #enemys2>0) - -- then - -- for _,npcEnemy in pairs( enemys ) - -- do - -- if ( (npcBot:WasRecentlyDamagedByHero( npcEnemy, 2.0 ) and CanCast[abilityNumber]( npcEnemy )) or GetUnitToUnitDistance(npcBot,npcEnemy)<400) - -- then - -- return BOT_ACTION_DESIRE_HIGH, npcEnemy; - -- end - -- end - -- end]] + --[[ If we're seriously retreating, see if we can land a stun on someone who's damaged us recently + if ( (npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH) or #enemys2>0) + then + for _,npcEnemy in pairs( enemys ) + do + if ( (npcBot:WasRecentlyDamagedByHero( npcEnemy, 2.0 ) and CanCast[abilityNumber]( npcEnemy )) or GetUnitToUnitDistance(npcBot,npcEnemy)<400) + then + return BOT_ACTION_DESIRE_HIGH, npcEnemy; + end + end + end]] -- If my mana is enough,use it at enemy if ( npcBot:GetActiveMode() == BOT_MODE_LANING ) @@ -181,7 +182,7 @@ Consider[1]=function() then if ( #creeps >=1 ) then - if(npcBot:GetMana()>ComboMana and CanCast[abilityNumber](WeakestCreep)) + if(npcBot:GetMana()>ComboMana*2 and CanCast[abilityNumber](WeakestCreep)) then return BOT_ACTION_DESIRE_LOW, WeakestCreep; end @@ -240,7 +241,7 @@ Consider[2]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or npcBot:GetMana() < ability:GetManaCost() or not ability:IsCooldownReady() then return BOT_ACTION_DESIRE_NONE, 0; end @@ -335,7 +336,7 @@ Consider[3]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or npcBot:GetMana() < ability:GetManaCost() or not ability:IsCooldownReady() then return BOT_ACTION_DESIRE_NONE, 0; end @@ -466,7 +467,7 @@ Consider[4]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or AbilityExtensions:CannotTeleport(npcBot) or AbilityExtensions:IsTempestDouble(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end @@ -484,7 +485,7 @@ Consider[4]=function() -------------------------------------- -- Stop making a huge bounty for the enemy - if (npcBot:GetHealth() <= 450 or HealthPercentage <= 0.3) and (npcBot:WasRecentlyDamagedByAnyHero(1.5) or AbilityExtensions:CanHardlyMove(npcBot) or not AbilityExtensions:CanMove(npcBot)) and not AbilityExtensions:Outnumber(allys, enemys) then + if (npcBot:GetHealth() <= 450 or HealthPercentage <= 0.3) and (npcBot:WasRecentlyDamagedByAnyHero(1.5) or AbilityExtensions:CanHardlyMove(npcBot) or AbilityExtensions:CannotTeleport(npcBot)) and not AbilityExtensions:Outnumber(npcBot, allys, enemys) then return 0 end diff --git a/ability_item_usage_axe.lua b/ability_item_usage_axe.lua index a070df2b..a93d1ac9 100644 --- a/ability_item_usage_axe.lua +++ b/ability_item_usage_axe.lua @@ -74,6 +74,10 @@ end local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} +CanCast[1] = function(t) + return AbilityExtensions:NormalCanCast(t, false, DAMAGE_TYPE_PURE, true, false) +end + local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -100,12 +104,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius()-50 local CastPoint = ability:GetCastPoint() - local i=npcBot:FindItemSlot("item_blink") - if(i>=0 and i<=5) - then - blink=npcBot:GetItemInSlot(i) - i=nil - end + local blink = AbilityExtensions:GetAvailableBlink(npcBot) if(blink~=nil and blink:IsFullyCastable()) then CastRange=CastRange+1200 @@ -120,8 +119,7 @@ Consider[1]=function() end end - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -196,7 +194,7 @@ Consider[1]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -330,7 +328,7 @@ Consider[2]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -358,41 +356,61 @@ Consider[4]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetSpecialValueInt("kill_threshold"); + local function IsWeak(t) + return AbilityExtensions:NormalCanCast(t,true, DAMAGE_TYPE_PURE,true, true) and t:GetHealth() <= Damage + end local CastPoint = ability:GetCastPoint(); local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) + local realEnemies = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, CastRange+300) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) -------------------------------------- -- Global high-priorty usage -------------------------------------- --Try to kill enemy hero - if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) - then - for _,npcEnemy in pairs(enemys) - do - if(npcEnemy:GetHealth()<=Damage) - then - return BOT_ACTION_DESIRE_HIGH,npcEnemy; + if AbilityExtensions:NotRetreating(npcBot) then + if #realEnemies > 0 then + local weakEnemy = AbilityExtensions:First(realEnemies, IsWeak) + if weakEnemy then + return BOT_ACTION_DESIRE_HIGH, weakEnemy + end + else -- only kill illusions when there are no real heroes + local weakEnemy = AbilityExtensions:First(enemys, IsWeak) + if AbilityExtensions:GetHealthPercent(npcBot) <= 0.3 and AbilityExtensions:GetManaPercent(npcBot) >= 0.5 + AbilitiesReal[4]:GetManaCost() and not npcBot:HasModifier("modifier_axe_culling_blade_boost") and weakEnemy then + return BOT_ACTION_DESIRE_MODERATE, weakEnemy end end end - - -------------------------------------- - -- Mode based usage - -------------------------------------- - return BOT_ACTION_DESIRE_NONE, 0; + return BOT_ACTION_DESIRE_NONE end AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) +local cullingBladeTarget + function AbilityUsageThink() -- Check if we're already using an ability if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() ) then + if npcBot:IsCastingAbility() then + if npcBot:GetCurrentActiveAbility() == AbilitiesReal[1] then + if not AbilityExtensions:IsFarmingOrPushing(npcBot) then + local nearbyEnemies = AbilityExtensions:GetNearbyHeroes(npcBot, AbilitiesReal[1]:GetAOERadius()) + nearbyEnemies = AbilityExtensions:Filter(nearbyEnemies, CanCast[1]) + if #nearbyEnemies == 0 then + npcBot:Action_ClearActions() + end + end + elseif npcBot:GetCurrentActiveAbility() == AbilitiesReal[4] and cullingBladeTarget then + if cullingBladeTarget:GetHealth() > AbilitiesReal[4]:GetSpecialValueInt("kill_threshold") then + npcBot:Action_ClearActions() + end + end + end return end @@ -407,7 +425,10 @@ function AbilityUsageThink() then ability_item_usage_generic.PrintDebugInfo(AbilitiesReal,cast) end - ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + local index, target = ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + if index == 4 then + cullingBladeTarget = target + end end function CourierUsageThink() diff --git a/ability_item_usage_bane.lua b/ability_item_usage_bane.lua index 950121be..4f6f6d22 100644 --- a/ability_item_usage_bane.lua +++ b/ability_item_usage_bane.lua @@ -75,13 +75,19 @@ end local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -function CanCast1( npcEnemy ) - return npcEnemy:CanBeSeen() and not npcEnemy:IsMagicImmune() and not npcEnemy:IsInvulnerable() and not npcEnemy:HasModifier( "modifier_bane_enfeeble" ) + +local CanCast = {} +CanCast[1] = function(t) + return AbilityExtensions:NormalCanCast(t, false, DAMAGE_TYPE_MAGICAL, false, true) +end +CanCast[2] = function(t) + return AbilityExtensions:NormalCanCast(t, true, DAMAGE_TYPE_PURE, false, true) and not AbilityExtensions:HasAbilityRetargetModifier(t) and not (AbilityExtensions:HasModifier("modifier_item_blade_mail") and AbilityExtensions:IsRetreating(npcBot)) end -function CanCast2( npcEnemy ) - return npcEnemy:CanBeSeen() and not npcEnemy:IsMagicImmune() and not npcEnemy:IsInvulnerable() and not npcEnemy:WasRecentlyDamagedByAnyHero(2.0) +CanCast[3] = CanCast[1] +CanCast[4] = function(t) + return AbilityExtensions:NormalCanCast(t, false, DAMAGE_TYPE_PURE, true, true) and not AbilityExtensions:HasAbilityRetargetModifier(t) end -local CanCast={CanCast1,CanCast2,utility.NCanCast,utility.UCanCast} + local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -524,8 +530,8 @@ Consider[4]=function() end end]] - if AbilityExtensions:IsRetreating(npcBot) and #enemys == 0 and not AbilityExtensions:HasAbilityRetargetModifier(enemys[1]) then - return BOT_ACTION_DESIRE_HIGH, enemys[0] + if AbilityExtensions:IsRetreating(npcBot) and #enemys == 1 and not AbilityExtensions:HasAbilityRetargetModifier(enemys[1]) then + return BOT_ACTION_DESIRE_HIGH, enemys[1] end -- If we're going after someone @@ -545,7 +551,7 @@ Consider[4]=function() end end - local disabledAllies = AbilityExtensions:Filter(allys, function(t) return AbilityExtensions:IsSeverlyDisabled(t) and not t:IsChanneling() end) + local disabledAllies = AbilityExtensions:Filter(allys, function(t) return AbilityExtensions:IsSeverelyDisabled(t) and not t:IsChanneling() end) disabledAllies = AbilityExtensions:SortByMinFirst(disabledAllies, function(t) return t:GetHealth() end) if #disabledAllies ~= 0 then return BOT_ACTION_DESIRE_MODERATE, disabledAllies[1] @@ -572,8 +578,14 @@ Consider[5]=function() local friends = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, 1200, false, BOT_MODE_NONE) local nightmaredFriends = AbilityExtensions:Filter(friends, function(t) return t:HasModifier("modifier_bane_nightmare") end) if #nightmaredEnemies ~= 0 then - if #enemies == 1 and #friends >= 2 and AbilityExtensions:GetModifierRemainingDuration(nightmaredFriends[1], "modifier_bane_nightmare") <= 4 - or AbilityExtensions:All(nightmaredEnemies, function(t) return AbilityExtensions:GetHealthPercent(t) <= 0.3 and AbilityExtensions:GetModifierRemainingDuration(nightmaredFriends[1], "modifier_bane_nightmare") <= 4 end) and AbilityExtensions:All(friends, function(t) return AbilityExtensions:GetHealthPercent(t) >= 0.5 end) then + if #enemies == 1 and #friends >= 2 and AbilityExtensions:GetModifierRemainingDuration(nightmaredEnemies[1], "modifier_bane_nightmare") <= 4 + or AbilityExtensions:All(nightmaredEnemies, function(t) + return AbilityExtensions:GetHealthPercent(t) <= 0.3 + end) and AbilityExtensions:All(nightmaredFriends, function(t) + return AbilityExtensions:GetModifierRemainingDuration(t, "modifier_bane_nightmare") <= 4 + end) and AbilityExtensions:All(friends, function(t) + return AbilityExtensions:GetHealthPercent(t) >= 0.5 + end) then return BOT_ACTION_DESIRE_HIGH end end @@ -589,11 +601,26 @@ end AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) +local drainSnapTarget +local fiendsGripTarget + function AbilityUsageThink() -- Check if we're already using an ability if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() ) then + if npcBot:IsCastingAbility() then + if npcBot:GetCurrentActiveAbility() == AbilitiesReal[2] then + if drainSnapTarget and AbilityExtensions:HasAbilityRetargetModifier(drainSnapTarget) then + npcBot:Action_ClearActions(true) + end + end + if npcBot:GetCurrentActiveAbility() == AbilitiesReal[4] and not npcBot:IsChanneling() then + if fiendsGripTarget and AbilityExtensions:HasAbilityRetargetModifier(fiendsGripTarget) then + npcBot:Action_ClearActions(true) + end + end + end return end @@ -608,7 +635,12 @@ function AbilityUsageThink() then ability_item_usage_generic.PrintDebugInfo(AbilitiesReal,cast) end - ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + local index, target = ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + if index == 2 then + drainSnapTarget = target + elseif index == 4 then + fiendsGripTarget = target + end end function CourierUsageThink() diff --git a/ability_item_usage_batrider.lua b/ability_item_usage_batrider.lua index 37310095..4ba6812e 100644 --- a/ability_item_usage_batrider.lua +++ b/ability_item_usage_batrider.lua @@ -131,7 +131,7 @@ Consider[1]=function() if ( npcBot:GetActiveMode() == BOT_MODE_FARM ) then local locationAoE = npcBot:FindAoELocation( true, false, npcBot:GetLocation(), CastRange, Radius, 0, Damage ); - if ( locationAoE.count >= 2 ) then + if ( locationAoE.count >= 3 ) then return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc; end end @@ -146,7 +146,7 @@ Consider[1]=function() then local locationAoE = npcBot:FindAoELocation( true, false, npcBot:GetLocation(), CastRange, Radius, 0, 0 ); - if ( locationAoE.count >= 2 ) + if ( locationAoE.count >= 4 ) then return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc; end @@ -202,7 +202,7 @@ Consider[1]=function() if ( npcEnemy ~= nil ) then - if ( CanCast[abilityNumber]( npcEnemy ) ) + if ( CanCast[abilityNumber]( npcEnemy ) ) and npcBot:GetMana() > ComboMana then return BOT_ACTION_DESIRE_HIGH, npcEnemy:GetExtrapolatedLocation(CastPoint); end @@ -215,7 +215,7 @@ end function GetStickyNapalmCount(npcTarget) local modifier=npcTarget:GetModifierByName("modifier_batrider_sticky_napalm") - if(modifier~=nil) + if(modifier~=nil) and modifier ~= -1 then return npcTarget:GetModifierStackCount(modifier) else @@ -578,8 +578,7 @@ Consider[4]=function() then local npcEnemy = npcBot:GetTarget(); - if ( npcEnemy ~= nil ) - then + if npcEnemy ~= nil and npcEnemy:IsHero() and AbilityExtensions:MayNotBeIllusion(npcEnemy) then if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange + 75*#allys) then return BOT_ACTION_DESIRE_MODERATE, npcEnemy diff --git a/ability_item_usage_beastmaster.lua b/ability_item_usage_beastmaster.lua index 8964e05c..9076c10b 100644 --- a/ability_item_usage_beastmaster.lua +++ b/ability_item_usage_beastmaster.lua @@ -73,7 +73,7 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} +local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast,utility.UCanCast} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -466,13 +466,13 @@ Consider[6]=function() --Target Ability Example -- Mode based usage -------------------------------------- --protect myself - local enemys2 = npcBot:GetNearbyHeroes( 400, true, BOT_MODE_NONE ); + local enemys2 = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, CastRange, true) -- If we're seriously retreating, see if we can land a stun on someone who's damaged us recently if ( (npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH) or #enemys2>0) then for _,npcEnemy in pairs( enemys ) do - if ( (npcBot:WasRecentlyDamagedByHero( npcEnemy, 2.0 ) and CanCast[abilityNumber]( npcEnemy )) or GetUnitToUnitDistance(npcBot,npcEnemy)<400) + if ( (npcBot:WasRecentlyDamagedByHero( npcEnemy, 2.0 ) and CanCast[abilityNumber]( npcEnemy )) or GetUnitToUnitDistance(npcBot,npcEnemy)<400) and not AbilityExtensions:HasDamageRetargetModifier(npcEnemy) then return BOT_ACTION_DESIRE_HIGH, npcEnemy; end @@ -485,9 +485,9 @@ Consider[6]=function() --Target Ability Example npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) - if ( npcEnemy ~= nil ) + if ( npcEnemy ~= nil ) then if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange + 75*#allys) then diff --git a/ability_item_usage_bounty_hunter.lua b/ability_item_usage_bounty_hunter.lua index 4a76275d..9d4a6782 100644 --- a/ability_item_usage_bounty_hunter.lua +++ b/ability_item_usage_bounty_hunter.lua @@ -29,12 +29,12 @@ local AbilityToLevelUp= Abilities[3], Abilities[3], "talent", - Abilities[3], + Abilities[2], Abilities[4], Abilities[2], Abilities[2], "talent", - Abilities[2], + Abilities[3], "nil", Abilities[4], "nil", @@ -132,10 +132,10 @@ Consider[1]=function() --Target Ability Example then if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) or (HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana)) then - if(GetUnitToUnitDistance(npcBot,WeakestEnemy)=0.2) - then - for _,npcEnemy in pairs( enemys ) - do - local count=100; - local modifier=npcEnemy:GetModifierByName("modifier_bounty_hunter_track") - if(modifier~=nil) - then - count=npcEnemy:GetModifierRemainingDuration(modifier) - end - - if(npcEnemy:HasModifier("modifier_bounty_hunter_track")==false or count<=5) - then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy; - end + local realEnemies = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, CastRange) + realEnemies = AbilityExtensions:Filter(realEnemies, CanCast[4]) + realEnemies = AbilityExtensions:Map(realEnemies, function(t) + return { t, t:GetHealth()*HasTrackModifierPenalty(t) } + end) + realEnemies = AbilityExtensions:SortByMinFirst(realEnemies, function(t) return t[2] end) + if AbilityExtensions:Any(realEnemies) then + local desire = RemapValClamped(realEnemies[2], 300+ability:GetLevel()*100, 1000, 0.8, 0.4) + if desire >= 0.5 and ManaPercentage >= 0.4 or desire >= 0.7 then + return desire, realEnemies[1] + else + return desire-0.2, realEnemies[1] end end - - return BOT_ACTION_DESIRE_NONE, 0; + + return BOT_ACTION_DESIRE_NONE end AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) diff --git a/ability_item_usage_brewmaster.lua b/ability_item_usage_brewmaster.lua index 3d3914f5..34527d0b 100644 --- a/ability_item_usage_brewmaster.lua +++ b/ability_item_usage_brewmaster.lua @@ -103,12 +103,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius()-50 local CastPoint = ability:GetCastPoint() - local i=npcBot:FindItemSlot("item_blink") - if(i>=0 and i<=5) - then - blink=npcBot:GetItemInSlot(i) - i=nil - end + local blink = AbilityExtensions:GetAvailableBlink(npcBot) if(blink~=nil and blink:IsFullyCastable()) then CastRange=CastRange+1200 @@ -123,8 +118,7 @@ Consider[1]=function() end end - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -160,13 +154,17 @@ Consider[1]=function() -- Mode based usage -------------------------------------- --protect myself + local blademailEnemies = AbilityExtensions:Count(enemys, function(t) return t:HasModifier("modifier_item_blade_mail") end) if((npcBot:WasRecentlyDamagedByAnyHero(2) and #enemys>=1) or #enemys >=2) then - for _,npcEnemy in pairs( enemys ) - do - if ( CanCast[abilityNumber]( npcEnemy ) ) - then - return BOT_ACTION_DESIRE_HIGH,"immediately" + if blademailEnemies ~= 0 and npcBot:GetHealth() <= 300 then + -- pass + else + for _,npcEnemy in pairs( enemys ) + do + if ( CanCast[abilityNumber]( npcEnemy ) ) then + return BOT_ACTION_DESIRE_HIGH + end end end end @@ -182,7 +180,7 @@ Consider[1]=function() then if(GetUnitToUnitDistance(npcBot,WeakestEnemy)ComboMana) then - return BOT_ACTION_DESIRE_LOW,WeakestCreep + return BOT_ACTION_DESIRE_LOW end end end @@ -214,12 +212,12 @@ Consider[1]=function() then if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy) <= Radius-CastPoint* npcEnemy:GetCurrentMovementSpeed()) then - return BOT_ACTION_DESIRE_MODERATE,npcEnemy + return BOT_ACTION_DESIRE_MODERATE end end end - return BOT_ACTION_DESIRE_NONE, 0; + return BOT_ACTION_DESIRE_NONE end @@ -373,12 +371,7 @@ Consider[3]=function() local Radius = ability:GetAOERadius()-50 local CastPoint = ability:GetCastPoint() - local i=npcBot:FindItemSlot("item_blink") - if(i>=0 and i<=5) - then - blink=npcBot:GetItemInSlot(i) - i=nil - end + local blink = AbilityExtensions:GetAvailableBlink(npcBot) if(blink~=nil and blink:IsFullyCastable()) then CastRange=CastRange+1200 @@ -393,8 +386,7 @@ Consider[3]=function() end end - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -523,6 +515,16 @@ function AbilityUsageThink() -- Check if we're already using an ability if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() ) then + if npcBot:IsCastingAbility() then + if npcBot:GetCurrentActiveAbility() == AbilitiesReal[1] then + if not AbilityExtensions:IsFarmingOrPushing(npcBot) then + local nearbyEnemies = AbilityExtensions:GetNearbyEnemyUnits(npcBot, AbilitiesReal[1]:GetAOERadius() + 40) + if AbilityExtensions:Count(nearbyEnemies, CanCast[1]) then + npcBot:Action_ClearActions() + end + end + end + end return end diff --git a/ability_item_usage_bristleback.lua b/ability_item_usage_bristleback.lua index d6b16d47..4799cf2c 100644 --- a/ability_item_usage_bristleback.lua +++ b/ability_item_usage_bristleback.lua @@ -110,15 +110,14 @@ Consider[1]=function() local CastRange = ability:GetCastRange(); local Damage = 0; - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - if npcBot:HasScepter() then + if AbilityExtensions:HasScepter(npcBot) then local enemies = npcBot:GetNearbyHeroes(CastRange, true, BOT_MODE_NONE) enemies = AbilityExtensions:Filter(enemies, function(t) local m = t:GetModifierByName("modifier_bristleback_viscous_nasal_goo") @@ -127,7 +126,7 @@ Consider[1]=function() end return true end) - if AbilityExtensions:IsAttackingEnemies(npcBot) or AbilityExtensions:IsRetreating(npcBot) then + if (AbilityExtensions:IsAttackingEnemies(npcBot) or AbilityExtensions:IsRetreating(npcBot)) and npcBot:GetMana() >= 120 then if #enemies == 0 then return 0 end @@ -188,10 +187,8 @@ Consider[1]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcTarget = npcBot:GetTarget(); - - if ( npcTarget ~= nil ) - then + local npcTarget = AbilityExtensions:GetTargetIfGood(npcBot) + if npcTarget ~= nil then if ( CanCast[abilityNumber]( npcTarget ) and GetUnitToUnitDistance(npcBot,npcTarget)< CastRange) then return BOT_ACTION_DESIRE_MODERATE, npcTarget @@ -220,8 +217,7 @@ Consider[2]=function() local Radius = ability:GetAOERadius() - 50 local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_broodmother.lua b/ability_item_usage_broodmother.lua index 801e8284..43afa3e0 100644 --- a/ability_item_usage_broodmother.lua +++ b/ability_item_usage_broodmother.lua @@ -147,68 +147,6 @@ Consider[4] = function() end -Consider[3] = function() - local abilityNumber = 3 - -------------------------------------- - -- Generic Variable Setting - -------------------------------------- - local ability = AbilitiesReal[abilityNumber]; - - if not ability:IsFullyCastable() - then - return BOT_ACTION_DESIRE_NONE, 0; - end - - local CastRange = ability:GetCastRange(); - local Damage = ability:GetAbilityDamage(); - local CastPoint = ability:GetCastPoint(); - - local allys = npcBot:GetNearbyHeroes(1200, false, BOT_MODE_NONE); - local enemys = npcBot:GetNearbyHeroes(math.min(1600,CastRange + 300), true, BOT_MODE_NONE) - local WeakestEnemy, HeroHealth = utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(math.min(1600,CastRange + 300), true) - local WeakestCreep, CreepHealth = utility.GetWeakestUnit(creeps) - -------------------------------------- - -- Global high-priorty usage - -------------------------------------- - --Try to kill enemy hero - if (npcBot:GetActiveMode() ~= BOT_MODE_RETREAT) - then - if (WeakestEnemy ~= nil) - then - if (CanCast[abilityNumber](WeakestEnemy)) - then - if (HeroHealth <= WeakestEnemy:GetActualIncomingDamage(Damage, DAMAGE_TYPE_MAGICAL) or (HeroHealth <= WeakestEnemy:GetActualIncomingDamage(GetComboDamage(), DAMAGE_TYPE_MAGICAL) and npcBot:GetMana() > ComboMana)) - then - return BOT_ACTION_DESIRE_HIGH, WeakestEnemy; - end - end - end - end - - -------------------------------------- - -- Mode based usage - -------------------------------------- - -- If we're going after someone - if (npcBot:GetActiveMode() == BOT_MODE_ROAM or - npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or - npcBot:GetActiveMode() == BOT_MODE_ATTACK) - then - local npcEnemy = npcBot:GetTarget(); - - if (npcEnemy ~= nil) - then - if (CanCast[abilityNumber](npcEnemy) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot, npcEnemy) < CastRange + 75 * #allys) - then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy - end - end - end - - return BOT_ACTION_DESIRE_NONE, 0; - -end function IsLocationOverlapWeb(location, Radius) local unit = GetUnitList(UNIT_LIST_ALLIES); diff --git a/ability_item_usage_centaur.lua b/ability_item_usage_centaur.lua index f24be452..f0eb0766 100644 --- a/ability_item_usage_centaur.lua +++ b/ability_item_usage_centaur.lua @@ -99,12 +99,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius()- 50 local CastPoint = ability:GetCastPoint() - local i=npcBot:FindItemSlot("item_blink") - if(i>=0 and i<=5) - then - blink=npcBot:GetItemInSlot(i) - i=nil - end + local blink = AbilityExtensions:GetAvailableBlink(npcBot) if(blink~=nil and blink:IsFullyCastable()) then CastRange=CastRange+1200 @@ -119,8 +114,7 @@ Consider[1]=function() end end - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -134,7 +128,7 @@ Consider[1]=function() do if ( npcEnemy:IsChanneling() and CanCast[abilityNumber]( npcEnemy )) then - return BOT_ACTION_DESIRE_HIGH,npcEnemy + return BOT_ACTION_DESIRE_HIGH--,npcEnemy end end @@ -147,7 +141,7 @@ Consider[1]=function() then if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) and GetUnitToUnitDistance(npcBot,WeakestEnemy) <= Radius-CastPoint* WeakestEnemy:GetCurrentMovementSpeed()) then - return BOT_ACTION_DESIRE_HIGH,WeakestEnemy + return BOT_ACTION_DESIRE_HIGH--,WeakestEnemy end end end @@ -162,7 +156,7 @@ Consider[1]=function() do if ( CanCast[abilityNumber]( npcEnemy ) ) then - return BOT_ACTION_DESIRE_HIGH,"immediately" + return BOT_ACTION_DESIRE_HIGH--,"immediately" end end end @@ -178,7 +172,7 @@ Consider[1]=function() then if(GetUnitToUnitDistance(npcBot,WeakestEnemy)= 2 ) then - if(CreepHealth<=WeakestCreep:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana) + if CreepHealth<=WeakestCreep:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) and ManaPercentage >= 0.8 + ability:GetManaCost() and #enemys == 0 then - return BOT_ACTION_DESIRE_LOW,WeakestCreep + return BOT_ACTION_DESIRE_LOW--,WeakestCreep end end end @@ -210,12 +204,12 @@ Consider[1]=function() then if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy) <= Radius-CastPoint* npcEnemy:GetCurrentMovementSpeed()) then - return BOT_ACTION_DESIRE_MODERATE,npcEnemy + return BOT_ACTION_DESIRE_MODERATE--,npcEnemy end end end - return BOT_ACTION_DESIRE_NONE, 0; + return BOT_ACTION_DESIRE_NONE end @@ -236,12 +230,12 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - if HealthPercentage <= 0.2 + npcBot:GetActualIncomingDamage(Damage, DAMAGE_TYPE_MAGICAL) then + local selfDamage = npcBot:GetActualIncomingDamage(Damage, DAMAGE_TYPE_MAGICAL) + if HealthPercentage <= 0.2 + selfDamage then return 0 end - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -268,9 +262,9 @@ Consider[2]=function() -- If we're farming and can hit 2+ creeps and kill 1+ if ( npcBot:GetActiveMode() == BOT_MODE_FARM ) then - if ( #creeps >= 2 ) + if ( #creeps >= 3 ) then - if(CreepHealth<=WeakestCreep:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) and HealthPercentage>=0.4) + if(CreepHealth<=WeakestCreep:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) and HealthPercentage>=0.4+selfDamage) then return BOT_ACTION_DESIRE_LOW, WeakestCreep; end @@ -413,7 +407,7 @@ Consider[4]=function() then if(#allys >=2) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then if ( CanCast[abilityNumber]( npcEnemy ) and GetUnitToUnitDistance(npcBot,npcEnemy)>=600) @@ -435,6 +429,16 @@ function AbilityUsageThink() -- Check if we're already using an ability if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() ) then + if npcBot:IsCastingAbility() then + if npcBot:GetCurrentActiveAbility() == AbilitiesReal[1] then + if not AbilityExtensions:IsFarmingOrPushing(npcBot) then + local nearbyEnemies = AbilityExtensions:GetNearbyEnemyUnits(npcBot, AbilitiesReal[1]:GetAOERadius() + 40) + if AbilityExtensions:Count(nearbyEnemies, CanCast[1]) then + npcBot:Action_ClearActions() + end + end + end + end return end diff --git a/ability_item_usage_chen.lua b/ability_item_usage_chen.lua index 1812c1ac..b8685c25 100644 --- a/ability_item_usage_chen.lua +++ b/ability_item_usage_chen.lua @@ -260,7 +260,7 @@ local goodNeutral= "npc_dota_neutral_enraged_wildkin", -- 枭兽撕裂者 } -function IsGoodNeutralCreeps(npcCreep) +local function IsGoodNeutralCreeps(npcCreep) local name=npcCreep:GetUnitName(); for k,creepName in pairs(goodNeutral) do if(name==creepName) @@ -300,7 +300,7 @@ Consider[2]=function() if(ManaPercentage>=0.3) then for k,creep in pairs(creepsNeutral) do - if(IsGoodNeutralCreeps(creep) or (creep:IsAncientCreep() and npcBot:HasScepter())) + if(IsGoodNeutralCreeps(creep) or (creep:IsAncientCreep() and AbilityExtensions:HasScepter(npcBot))) then return BOT_ACTION_DESIRE_HIGH, creep; end @@ -459,66 +459,64 @@ function ConsiderRecall() return BOT_ACTION_DESIRE_NONE, 0; end +local GetAllAllyHeroes = AbilityExtensions:EveryManySeconds(2, function() + return AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, 10000, false) +end) + Consider[4]=function() - local abilityNumber=4 - -------------------------------------- - -- Generic Variable Setting - -------------------------------------- - local ability=AbilitiesReal[abilityNumber]; - - if not ability:IsFullyCastable() then - return BOT_ACTION_DESIRE_NONE, 0; + local abilityNumber=4 + -------------------------------------- + -- Generic Variable Setting + -------------------------------------- + local ability=AbilitiesReal[abilityNumber]; + + if not ability:IsFullyCastable() then + return BOT_ACTION_DESIRE_NONE, 0; + end + local healAmount = ability:GetSpecialValueInt("heal_amount") + local function IsSeverelyDamaged(npc) + return (AbilityExtensions:GetHealthPercent(npc) <= 0.3 or npc:GetHealth() <= 400) and AbilityExtensions:IsSeverelyDisabled(npc) and npc:WasRecentlyDamagedByAnyHero(0.8) + end + local function IsDamaged(npc) + return npc:GetHealth() <= 400 or AbilityExtensions:GetHealthDeficit(npc) >= healAmount * 1.3 and npc:GetUnitName() ~= "npc_dota_hero_huskar" and npc:WasRecentlyDamagedByAnyHero(1.2) + end + + local CastRange = 1599 + local allys = GetAllAllyHeroes() + if not AbilityExtensions:CalledOnThisFrame(allys) then + AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, CastRange, false) end - - local CastRange = 1000; - local Damage = 0; - local CastPoint = ability:GetCastPoint(); - - local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) + allys = AbilityExtensions:Filter(allys, function(t) return not t:IsInvulnerable() and not t:HasModifier("modifier_ice_blast") end) + local damagedAllies = AbilityExtensions:Filter(allys, function(t) return IsDamaged(t) and not IsSeverelyDamaged(t) end) + local severelyDamagedAllies = AbilityExtensions:Filter(allys, IsSeverelyDamaged) + + local enemys = npcBot:GetNearbyHeroes(CastRange,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) + local creeps = npcBot:GetNearbyCreeps(CastRange,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) then - if ( npcBot:WasRecentlyDamagedByAnyHero( 1.0 ) ) - then - return BOT_ACTION_DESIRE_HIGH; + if npcBot:WasRecentlyDamagedByAnyHero(1.0) and (not IsSeverelyDamaged(npcBot) or #damagedAllies >= 2) then + return BOT_ACTION_DESIRE_HIGH end end + + if npcBot:GetActiveMode() == BOT_MODE_LANING then + if #damagedAllies >= 2 and #severelyDamagedAllies >= 1 then + return BOT_ACTION_DESIRE_MODERATE + end + end -- If we're in a teamfight, use it on the scariest enemy local tableNearbyAttackingAlliedHeroes = npcBot:GetNearbyHeroes( 1000, false, BOT_MODE_ATTACK ); - if ( #tableNearbyAttackingAlliedHeroes >= 2 ) - then - for _,Ally in pairs(allys) do - if Ally:GetHealth()/Ally:GetMaxHealth() < 0.35 and enemys~=nil and #enemys > 0 - then - return BOT_ACTION_DESIRE_HIGH; - end - end + if #tableNearbyAttackingAlliedHeroes >= 2 and #enemys > 0 then + if AbilityExtensions:Contains(severelyDamagedAllies, npcBot) and #damagedAllies >= 3 + or #damagedAllies >= 2 and #severelyDamagedAllies >= 1 then + return BOT_ACTION_DESIRE_HIGH + end end - - local numPlayer = GetTeamPlayers(GetTeam()); - local maxDist = 0; - local target = nil; - for i = 1, #numPlayer - do - local Ally = GetTeamMember(i); - if Ally:IsAlive() and - Ally:GetActiveMode() == BOT_MODE_RETREAT and Ally:GetActiveModeDesire() >= BOT_ACTION_DESIRE_HIGH and - Ally:GetHealth() /Ally:GetMaxHealth() < 0.45 and Ally:WasRecentlyDamagedByAnyHero(2.0) - then - target = GetTeamMember(i); - break; - end - end - if target ~= nil then - return BOT_ACTION_DESIRE_MODERATE; - end - - return BOT_ACTION_DESIRE_NONE; + return 0 end AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) diff --git a/ability_item_usage_clinkz.lua b/ability_item_usage_clinkz.lua index 62e26ab7..48ee9ccd 100644 --- a/ability_item_usage_clinkz.lua +++ b/ability_item_usage_clinkz.lua @@ -186,8 +186,7 @@ Consider[2]=function() local Damage = ability:GetSpecialValueInt("damage_bonus")+npcBot:GetAttackDamage() --print(ability:GetName().." :Damage is "..Damage) - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+100,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -302,8 +301,7 @@ Consider[3]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -352,7 +350,7 @@ local goodNeutral= "npc_dota_neutral_enraged_wildkin", -- 枭兽撕裂者 } -function IsGoodNeutralCreeps(npcCreep) +local function IsGoodNeutralCreeps(npcCreep) local name=npcCreep:GetUnitName(); for k,creepName in pairs(goodNeutral) do if(name==creepName) @@ -363,8 +361,8 @@ function IsGoodNeutralCreeps(npcCreep) return false; end -Consider[5]=function() - local abilityNumber=5 +Consider[4]=function() + local abilityNumber=4 -------------------------------------- -- Generic Variable Setting -------------------------------------- @@ -378,8 +376,7 @@ Consider[5]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -422,6 +419,47 @@ Consider[5]=function() end + +Consider[5]=function() + local abilityNumber=5 + -------------------------------------- + -- Generic Variable Setting + -------------------------------------- + local ability=AbilitiesReal[abilityNumber]; + + if not ability:IsFullyCastable() then + return BOT_ACTION_DESIRE_NONE, 0; + end + + local CastRange = ability:GetCastRange(); + local Damage = 0; + local CastPoint = ability:GetCastPoint(); + + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); + local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) + local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) + local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) + local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) + local creepsNeutral = npcBot:GetNearbyNeutralCreeps(1600) + local StrongestCreep,CreepHealth2=utility.GetStrongestUnit(creepsNeutral) + -------------------------------------- + -- Mode based usage + -------------------------------------- + + -- Find neural creeps + if(ManaPercentage>=0.4) + then + for k,creep in pairs(creepsNeutral) do + if(IsGoodNeutralCreeps(creep) and not creep:WasRecentlyDamagedByAnyHero(1.5)) + then + return BOT_ACTION_DESIRE_MODERATE, creep + end + end + end + + return BOT_ACTION_DESIRE_NONE +end + AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) function AbilityUsageThink() diff --git a/ability_item_usage_crystal_maiden.lua b/ability_item_usage_crystal_maiden.lua index e721ea3e..52cff0c0 100644 --- a/ability_item_usage_crystal_maiden.lua +++ b/ability_item_usage_crystal_maiden.lua @@ -72,7 +72,9 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} +local CanCast={utility.NCanCast,function(t) + return AbilityExtensions:NormalCanCast(t, false, DAMAGE_TYPE_MAGICAL, false, true) and not AbilityExtensions:HasAbilityRetargetModifier(t) +end,utility.NCanCast,utility.UCanCast} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -99,8 +101,7 @@ Consider[1]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetSpecialValueInt( "radius" ); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -227,14 +228,13 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+150,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - local StrongestCreep,CreepHealth2=utility.GetStrongestUnit(creeps) + local StrongestCreep,CreepHealth2=utility.GetStrongestUnit(npcBot:GetNearbyNeutralCreeps(CastRange+200)) -------------------------------------- -- Global high-priorty usage -------------------------------------- @@ -325,9 +325,9 @@ Consider[2]=function() -- If we're farming and can kill 1 if ( npcBot:GetActiveMode() == BOT_MODE_FARM ) then - if(CreepHealth2>=600 and npcBot:GetMana()>ComboMana) + if(CreepHealth2>=600 and not StrongestCreep:GetUnitName() == "npc_dota_neutral_mud_golem" and not StrongestCreep:IsAncientCreep() and npcBot:GetMana()>240) and not (StrongestCreep:WasRecentlyDamagedByAnyHero(3) and not StrongestCreep:WasRecentlyDamagedByHero(npcBot, 3)) then - return BOT_ACTION_DESIRE_LOW, StrongestCreep; + return BOT_ACTION_DESIRE_MODERATE, StrongestCreep end end @@ -384,8 +384,7 @@ Consider[4]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -416,7 +415,7 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -433,31 +432,38 @@ end AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) - +local iceFreezingEnemy local freezingFieldHitSomeoneTimer + function AbilityUsageThink() -- Check if we're already using an ability if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() ) then + if npcBot:IsCastingAbility() and npcBot:GetCurrentActiveAbility() == AbilitiesReal[2] then + if iceFreezingEnemy ~= nil and AbilityExtensions:HasAbilityRetargetModifier(iceFreezingEnemy) then + npcBot:Action_ClearActions() + end + end if npcBot:IsChanneling() and npcBot:GetCurrentActiveAbility() == AbilitiesReal[4] then - --if npcBot:HasModifier("modifier_crystal_maiden_freezing_field") then - local glimmer = AbilityExtensions:GetAvailableItem(npcBot, "item_glimmer_cape") - if glimmer and glimmer:IsFullyCastable() then - npcBot:ActionImmediate_UseAbilityOnEntity(glimmer, npcBot) - end - local enemies = npcBot:GetNearbyHeroes(AbilitiesReal[4]:GetAOERadius(), true, BOT_MODE_NONE) - if #enemies > 0 or freezingFieldHitSomeoneTimer == nil then - freezingFieldHitSomeoneTimer = DotaTime() - else - if DotaTime() - freezingFieldHitSomeoneTimer >= 1.5 and #npcBot:GetNearbyHeroes(AbilitiesReal[4]:GetAOERadius() + 200, false, BOT_MODE_NONE) > 0 then - local location = npcBot:GetLocation() + RandomVector(50) - npcBot:Action_ClearActions(true) - else - end - end - else - freezingFieldHitSomeoneTimer = nil - end + if not AbilityExtensions:IsFarmingOrPushing(npcBot) then + local glimmer = AbilityExtensions:GetAvailableItem(npcBot, "item_glimmer_cape") + if glimmer and glimmer:IsFullyCastable() then + npcBot:ActionImmediate_UseAbilityOnEntity(glimmer, npcBot) + end + local enemies = npcBot:GetNearbyHeroes(AbilitiesReal[4]:GetAOERadius(), true, BOT_MODE_NONE) + if #enemies > 0 or freezingFieldHitSomeoneTimer == nil then + freezingFieldHitSomeoneTimer = DotaTime() + else + if DotaTime() - freezingFieldHitSomeoneTimer >= 1.5 and #npcBot:GetNearbyHeroes(AbilitiesReal[4]:GetAOERadius() + 200, false, BOT_MODE_NONE) > 0 then + local location = npcBot:GetLocation() + RandomVector(50) + npcBot:Action_ClearActions(true) + else + end + end + else + freezingFieldHitSomeoneTimer = nil + end + end return end @@ -472,8 +478,10 @@ function AbilityUsageThink() then ability_item_usage_generic.PrintDebugInfo(AbilitiesReal,cast) end - ability_item_usage_generic.UseAbility(AbilitiesReal,cast) - + local index, target = ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + if index == 2 then + iceFreezingEnemy = target + end end function CourierUsageThink() diff --git a/ability_item_usage_dark_seer.lua b/ability_item_usage_dark_seer.lua index 4db9f5ba..35ba2f00 100644 --- a/ability_item_usage_dark_seer.lua +++ b/ability_item_usage_dark_seer.lua @@ -169,7 +169,7 @@ Consider[1]=function() return BOT_ACTION_DESIRE_LOW+0.05, locationAoE.targetloc; end - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -300,18 +300,18 @@ Consider[2]=function() end end - if ( GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange + 75*#allys) - then - for _,myFriend in pairs(allys) do - if ( not myFriend:HasModifier("modifier_dark_seer_ion_shell") and myFriend:GetAttackRange() < 300 ) - then - return BOT_ACTION_DESIRE_MODERATE-0.05, myFriend; - end - end - if not npcBot:HasModifier("modifier_dark_seer_ion_shell") then - return BOT_ACTION_DESIRE_MODERATE-0.05, npcBot; - end - end + -- if ( GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange + 75*#allys) + -- then + -- for _,myFriend in pairs(allys) do + -- if ( not myFriend:HasModifier("modifier_dark_seer_ion_shell") and myFriend:GetAttackRange() < 300 ) + -- then + -- return BOT_ACTION_DESIRE_MODERATE-0.05, myFriend; + -- end + -- end + -- if not npcBot:HasModifier("modifier_dark_seer_ion_shell") then + -- return BOT_ACTION_DESIRE_MODERATE-0.05, npcBot; + -- end + -- end end -- If we're going after someone @@ -343,6 +343,10 @@ Consider[2]=function() end +local function ShouldSurge(t) + return (AbilityExtensions:IsRetreating(t) or AbilityExtensions:GetHealthPercent(t) <= 0.4 or t:IsHexed() or t:GetCurrentMovementSpeed() <= 150) and AbilityExtensions:CanMove(t) and t:WasRecentlyDamagedByAnyHero(3) +end + Consider[3]=function() local abilityNumber=3 -------------------------------------- @@ -358,8 +362,8 @@ Consider[3]=function() local Damage = ability:GetAbilityDamage(); local CastPoint = ability:GetCastPoint(); - local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) + local allys = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, CastRange + 200) + local enemys = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, 1400) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) @@ -368,14 +372,14 @@ Consider[3]=function() local Radius=300; local locationAoE = npcBot:FindAoELocation( false, true, npcBot:GetLocation(), CastRange, Radius, 0, 0 ); - if ( locationAoE.count >= 2 and AOESurge:IsTrained()==true ) then - return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc, "Location" + if ( locationAoE.count >= 2 and AOESurge:IsTrained()==true ) and #enemys ~= 0 then + return RemapValClamped(locationAoE.count, 2, 4, BOT_ACTION_DESIRE_LOW, BOT_ACTION_DESIRE_HIGH), locationAoE.targetloc, "Location" end -------------------------------------- -- Mode based usage -------------------------------------- -- If we're seriously retreating, see if we can land a stun on someone who's damaged us recently - if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) + if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH and ShouldSurge(npcBot) ) then if ( npcBot:WasRecentlyDamagedByAnyHero( 2.0 ) ) then @@ -390,7 +394,7 @@ Consider[3]=function() -- Help our ally local allysRetreat = npcBot:GetNearbyHeroes( CastRange+300, false, BOT_MODE_RETREAT ); for k,ally in pairs(allys) do - if(CanCast[abilityNumber]( ally ) and ally:WasRecentlyDamagedByAnyHero(2.0)) + if(CanCast[abilityNumber]( ally ) and ally:WasRecentlyDamagedByAnyHero(2.0)) and ShouldSurge(ally) then if(AOESurge:IsTrained()==true) then local locationAoE = npcBot:FindAoELocation( false, true, ally:GetLocation(), CastRange, Radius, 0, 0 ); @@ -413,10 +417,10 @@ Consider[3]=function() then if ( GetUnitToUnitDistance(npcBot,npcEnemy)< 1600) then - local ClosestDist = GetUnitToUnitDistance(npcTarget, npcBot); + local ClosestDist = GetUnitToUnitDistance(npcEnemy, npcBot); local ClosestBot = npcBot; for _,myFriend in pairs(allys) do - local dist = GetUnitToUnitDistance(npcTarget, myFriend); + local dist = GetUnitToUnitDistance(npcEnemy, myFriend); if dist < ClosestDist and dist < CastRange then ClosestDist = dist; ClosestBot = myFriend; @@ -491,7 +495,7 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then diff --git a/ability_item_usage_dazzle.lua b/ability_item_usage_dazzle.lua index f6a536de..895b9e14 100644 --- a/ability_item_usage_dazzle.lua +++ b/ability_item_usage_dazzle.lua @@ -73,7 +73,9 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} +local CanCast={function(t) + return AbilityExtensions:NormalCanCast(t, true, DAMAGE_TYPE_PHYSICAL, false, true) +end,utility.NCanCast,utility.NCanCast,utility.UCanCast} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -84,6 +86,7 @@ function GetComboMana() return ability_item_usage_generic.GetComboMana(AbilitiesReal) end + Consider[1]=function() local abilityNumber=1 -------------------------------------- @@ -98,13 +101,35 @@ Consider[1]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) + + local endDistance = ability:GetSpecialValueInt("end_distance") + local startRadius = ability:GetSpecialValueInt("start_radius") + local endRadius = ability:GetSpecialValueInt("end_radius") + + local function FindPoisonTouchAlternativeNear(target) + local radius = RemapVal(GetUnitToUnitDistance(npcBot, target), 0, endDistance, startRadius, endRadius) + local enemies = AbilityExtensions:GetNearbyEnemyUnits(target, radius) + enemies = AbilityExtensions:First(enemies, function (t) return CanCast[1](t) and t:HasModifier("modifier_antimage_counterspell") end) + return enemies + end + + local function UseAt(target) + if AbilityExtensions:HasAbilityRetargetModifier(target) then + local alternativeEnemy = FindPoisonTouchAlternativeNear(target) + if alternativeEnemy then + return alternativeEnemy + end + else + return target + end + end + -------------------------------------- -- Global high-priorty usage -------------------------------------- @@ -117,7 +142,10 @@ Consider[1]=function() then if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) or (HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana)) then - return BOT_ACTION_DESIRE_HIGH,WeakestEnemy; + local target = UseAt(WeakestEnemy) + if target ~= nil then + return BOT_ACTION_DESIRE_HIGH, target + end end end end @@ -133,7 +161,7 @@ Consider[1]=function() for _,npcEnemy in pairs( enemys ) do - if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy)) + if ( CanCast[abilityNumber]( npcEnemy )) then local Damage2 = npcEnemy:GetEstimatedDamageToTarget( false, npcBot, 3.0, DAMAGE_TYPE_ALL ); if ( Damage2 > nMostDangerousDamage ) @@ -144,9 +172,11 @@ Consider[1]=function() end end - if ( npcMostDangerousEnemy ~= nil ) - then - return BOT_ACTION_DESIRE_HIGH, npcMostDangerousEnemy; + if ( npcMostDangerousEnemy ~= nil ) then + local target = UseAt(npcMostDangerousEnemy) + if target ~= nil then + return BOT_ACTION_DESIRE_HIGH, target + end end end -------------------------------------- @@ -160,7 +190,10 @@ Consider[1]=function() do if ( CanCast[abilityNumber]( npcEnemy ) ) then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy + local target = UseAt(npcEnemy) + if target ~= nil then + return BOT_ACTION_DESIRE_HIGH, target + end end end end @@ -170,11 +203,11 @@ Consider[1]=function() then for _,npcEnemy in pairs( enemys ) do - if ( npcBot:WasRecentlyDamagedByHero( npcEnemy, 2.0 ) ) + if ( npcBot:WasRecentlyDamagedByHero( npcEnemy, 2.0 ) ) then - if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy)) - then - return BOT_ACTION_DESIRE_HIGH, npcEnemy; + local target = UseAt(npcEnemy) + if target ~= nil then + return BOT_ACTION_DESIRE_HIGH, target end end end @@ -189,7 +222,10 @@ Consider[1]=function() then if ( CanCast[abilityNumber]( WeakestEnemy ) ) then - return BOT_ACTION_DESIRE_LOW,WeakestEnemy; + local target = UseAt(WeakestEnemy) + if target ~= nil then + return BOT_ACTION_DESIRE_HIGH, target + end end end end @@ -207,7 +243,10 @@ Consider[1]=function() then if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange + 75*#allys) then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy + local target = UseAt(npcEnemy) + if target ~= nil then + return BOT_ACTION_DESIRE_MODERATE, target + end end end end @@ -230,9 +269,17 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local allys = npcBot:GetNearbyHeroes( CastRange+300, false, BOT_MODE_NONE ); + local allys = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, CastRange+300, false) local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) + local enemyAxe = AbilityExtensions:First(enemys, function(t) + return AbilityExtensions:MayNotBeIllusion(t) and t:GetUnitName() == "npc_dota_hero_axe" + end) + local canEnemyAxeUseCullingBlade = false + if enemyAxe then + canEnemyAxeUseCullingBlade = AbilityExtensions:GetSilenceRemainingDuration(enemyAxe) <= 3 and enemyAxe:GetMana() >= Clamp(enemyAxe:GetLevel()/6, 0, 3) * 60 + end + local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) @@ -242,7 +289,7 @@ Consider[2]=function() -- If we're seriously retreating if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) then - if(HealthPercentage<=0.3) + if(HealthPercentage<=0.3) and not (enemyAxe and canEnemyAxeUseCullingBlade and GetUnitToUnitDistance(npcBot, enemyAxe) <= 350) then return BOT_ACTION_DESIRE_HIGH+0.15, npcBot end @@ -259,7 +306,7 @@ Consider[2]=function() do Damage2 =Damage2 + npcEnemy:GetEstimatedDamageToTarget( true, npcBot, 2.0, DAMAGE_TYPE_ALL ); end - if not npcTarget:IsIllusion() and (npcTarget:GetHealth()= BOT_MODE_DESIRE_HIGH ) + if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH and not npcBot:HasModifier("modifier_ice_blast") ) then if ( npcBot:WasRecentlyDamagedByAnyHero(2) ) then @@ -377,6 +423,7 @@ Consider[3]=function() -- Mode based usage -------------------------------------- --protect teammate + allys = AbilityExtensions:Filter(allys, function(t) return not t:HasModifier("modifier_ice_blast") end) for _,npcTarget in pairs (allys) do local enemys2=npcTarget:GetNearbyHeroes(600,true,BOT_MODE_NONE) diff --git a/ability_item_usage_death_prophet.lua b/ability_item_usage_death_prophet.lua index fe090600..f222004c 100644 --- a/ability_item_usage_death_prophet.lua +++ b/ability_item_usage_death_prophet.lua @@ -100,8 +100,7 @@ Consider[1]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+0,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -198,7 +197,7 @@ Consider[1]=function() end Consider[2]=function() -local abilityNumber=2 + local abilityNumber=2 -------------------------------------- -- Generic Variable Setting -------------------------------------- @@ -213,8 +212,7 @@ local abilityNumber=2 local Radius = ability:GetAOERadius() local CastPoint=ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) enemys = AbilityExtensions:Filter(enemys, function(t) return not t:IsStunned() and not t:IsSilenced() and not t:IsInvulnerable() and not t:IsMagicImmune() end) @@ -277,7 +275,7 @@ local abilityNumber=2 return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc end - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -409,8 +407,7 @@ Consider[4]=function() local Damage = 0--ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -457,7 +454,7 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -472,8 +469,6 @@ Consider[4]=function() end AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) -local lastAbilityIndex -local lastAbilityTarget function AbilityUsageThink() @@ -482,8 +477,6 @@ function AbilityUsageThink() then return end - lastAbilityIndex = nil - lastAbilityTarget = nil ComboMana=GetComboMana() AttackRange=npcBot:GetAttackRange() @@ -496,7 +489,7 @@ function AbilityUsageThink() then ability_item_usage_generic.PrintDebugInfo(AbilitiesReal,cast) end - lastAbilityIndex, lastAbilityTarget = ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + ability_item_usage_generic.UseAbility(AbilitiesReal,cast) end function CourierUsageThink() diff --git a/ability_item_usage_disruptor.lua b/ability_item_usage_disruptor.lua index ff9ebecb..4db17a37 100644 --- a/ability_item_usage_disruptor.lua +++ b/ability_item_usage_disruptor.lua @@ -469,6 +469,14 @@ Consider[4]=function() -------------------------------------- -- Global high-priorty usage -------------------------------------- + local channelingEnemies = AbilityExtensions:Filter(enemys, function(t) + return CanCast[4](t) and AbilityExtensions:IsChannelingAbility(t) and AbilityExtensions:IsChannelingBreakWorthAbility(t) + end) + channelingEnemies = AbilityExtensions:Max(channelingEnemies, function(t) return t:GetCurrentActiveAbility():GetCooldown() end) + if channelingEnemies ~= nil and channelingEnemies[1]:GetCurrentActiveAbility():GetCooldown() >= ability:GetCooldown() * 0.7 then + return BOT_ACTION_DESIRE_MODERATE, AbilityExtensions:FindAOELocationAtSingleTarget(npcBot, channelingEnemies, Radius, CastRange, CastPoint) + end + --try to kill enemy hero if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) then @@ -536,11 +544,11 @@ Consider[4]=function() return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc; end - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then - if ( CanCast[abilityNumber]( npcEnemy ) ) + if CanCast[abilityNumber]( npcEnemy ) and AbilityExtensions:IsNonIllusionHero(npcEnemy) then return BOT_ACTION_DESIRE_HIGH, npcEnemy:GetExtrapolatedLocation(CastPoint); end diff --git a/ability_item_usage_doom_bringer.lua b/ability_item_usage_doom_bringer.lua index 94d23824..ab161589 100644 --- a/ability_item_usage_doom_bringer.lua +++ b/ability_item_usage_doom_bringer.lua @@ -72,12 +72,7 @@ function CanCast1( npcEnemy ) then return false end - if(npcBot:HasScepter()) - then - return npcEnemy:CanBeSeen() and not npcEnemy:IsInvulnerable(); - else - return npcEnemy:CanBeSeen() and not npcEnemy:IsInvulnerable() and not npcEnemy:IsAncientCreep() - end + return npcEnemy:CanBeSeen() and not npcEnemy:IsInvulnerable() end -------------------------------------- @@ -148,8 +143,7 @@ Consider[2]=function() local Damage = ability:GetDuration()*ability:GetSpecialValueInt("damage_per_second") local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -215,8 +209,7 @@ Consider[3]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+150,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -297,8 +290,7 @@ Consider[6]=function() local Damage = ability:GetDuration()*ability:GetSpecialValueInt("damage_per_second") local CastRange = ability:GetCastRange(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -382,10 +374,9 @@ Consider[6]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) - if ( npcEnemy ~= nil ) - then + if npcEnemy ~= nil then if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange + 75*#allys) then return BOT_ACTION_DESIRE_MODERATE, npcEnemy @@ -396,9 +387,6 @@ Consider[6]=function() return BOT_ACTION_DESIRE_NONE, 0; end --- - - AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) function AbilityUsageThink() diff --git a/ability_item_usage_dragon_knight.lua b/ability_item_usage_dragon_knight.lua index 396dbf17..36978e70 100644 --- a/ability_item_usage_dragon_knight.lua +++ b/ability_item_usage_dragon_knight.lua @@ -100,8 +100,7 @@ Consider[1]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+0,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -215,8 +214,7 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -299,7 +297,7 @@ Consider[2]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcTarget = npcBot:GetTarget(); + local npcTarget = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcTarget ~= nil ) then @@ -455,8 +453,7 @@ Consider[5]=function() local CastRange = 600 local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -483,10 +480,26 @@ Consider[5]=function() -------------------------------------- -- Mode based usage -------------------------------------- - -- If we're in a teamfight, use it on the scariest enemy local tableNearbyAttackingAlliedHeroes = npcBot:GetNearbyHeroes( 1000, false, BOT_MODE_ATTACK ); if ( #tableNearbyAttackingAlliedHeroes >= 2 ) then + + local npcMostDangerousEnemy = nil; + local nMostDangerousDamage = 0; + + for _,npcEnemy in pairs( enemys ) + do + if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy)) + then + local Damage2 = npcEnemy:GetEstimatedDamageToTarget( false, npcBot, 3.0, DAMAGE_TYPE_ALL ); + if ( Damage2 > nMostDangerousDamage ) + then + nMostDangerousDamage = Damage2; + npcMostDangerousEnemy = npcEnemy; + end + end + end + if ( npcMostDangerousEnemy ~= nil ) then return BOT_ACTION_DESIRE_HIGH diff --git a/ability_item_usage_drow_ranger.lua b/ability_item_usage_drow_ranger.lua index 1c971930..7772f4e1 100644 --- a/ability_item_usage_drow_ranger.lua +++ b/ability_item_usage_drow_ranger.lua @@ -74,7 +74,7 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.CanCastNoTarget,utility.UCanCast} +local CanCast={AbilityExtensions.PhysicalCanCastFunction,utility.NCanCast,AbilityExtensions.PhysicalCanCastFunction,utility.UCanCast} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -85,118 +85,6 @@ function GetComboMana() return ability_item_usage_generic.GetComboMana(AbilitiesReal) end -Consider[1]=function() - local abilityNumber=1 - -------------------------------------- - -- Generic Variable Setting - -------------------------------------- - local ability=AbilitiesReal[abilityNumber]; - - if not ability:IsFullyCastable() then - return BOT_ACTION_DESIRE_NONE, 0; - end - - local CastRange = ability:GetCastRange(); - local Damage = 0 - - local HeroHealth=10000 - local CreepHealth=10000 - local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(CastRange+100,true,BOT_MODE_NONE) - local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(CastRange+100,true) - local creeps2 = npcBot:GetNearbyCreeps(300,true) - local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - - if(ability:GetToggleState()==false) - then - local t=npcBot:GetAttackTarget() - if(t~=nil) - then - if (t:IsHero()) - then - ability:ToggleAutoCast() - return BOT_ACTION_DESIRE_NONE, 0; - end - end - end - --[[else - local t=npcBot:GetAttackTarget() - if(t~=nil) - then - if (not t:IsHero()) - then - ability:ToggleAutoCast() - return BOT_ACTION_DESIRE_NONE, 0; - end - end - end]] - - --try to kill enemy hero - if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT) - then - if (WeakestEnemy~=nil) - then - if ( CanCast[abilityNumber]( WeakestEnemy ) ) - then - if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_ALL)) - then - return BOT_ACTION_DESIRE_HIGH,WeakestEnemy; - end - end - end - end - -------------------------------------- - -- Mode based usage - -------------------------------------- - if ( npcBot:GetActiveMode() == BOT_MODE_LANING ) - then - if AbilityExtensions:HasEnoughManaToUseAttackAttachedAbility(npcBot, AbilitiesReal[abilityNumber]) and #creeps2<=1 - then - if (WeakestEnemy~=nil) - then - if ( CanCast[abilityNumber]( WeakestEnemy ) ) - then - return BOT_ACTION_DESIRE_LOW-0.01,WeakestEnemy - end - end - end - end - - -- If we're farming - if ( npcBot:GetActiveMode() == BOT_MODE_FARM and AbilityExtensions:HasEnoughManaToUseAttackAttachedAbility(npcBot, AbilitiesReal[abilityNumber]) ) - then - if(WeakestCreep~=nil) - then - if(WeakestCreep:HasModifier("modifier_drow_ranger_frost_arrows_slow")==false) - then - return BOT_ACTION_DESIRE_LOW, WeakestCreep; - end - end - end - - -- If we're going after someone - if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or - npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or - npcBot:GetActiveMode() == BOT_MODE_ATTACK ) - then - local npcEnemy = npcBot:GetTarget(); - - if ( npcEnemy ~= nil ) - then - if ( CanCast[abilityNumber]( npcEnemy ) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange+100) - then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy; - end - end - end - - return BOT_ACTION_DESIRE_NONE, 0; - -end - --- copied and modified from enchantress_impetus Consider[1] = function() local abilityNumber=1 -------------------------------------- @@ -269,8 +157,7 @@ Consider[2]=function() local Radius = ability:GetAOERadius() local CastPoint=ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -295,8 +182,7 @@ Consider[2]=function() -- Check for a channeling enemy for _,npcEnemy in pairs( enemys ) do - if ( npcEnemy:IsChanneling() and CanCast[abilityNumber]( npcEnemy ) and not npcEnemy:HasModifier("modifier_teleporting") and not npcEnemy:HasModifier("modifier_boots_of_travel_incoming")) - then + if AbilityExtensions:IsChannelingAbility(npcEnemy) and CanCast[abilityNumber](npcEnemy) then return BOT_ACTION_DESIRE_HIGH, npcEnemy:GetLocation(),"Location" end end @@ -363,8 +249,7 @@ Consider[3]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -382,7 +267,7 @@ Consider[3]=function() then if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) or (HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana)) then - return BOT_ACTION_DESIRE_HIGH,WeakestEnemy,"Target"; + return BOT_ACTION_DESIRE_HIGH,WeakestEnemy:GetLocation(),"Location" end end end @@ -400,8 +285,8 @@ Consider[3]=function() then if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy)) then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy,"Target"; - end + return BOT_ACTION_DESIRE_MODERATE, npcEnemy:GetLocation(),"Location" + end end end end @@ -447,8 +332,8 @@ Consider[3]=function() then if ( CanCast[abilityNumber]( WeakestEnemy ) ) then - return BOT_ACTION_DESIRE_LOW,WeakestEnemy,"Target"; - end + return BOT_ACTION_DESIRE_LOW,WeakestEnemy:GetLocation(),"Location" + end end end end @@ -471,8 +356,8 @@ Consider[3]=function() then if ( not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange + 75*#allys) then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy,"Target" - end + return BOT_ACTION_DESIRE_MODERATE, npcEnemy:GetLocation(),"Location" + end end end diff --git a/ability_item_usage_earth_spirit.lua b/ability_item_usage_earth_spirit.lua index 1821e1fc..28ad151d 100644 --- a/ability_item_usage_earth_spirit.lua +++ b/ability_item_usage_earth_spirit.lua @@ -18,8 +18,6 @@ local AbilitiesReal ={} ability_item_usage_generic.InitAbility(Abilities,AbilitiesReal,Talents) - - local AbilityToLevelUp= { Abilities[2], @@ -146,7 +144,7 @@ Consider[1]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotMove(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end @@ -345,7 +343,7 @@ Consider[2]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotMove(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end @@ -375,7 +373,7 @@ Consider[2]=function() if utility.IsStuck(npcBot) then local loc = utility.GetEscapeLoc(); - return BOT_ACTION_DESIRE_HIGH, npcBot:GetLocation(),"Location"; + return BOT_ACTION_DESIRE_HIGH, npcBot:GetLocation(), false end --Try to kill enemy hero @@ -520,6 +518,7 @@ Consider[3]=function() then if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy)) then + local stoneNearby = IsStoneNearby(npcBot:GetLocation(), nSearchRad); if stoneNearby then return BOT_ACTION_DESIRE_HIGH, npcEnemy:GetLocation(), false, true; elseif nStone >= 1 then @@ -538,6 +537,7 @@ Consider[3]=function() then local locationAoE = npcBot:FindAoELocation( true, true, npcBot:GetLocation(), nCastRange, nRadius, nCastPoint, 0 ); if ( locationAoE.count >= 2 ) + then local stoneNearby = IsStoneNearby(locationAoE.targetloc, nSearchRad); if stoneNearby and ( nStone >= 1 or nStone < 1 ) then @@ -665,7 +665,7 @@ Consider[6]=function() return BOT_ACTION_DESIRE_HIGH; end - local npcTarget = npcBot:GetTarget(); + local npcTarget = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcTarget ~= nil ) then if ( CanCast[abilityNumber]( npcTarget ) and not enemyDisabled(npcTarget) and GetUnitToUnitDistance(npcBot,npcTarget)< CastRange + 75*#allys) and GetUnitToUnitDistance(npcBot,npcTarget)< nRadius-100 @@ -723,7 +723,7 @@ function AbilityUsageThink() if ( cast.Desire[1] > 0 ) then - if castQStone then + if castQStone and AbilitiesReal[4]:IsFullyCastable() then npcBot:Action_ClearActions(false); npcBot:ActionQueue_UseAbilityOnLocation(AbilitiesReal[4], npcBot:GetLocation()); npcBot:ActionQueue_UseAbilityOnLocation(AbilitiesReal[1], castQLoc); @@ -741,7 +741,7 @@ function AbilityUsageThink() if ( cast.Desire[2] > 0 ) then - if castWStone then + if castWStone and AbilitiesReal[4]:IsFullyCastable() and not npcBot:IsChanneling() and not npcBot:IsSilenced() then npcBot:Action_ClearActions(false); npcBot:ActionQueue_UseAbilityOnLocation(AbilitiesReal[2], castWLoc); npcBot:ActionQueue_UseAbilityOnLocation(AbilitiesReal[4], npcBot:GetXUnitsTowardsLocation(castWLoc, 300)); @@ -754,7 +754,7 @@ function AbilityUsageThink() if ( cast.Desire[3] > 0 ) then - if castEStone then + if castEStone and AbilitiesReal[4]:IsFullyCastable() and not npcBot:IsChanneling() and not npcBot:IsSilenced() then npcBot:Action_ClearActions(false); npcBot:ActionQueue_UseAbilityOnLocation(AbilitiesReal[4], castELoc); npcBot:ActionQueue_UseAbilityOnLocation(AbilitiesReal[3], castELoc); @@ -765,10 +765,9 @@ function AbilityUsageThink() end end - if ( cast.Desire[4] > 0 ) + if cast.Desire[4] > 0 and AbilitiesReal[4]:IsFullyCastable() and not npcBot:IsChanneling() and not npcBot:IsSilenced() then npcBot:Action_UseAbilityOnLocation( AbilitiesReal[4], castDLoc ); - npcBot:ActionImmediate_Chat( "RESET BOYS", true ); stoneCast = DotaTime(); return; end diff --git a/ability_item_usage_earthshaker.lua b/ability_item_usage_earthshaker.lua index 6f14c3a7..62ecf2d7 100644 --- a/ability_item_usage_earthshaker.lua +++ b/ability_item_usage_earthshaker.lua @@ -101,8 +101,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius() local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -115,7 +114,7 @@ Consider[1]=function() -- Check for a channeling enemy for _,npcEnemy in pairs( enemys ) do - if ( npcEnemy:IsChanneling() ) + if ( npcEnemy:IsChanneling() and CanCast[1](npcEnemy) ) then return BOT_ACTION_DESIRE_HIGH, npcEnemy:GetLocation(); end @@ -214,7 +213,7 @@ Consider[1]=function() local npcTarget = npcBot:GetTarget(); if ( npcTarget ~= nil ) then - if ( CanCast[abilityNumber]( npcTarget ) and not enemyDisabled(npcTarget) and GetUnitToUnitDistance(npcBot,npcEnemy)<=CastRange) + if ( CanCast[abilityNumber]( npcTarget ) and not enemyDisabled(npcTarget) and GetUnitToUnitDistance(npcBot,npcTarget)<=CastRange) then return BOT_ACTION_DESIRE_MODERATE, npcTarget:GetExtrapolatedLocation(CastPoint); end @@ -240,8 +239,7 @@ Consider[2]=function() local Radius = AbilitiesReal[3]:GetAOERadius()-80 local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -250,7 +248,7 @@ Consider[2]=function() -------------------------------------- -- Mode based usage -------------------------------------- - if(npcBot:HasScepter() or npcBot:HasModifier("modifier_item_ultimate_scepter")) + if AbilityExtensions:HasScepter(npcBot) then -- If we're seriously retreating, see if we can land a stun on someone who's damaged us recently if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) @@ -387,8 +385,7 @@ Consider[4]=function() local Radius = ability:GetSpecialValueInt("echo_slam_echo_range")-150 local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -409,13 +406,7 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local i=npcBot:FindItemSlot("item_blink") - if(i>=0 and i<=5) - then - blink=npcBot:GetItemInSlot(i) - i=nil - end - + local blink = AbilityExtensions:GetAvailableBlink(npcBot) if(blink~=nil and blink:IsFullyCastable()) then local CastRange=1200 @@ -467,7 +458,7 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil and #enemys>=2) then diff --git a/ability_item_usage_elder_titan.lua b/ability_item_usage_elder_titan.lua index dd6efa15..dc2ce525 100644 --- a/ability_item_usage_elder_titan.lua +++ b/ability_item_usage_elder_titan.lua @@ -104,8 +104,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius()-50 local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -349,15 +348,6 @@ Consider[4]=function() -------------------------------------- -- Global high-priorty usage -------------------------------------- - -- Check for a channeling enemy - for _,npcEnemy in pairs( enemys ) - do - if ( npcEnemy:IsChanneling() ) - then - return BOT_ACTION_DESIRE_HIGH, npcEnemy:GetLocation(); - end - end - --try to kill enemy hero if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) then diff --git a/ability_item_usage_ember_spirit.lua b/ability_item_usage_ember_spirit.lua index a5e8144d..ff302dde 100644 --- a/ability_item_usage_ember_spirit.lua +++ b/ability_item_usage_ember_spirit.lua @@ -2,41 +2,38 @@ -- Ranked Matchmaking AI v1.3 New Structure -- Author: adamqqq Email:adamqqq@163.com ---------------------------------------------------------------------------- --------------------------------------- --- General Initialization --------------------------------------- -local utility = require( GetScriptDirectory().."/utility" ) +-- v1.7 template by AaronSong321 +local utility = require(GetScriptDirectory().."/utility") require(GetScriptDirectory() .. "/ability_item_usage_generic") local AbilityExtensions = require(GetScriptDirectory().."/util/AbilityAbstraction") -local debugmode=false local npcBot = GetBot() -local Talents ={} -local Abilities ={} -local AbilitiesReal ={} - -ability_item_usage_generic.InitAbility(Abilities,AbilitiesReal,Talents) +if npcBot:IsIllusion() then + return +end +local AbilityNames, Abilities, Talents = AbilityExtensions:InitAbility(npcBot) +--local CanCast = {utility.NCanCast,utility.UCanCast,utility.NCanCast,utility.UCanCast,utility.UCanCast} -local AbilityToLevelUp= +local AbilityToLevelUp = { - Abilities[3], - Abilities[1], - Abilities[3], - Abilities[1], - Abilities[3], - Abilities[4], - Abilities[3], - Abilities[1], - Abilities[1], + AbilityNames[2], + AbilityNames[3], + AbilityNames[3], + AbilityNames[1], + AbilityNames[3], + AbilityNames[5], + AbilityNames[3], + AbilityNames[2], + AbilityNames[2], "talent", - Abilities[2], - Abilities[4], - Abilities[2], - Abilities[2], + AbilityNames[2], + AbilityNames[1], + AbilityNames[1], + AbilityNames[1], "talent", - Abilities[2], + AbilityNames[5], "nil", - Abilities[4], + AbilityNames[5], "nil", "talent", "nil", @@ -45,7 +42,7 @@ local AbilityToLevelUp= "nil", "talent", } -local TalentTree={ +local TalentTree = { function() return Talents[1] end, @@ -59,670 +56,473 @@ local TalentTree={ return Talents[8] end } - --- check skill build vs current level utility.CheckAbilityBuild(AbilityToLevelUp) function AbilityLevelUpThink() - ability_item_usage_generic.AbilityLevelUpThink2(AbilityToLevelUp,TalentTree) + ability_item_usage_generic.AbilityLevelUpThink2(AbilityToLevelUp, TalentTree) end --------------------------------------- --- Ability Usage Thinking --------------------------------------- -local cast={} cast.Desire={} cast.Target={} cast.Type={} -local Consider ={} +local cast= {} cast.Desire= {} cast.Target= {} cast.Type= {} +local Consider = {} -local enemyDisabled=utility.enemyDisabled -function GetComboDamage() - return ability_item_usage_generic.GetComboDamage(AbilitiesReal) -end +local attackRange +local healthPercent +local mana +local manaPercent -function GetComboMana() - return ability_item_usage_generic.GetComboMana(AbilitiesReal) +local function IsUsingSleightOfFist() + return npcBot:HasModifier("modifier_ember_spirit_sleight_of_fist_in_progress") end - -function CanCast2( npcEnemy ) - return npcEnemy:CanBeSeen() and not npcEnemy:IsInvulnerable(); +local function IsUsingRemnant() + return npcBot:HasModifier("modifier_ember_spirit_fire_remnant") +end +local fistCastLocation + +Consider[1] = function() + local ability = Abilities[1] + if not ability:IsFullyCastable() then + return 0 + end + local abilityLevel = ability:GetLevel() + local castRange = ability:GetCastRange() + local castPoint = ability:GetCastPoint() + local manaCost = ability:GetManaCost() + local duration = ability:GetDuration() + local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, castRange) + local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) + local targettableEnemies = AbilityExtensions:Filter(realEnemies, function(t) return AbilityExtensions:NormalCanCast(t, true) end) + local friends = AbilityExtensions:GetNearbyHeroes(npcBot, 1200, true) + local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) + local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, castRange) + local friendCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, npcBot:GetAttackRange()+150, false) + local neutralCreeps = npcBot:GetNearbyNeutralCreeps(castRange) + local damage = ability:GetSpecialValueInt("total_damage") + local weakestEnemy, enemyHealth = utility.GetWeakestUnit(targettableEnemies) + local weakCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) return t:GetHealth() < t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) end) + local weakestCreep = utility.GetWeakestUnit(weakCreeps) + local forbiddenCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) + return t:GetHealth() > t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) and t:GetHealth() <= t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) + AbilityExtensions:AttackOnceDamage(npcBot, t) * (0.9+#enemyCreeps*0.1) + end) + if #friendCreeps == 0 then + forbiddenCreeps = {} + end + + local unitCount = ability:GetSpecialValueInt("unit_count") + local allNearbyTargettableEnemies = AbilityExtensions:Concat(targettableEnemies, enemyCreeps, neutralCreeps) + allNearbyTargettableEnemies = AbilityExtensions:Count(enemies, function(t) return not t:IsInvulnerable() and not t:IsMagicImmune() end) + local fistBonus = 1 + if IsUsingSleightOfFist() and fistCastLocation ~= nil and GetUnitToLocationDistance(npcBot, fistCastLocation) >= Abilities[2]:GetCastRange()-200 then + fistBonus = 2 + end + local goodTargets = AbilityExtensions:Count(targettableEnemies, function(t) return t:IsChanneling() end) * fistBonus + goodTargets = goodTargets + AbilityExtensions:GetEnemyHeroNumber(npcBot, targettableEnemies) * 0.3 * fistBonus + goodTargets = goodTargets + AbilityExtensions:Count(targettableEnemies, function(t) return AbilityExtensions:GetHealthPercent(t) <= duration/5+0.1*friendCount end) + if allNearbyTargettableEnemies ~= 1 then + goodTargets = goodTargets * unitCount / allNearbyTargettableEnemies + end + + if AbilityExtensions:IsLaning(npcBot) then + if manaPercent >= 0.5 + manaCost and goodTargets >= manaPercent or goodTargets >= 0.8 then + return BOT_ACTION_DESIRE_HIGH + end + elseif AbilityExtensions:IsAttackingEnemies(npcBot) then + if friendCount >= 2 and #enemies <= 2 then + return BOT_ACTION_DESIRE_HIGH + end + if manaPercent >= 0.2 + manaCost and goodTargets >= 1 then + return BOT_ACTION_DESIRE_MODERATE + end + elseif AbilityExtensions:IsFarmingOrPushing(npcBot) then + if manaPercent >= 0.8 + manaCost and allNearbyTargettableEnemies >= 2 then + return BOT_ACTION_DESIRE_MODERATE + end + elseif AbilityExtensions:IsRetreating(npcBot) then + if allNearbyTargettableEnemies <= 3 and #targettableEnemies >= 1 then + return BOT_ACTION_DESIRE_HIGH + end + end + return 0 end -local CanCast={utility.NCanCast,CanCast2,utility.NCanCast,utility.UCanCast,utility.UCanCast} - -AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) -function AbilityUsageThink() +Consider[2] = function() + local ability = Abilities[2] + if not ability:IsFullyCastable() or IsUsingRemnant() or IsUsingSleightOfFist() or AbilityExtensions:CannotMove(npcBot) or ability:GetCurrentCharges() == 0 then + return 0 + end + local abilityLevel = ability:GetLevel() + local castRange = ability:GetCastRange() + 100 + local radius = ability:GetAOERadius() + local castPoint = ability:GetCastPoint() + local manaCost = ability:GetManaCost() + local duration = ability:GetDuration() + local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, castRange + radius) + local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) + local targettableEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:NormalCanCast(t, true, DAMAGE_TYPE_PHYSICAL, true) and not AbilityExtensions:CannotBeAttacked(t) end) + local friends = AbilityExtensions:GetNearbyHeroes(npcBot, 1200, true) + local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) + local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, castRange + radius) + local friendCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, npcBot:GetAttackRange()+150, false) + local neutralCreeps = npcBot:GetNearbyNeutralCreeps(castRange) + local weakestEnemy, enemyHealth = utility.GetWeakestUnit(targettableEnemies) + local creepDamage = npcBot:GetAttackDamage() * (1 + ability:GetSpecialValueInt("creep_damage_penalty") / 100) + local weakCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) return t:GetHealth() < t:GetActualIncomingDamage(creepDamage, DAMAGE_TYPE_MAGICAL) end) + local weakestCreep = utility.GetWeakestUnit(weakCreeps) + local forbiddenCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) + return t:GetHealth() > t:GetActualIncomingDamage(creepDamage, DAMAGE_TYPE_MAGICAL) and t:GetHealth() <= t:GetActualIncomingDamage(creepDamage, DAMAGE_TYPE_MAGICAL) + AbilityExtensions:AttackOnceDamage(npcBot, t) * (0.9+#enemyCreeps*0.1) + end) + if #friendCreeps == 0 then + forbiddenCreeps = {} + end + local damage = npcBot:GetAttackDamage() + ability:GetSpecialValueInt("bonus_hero_damage") + if AbilityExtensions:GetAvailableItem(npcBot, "item_lesser_crit") then + damage = damage * 1.7 + elseif AbilityExtensions:GetAvailableItem(npcBot, "item_greater_crit") then + damage = damage * 2.3 + end + local hasBattleFury = AbilityExtensions:GetAvailableItem(npcBot, "item_bfury") ~= nil + + local projectiles = AbilityExtensions:GetIncomingDodgeWorthProjectiles(npcBot) or {} + projectiles = AbilityExtensions:Any(projectiles, function(t) return GetUnitToLocationDistance(npcBot, t.location) <= 200 end) + if projectiles then + local locationAoE = npcBot:FindAoELocation(true, false, npcBot:GetLocation(), castRange+60, radius, 0, 0) + if locationAoE.count >= 2 then + return BOT_ACTION_DESIRE_HIGH, locationAoE.targetloc + end + end + if AbilityExtensions:IsFarmingOrPushing(npcBot) then + local locationAoE = npcBot:FindAoELocation(true, false, npcBot:GetLocation(), castRange+150, radius, 0, 0) + if hasBattleFury and (locationAoE.count >= 4 and manaPercent >= 0.3 + manaCost or locationAoE.count >= 3 and manaPercent >= 0.6 + manaCost) then + return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc + end + elseif AbilityExtensions:IsLaning(npcBot) then + if manaPercent >= 0.6 + manaCost and #enemies == 1 and enemies[1]:CanBeSeen() and healthPercent >= 0.8 and abilityLevel >= 3 then + return BOT_ACTION_DESIRE_HIGH, AbilityExtensions:FindAOELocationAtSingleTarget(npcBot, enemies[1], radius, castRange, castPoint) + end + if manaPercent >= 0.3 and #enemies == 1 and enemies[1]:CanBeSeen() and healthPercent >= 0.75 and abilityLevel >= 4 then + return BOT_ACTION_DESIRE_HIGH, AbilityExtensions:FindAOELocationAtSingleTarget(npcBot, enemies[1], radius, castRange, castPoint) + end + end + if AbilityExtensions:NotRetreating(npcBot) then + local findPlace = npcBot:FindAoELocation(true, true, npcBot:GetLocation(), castRange+100, radius, 0, 0) + if findPlace.count >= 3 then + if GetUnitToLocationDistance(npcBot, findPlace.targetloc) <= castRange then + return BOT_ACTION_DESIRE_VERYHIGH, findPlace.targetloc + else + return BOT_ACTION_DESIRE_MODERATE + 0.05, findPlace.targetloc + end + elseif findPlace.count >= 2 then + return BOT_ACTION_DESIRE_MODERATE, findPlace.targetloc + end + + if weakestEnemy ~= nil and enemyHealth ~= -1 then + local damageTaken = weakestEnemy:GetActualIncomingDamage(damage, DAMAGE_TYPE_PHYSICAL) + if enemyHealth <= damageTaken or enemyHealth <= damageTaken * 1.5 and mana > 200 + manaCost then + local targetLocation = AbilityExtensions:FindAOELocationAtSingleTarget(npcBot, weakestEnemy, radius, castRange, castPoint) + return BOT_ACTION_DESIRE_HIGH, targetLocation + end + end + + local target = npcBot:GetTarget() + if target ~= nil and target:CanBeSeen() and AbilityExtensions:NormalCanCast(target, true, DAMAGE_TYPE_PHYSICAL) and not AbilityExtensions:CannotBeAttacked(target) + and (mana >= 200 and target:GetHealth() < target:GetActualIncomingDamage(damage, DAMAGE_TYPE_PHYSICAL) * (0.9 + friendCount*0.1)) then + return BOT_ACTION_DESIRE_HIGH, AbilityExtensions:FindAOELocationAtSingleTarget(npcBot, target, radius, castRange, castPoint) + end + end + return 0 +end - -- Check if we're already using an ability - if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() ) - then - return - end - - GetComboMana() - AttackRange=npcBot:GetAttackRange() - ManaPercentage=npcBot:GetMana()/npcBot:GetMaxMana() - - -- Consider using each ability - castDesire[1]=Consider1(); - castType[1]="no" - castDesire[2], castLocation[2] = Consider2(); - castDesire[3] = Consider3(); - castDesire[4], castLocation[4] = Consider4(); - castDesire[5], castLocation[5] = Consider5(); - ---------------------------------debug-------------------------------------------- - if(debugmode==true) then - if(npcBot.LastSpeaktime==nil) - then - npcBot.LastSpeaktime=0 - end - if(GameTime()-npcBot.LastSpeaktime>1) - then - for i=1,5,1 - do - if ( castDesire[i] > 0 ) - then - if (castType[i]==nil or castType[i]=="target" )and castTarget[i]~=nil - then - npcBot:ActionImmediate_Chat("try to use skill "..i.." at "..castTarget[i]:GetUnitName().." Desire= "..castDesire[i],true) - else - npcBot:ActionImmediate_Chat("try to use skill "..i.." Desire= "..castDesire[i],true) - end - npcBot.LastSpeaktime=GameTime() - end +Consider[3] = function() + local ability = Abilities[3] + if not ability:IsFullyCastable() or npcBot:HasModifier("modifier_ember_spirit_flame_guard") or npcBot:HasModifier("modifier_shadow_demon_purge_slow") then + return 0 + end + local abilityLevel = ability:GetLevel() + local castRange = ability:GetCastRange() + local radius = ability:GetAOERadius() + local castPoint = ability:GetCastPoint() + local manaCost = ability:GetManaCost() + local duration = ability:GetDuration() + local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, radius) + local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) + local targettableEnemies = AbilityExtensions:Filter(realEnemies, function(t) return AbilityExtensions:NormalCanCast(t) end) + local friends = AbilityExtensions:GetNearbyHeroes(npcBot, 1200, true) + local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) + local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, 900) + local friendCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, npcBot:GetAttackRange()+150, false) + local neutralCreeps = npcBot:GetNearbyNeutralCreeps(castRange) + local weakestEnemy, enemyHealth = utility.GetWeakestUnit(targettableEnemies) + local weakCreeps = enemyCreeps + local weakestCreep = utility.GetWeakestUnit(weakCreeps) + local forbiddenCreeps = {} + local manaMaintain = npcBot:GetMaxMana() * 0.6 + manaCost + if AbilityExtensions:IsFarmingOrPushing(npcBot) then + if #enemies == 0 and #enemyCreeps >= 5 and mana >= manaMaintain and abilityLevel >= 3 then + return BOT_ACTION_DESIRE_MODERATE - 0.08 + end + elseif AbilityExtensions:IsLaning(npcBot) then + if #enemyCreeps >= 3 and mana >= npcBot:GetMaxMana() * 0.3 + manaCost then + local laneEnemyHero = enemies[1] + if laneEnemyHero ~= nil and GetUnitToUnitDistance(npcBot, laneEnemyHero) <= radius and AbilityExtensions:GetHealthPercent(laneEnemyHero) <= 0.4 then + return BOT_ACTION_DESIRE_MODERATE + end + if #friendCreeps == 0 and abilityLevel >= 2 then + return BOT_ACTION_DESIRE_MODERATE end - end - end - ---------------------------------debug-------------------------------------------- - if ( castDesire[4] > 0 ) - then - table.insert(npcBot.ult,{DotaTime(),castLocation[4],GetUnitToLocationDistance(npcBot,castLocation[4])/(2.5*npcBot:GetCurrentMovementSpeed())}) - print("insert"..DotaTime().." "..GetUnitToLocationDistance(npcBot,castLocation[4])/(2.5*npcBot:GetCurrentMovementSpeed()).." "..#npcBot.ult) - npcBot:Action_UseAbilityOnLocation( AbilitiesReal[4], castLocation[4] ); - return - end - - if ( castDesire[5] > 0 ) - then - npcBot:Action_UseAbilityOnLocation( AbilitiesReal[5], castLocation[5] ); - return - end - - if ( castDesire[3] > 0 ) - then - npcBot:Action_UseAbility( AbilitiesReal[3] ); - return - end - - if ( castDesire[2] > 0 ) - then - npcBot:Action_UseAbilityOnLocation( AbilitiesReal[2], castLocation[2] ); - return - end - - if ( castDesire[1] > 0 ) - then - npcBot:Action_UseAbility( AbilitiesReal[1] ); - return - --[[if(castTarget=="immediately") - then - npcBot:Action_UseAbility( AbilitiesReal[1] ); - return - end - - if(GetUnitToUnitDistance(npcBot,castTarget[1])< AbilitiesReal[1]:GetAOERadius()) - then - npcBot:Action_UseAbility( AbilitiesReal[1] ); - return - else - npcBot:Action_MoveToUnit(castTarget[1]) - return - end]]-- - end - + end + elseif AbilityExtensions:IsAttackingEnemies(npcBot) then + if abilityLevel <= 2 then + return 0 + end + if IsUsingSleightOfFist() then + local sleightFistMarkedHeroes = AbilityExtensions:Count(enemies, function(t) return t:HasModifier("modifier_ember_spirit_sleight_of_fist_mark") end) + if sleightFistMarkedHeroes >= 3 then + return BOT_ACTION_DESIRE_HIGH + end + else + if not npcBot:IsMagicImmune() then + local projectiles = AbilityExtensions:GetIncomingDodgeWorthProjectiles(npcBot) + projectiles = AbilityExtensions:Any(projectiles, function(t) return GetUnitToLocationDistance(npcBot, t.location) <= 400 end) + if projectiles then + return BOT_ACTION_DESIRE_MODERATE + end + end + if #enemies >= 1 and DotaTime() < 10 * 60 or #realEnemies >= 2 and npcBot:GetNetWorth() / DotaTime() * 60 <= 350 or #realEnemies >= 3 then + return BOT_ACTION_DESIRE_HIGH + end + end + elseif AbilityExtensions:IsRetreating(npcBot) then + local projectiles = AbilityExtensions:GetIncomingDodgeWorthProjectiles(npcBot) + projectiles = AbilityExtensions:Any(projectiles, function(t) return GetUnitToLocationDistance(npcBot, t.location) <= 400 end) + if projectiles and abilityLevel >= 3 then + return BOT_ACTION_DESIRE_MODERATE + end + end + do + local target = npcBot:GetTarget() + if target ~= nil and target:CanBeSeen() and not AbilityExtensions:NormalCanCast(target) and GetUnitToUnitDistance(npcBot, target) < radius - 50 and abilityLevel >= 3 then + return BOT_ACTION_DESIRE_MODERATE + end + end end -Consider[1]=function() --Target Ability Example - local abilityNumber=1 - -------------------------------------- - -- Generic Variable Setting - -------------------------------------- - local ability=AbilitiesReal[abilityNumber]; - - if not ability:IsFullyCastable() then - return BOT_ACTION_DESIRE_NONE, 0; - end - - local CastRange = ability:GetCastRange(); - local Damage = ability:GetAbilityDamage(); - local Radius = ability:GetAOERadius() - - local HeroHealth=10000 - local CreepHealth=10000 - local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(CastRange,true,BOT_MODE_NONE) - local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(CastRange,true) - local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - -------------------------------------- - -- Global high-priorty usage - -------------------------------------- - -- Check for a channeling enemy - for _,npcEnemy in pairs( enemys ) - do - if ( npcEnemy:IsChanneling() and CanCast[abilityNumber]( npcEnemy )) - then - return BOT_ACTION_DESIRE_HIGH, npcEnemy - end - end - - --Try to kill enemy hero - if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) - then - if (WeakestEnemy~=nil) - then - if ( CanCast[abilityNumber]( WeakestEnemy ) ) - then - if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) or (HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana)) - then - return BOT_ACTION_DESIRE_HIGH,WeakestEnemy; - end +local activeRemnants +local refreshRemnantToken +local function RefreshActiveRemnants() + activeRemnants = AbilityExtensions:Filter(GetUnitList(UNIT_LIST_ALL), function(t) return t:GetUnitName() == "npc_dota_ember_spirit_remnant" end) +end +local DetectRemnant = AbilityExtensions:EveryManySeconds(2, RefreshActiveRemnants) +RefreshActiveRemnants() + +Consider[4] = function() + local ability = Abilities[4] + if not ability:IsFullyCastable() or IsUsingSleightOfFist() or IsUsingRemnant() or AbilityExtensions:CannotMove(npcBot) then + return 0 + end + DetectRemnant() + if #activeRemnants == 0 then + return 0 + end + local abilityLevel = ability:GetLevel() + local radius = ability:GetAOERadius()-100 + local castPoint = ability:GetCastPoint() + local manaCost = ability:GetManaCost() + local duration = ability:GetDuration() + local damage = ability:GetAbilityDamage() + local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, 900) + local friendCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, npcBot:GetAttackRange()+150, false) + local weakCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) return t:GetHealth() < t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) end) + local weakestCreep = utility.GetWeakestUnit(weakCreeps) + local forbiddenCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) + return t:GetHealth() > t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) and t:GetHealth() <= t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) + AbilityExtensions:AttackOnceDamage(npcBot, t) * (0.9+#enemyCreeps*0.1) + end) + if #friendCreeps == 0 then + forbiddenCreeps = {} + end + + if AbilityExtensions:IsFarmingOrPushing(npcBot) and AbilityExtensions:GetManaPercent(npcBot) >= 0.9 then + for _, activeRemnant in ipairs(activeRemnants) do + if #weakCreeps >= 3 and #forbiddenCreeps == 0 then + return BOT_ACTION_DESIRE_MODERATE, activeRemnant:GetLocation() end end end - -------------------------------------- - -- Mode based usage - -------------------------------------- - if ( #enemys>=1 and #creeps<=1 ) - then - if ( CanCast[abilityNumber]( enemys[1] ) ) - then - return BOT_ACTION_DESIRE_MODERATE,WeakestEnemy; + if healthPercent >= 0.75 and manaPercent >= 0.9 and AbilityExtensions:GetDistanceFromAncient(npcBot) <= 1000 and DotaTime() <= 15 * 60 then + if AbilityExtensions:IsLaning(npcBot) then + local laneFront = GetLaneFrontLocation(GetTeam(), npcBot:GetAssignedLane(), 0) + local remnantUnderTower = AbilityExtensions:Filter(activeRemnants, function(t) return GetUnitToUnitDistance(t, laneFront) <= 1000 end) + if remnantUnderTower[1] then + return BOT_ACTION_DESIRE_MODERATE, remnantUnderTower[1]:GetLocation() end - end - - -- If we're seriously retreating, see if we can land a stun on someone who's damaged us recently - if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) - then - for _,npcEnemy in pairs( enemys ) - do - if ( npcBot:WasRecentlyDamagedByHero( npcEnemy, 2.0 ) ) - then - if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange) - then - return BOT_ACTION_DESIRE_HIGH, npcEnemy; - end + elseif AbilityExtensions:IsFarmingOrPushing(npcBot) then + local remnantUnderTower = AbilityExtensions:Filter(activeRemnants, function(t) + return GetUnitToUnitDistance(t, npcBot) >= 4000 and #AbilityExtensions:GetNearbyNonIllusionHeroes(t) == 0 + end) + if remnantUnderTower[1] then + return BOT_ACTION_DESIRE_MODERATE, remnantUnderTower[1]:GetLocation() end - end - end - - -- If my mana is enough,use it at enemy - if ( npcBot:GetActiveMode() == BOT_MODE_LANING ) - then - if(ManaPercentage>0.4 or npcBot:GetMana()>ComboMana) - then - if (WeakestEnemy~=nil) - then - if ( CanCast[abilityNumber]( WeakestEnemy ) ) - then - return BOT_ACTION_DESIRE_LOW,WeakestEnemy; + elseif AbilityExtensions:IsAttackingEnemies(npcBot) then + for _, activeRemnant in ipairs(activeRemnants) do + local enemies = AbilityExtensions:GetNearbyHeroes(activeRemnant, 1599) + local enemyCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, enemies) + local friends = AbilityExtensions:GetNearbyHeroes(activeRemnant, 1200, true) + local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) + local veryNearEnemies = AbilityExtensions:GetEnemyHeroNumber(npcBot, AbilityExtensions:GetNearbyHeroes(activeRemnant, 400)) + if friendCount >= enemyCount and #veryNearEnemies == 0 then + return BOT_ACTION_DESIRE_MODERATE, activeRemnant:GetLocation() end end end end - - -- If we're farming and can hit 2+ creeps and kill 1+ - if ( npcBot:GetActiveMode() == BOT_MODE_FARM ) - then - if ( #creeps >= 2 ) - then - if(CreepHealth<=WeakestCreep:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana) - then - return BOT_ACTION_DESIRE_LOW, WeakestCreep; - end - end - end - - -- If we're going after someone - if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or - npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or - npcBot:GetActiveMode() == BOT_MODE_ATTACK ) - then - local npcEnemy = npcBot:GetTarget(); - - if ( npcEnemy ~= nil ) - then - if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange) - then - return BOT_ACTION_DESIRE_MODERATE,npcEnemy - end - end - end - return BOT_ACTION_DESIRE_NONE, 0; - + if AbilityExtensions:IsRetreating(npcBot) then + local distanceToFountain = AbilityExtensions:Filter(activeRemnants, function(t) + local distance = GetUnitToUnitDistance(t, npcBot) + return distance >= npcBot:GetCurrentMovementSpeed() * 2 and distance > AbilityExtensions:GetDistanceFromAncient(t) + 600 + end) + distanceToFountain = AbilityExtensions:Map(distanceToFountain, function(t) return { t, AbilityExtensions:GetDistanceFromAncient(t) } end) + distanceToFountain = AbilityExtensions:SortByMinFirst(distanceToFountain, function(t) return t[2] end) + if AbilityExtensions:Any(distanceToFountain) then + return BOT_ACTION_DESIRE_HIGH, distanceToFountain[1][1]:GetLocation() + end + + else + for _, activeRemnant in ipairs(activeRemnants) do + local target = AbilityExtensions:GetTargetIfGood(npcBot) + if target ~= nil and target:CanBeSeen() and AbilityExtensions:NormalCanCast(target, false) and GetUnitToUnitDistance(activeRemnant, target) <= radius then + if AbilityExtensions:GetHealthPercent(target) <= 0.7 then + if AbilityExtensions:Any(activeRemnants, function(t) + local d = GetUnitToUnitDistance(t, target) + return d >= 0.7*radius and d <= 800 and t:IsFacingLocation(target, 30) and t:GetCurrentMovementSpeed() ~= 0 + end) then + return 0.1, activeRemnant:GetLocation() + end + return RemapValClamped(AbilityExtensions:GetHealthPercent(target), 0, 0.7, 0.9, 0.5), activeRemnant:GetLocation() + end + end + local enemies = AbilityExtensions:GetNearbyNonIllusionHeroes(activeRemnant) + local realEnemies = AbilityExtensions:Filter(enemies, function(t) return + AbilityExtensions:MayNotBeIllusion(npcBot, t) and AbilityExtensions:NormalCanCast(t, false) + end) + end + end + return 0 end -Consider[2]=function() --Target AOE Ability Example - local abilityNumber=2 - -------------------------------------- - -- Generic Variable Setting - -------------------------------------- - local ability=AbilitiesReal[abilityNumber]; - - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then - return BOT_ACTION_DESIRE_NONE, 0; - end - - local CastRange = ability:GetCastRange(); - local Damage = npcBot:GetAttackDamage()+ability:GetSpecialValueInt("bonus_hero_damage") - local Radius = ability:GetAOERadius() - - local HeroHealth=10000 - local CreepHealth=10000 - local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(1200,true,BOT_MODE_NONE) - local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(1200,true) - local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - - --try to kill enemy hero - if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) - then - if (WeakestEnemy~=nil) - then - if ( CanCast[abilityNumber]( WeakestEnemy ) ) - then - if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) or (HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana)) - then - return BOT_ACTION_DESIRE_HIGH,WeakestEnemy:GetLocation()+GetSafeVector(npcBot,Radius); - end - end - end - end - -------------------------------------- - -- Mode based usage - -------------------------------------- - -- if we can hit 3+ hero - if ( npcBot:GetActiveMode() == BOT_MODE_ATTACK ) - then - local locationAoE = npcBot:FindAoELocation( true, true, npcBot:GetLocation(), CastRange+500, Radius, 0, 0 ); - if ( locationAoE.count >= 2) then - return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc; - end - end - - -- LANING - if ( npcBot:GetActiveMode() == BOT_MODE_LANING ) - then - if((ManaPercentage>0.4 or npcBot:GetMana()>ComboMana)) - then - local locationAoE = npcBot:FindAoELocation( true, false, npcBot:GetLocation(), CastRange+500, Radius, 0, 0 ); - if ( locationAoE.count >= 2) then - return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc; - end - end - end - - -- If we're farming and can kill 3+ creeps with LSA - if ( npcBot:GetActiveMode() == BOT_MODE_FARM ) then - local locationAoE = npcBot:FindAoELocation( true, false, npcBot:GetLocation(), CastRange+500, Radius, 0, 0 ); - - if ( locationAoE.count >= 2) then - return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc; - end - end - - -- If we're pushing or defending a lane and can hit 4+ creeps, go for it - if ( npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_TOP or - npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_BOT or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_TOP or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_BOT ) - then - local locationAoE = npcBot:FindAoELocation( true, false, npcBot:GetLocation(), CastRange+500, Radius, 0, 0 ); - - if ( locationAoE.count >= 3) - then - return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc; - end - end - - -- If we're going after someone - if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or - npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or - npcBot:GetActiveMode() == BOT_MODE_ATTACK ) - then - local npcEnemy = npcBot:GetTarget(); - - if ( npcEnemy ~= nil ) - then - if ( CanCast[abilityNumber]( npcEnemy ) ) - then - return BOT_ACTION_DESIRE_HIGH, npcEnemy:GetLocation()+GetSafeVector(npcBot,Radius); - end - end - end - - return BOT_ACTION_DESIRE_NONE, 0; - -end - -Consider[3]=function() - - local abilityNumber=3 - -------------------------------------- - -- Generic Variable Setting - -------------------------------------- - local ability=AbilitiesReal[abilityNumber]; - - if not ability:IsFullyCastable() then - return BOT_ACTION_DESIRE_NONE, 0; - end - - local CastRange = ability:GetCastRange(); - local Damage = ability:GetAbilityDamage(); - - local HeroHealth=10000 - local CreepHealth=10000 - local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) - local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) - local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - - -------------------------------------- - -- Global high-priorty usage - -------------------------------------- - --try to kill enemy hero - if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) - then - if (WeakestEnemy~=nil) - then - if ( CanCast[abilityNumber]( WeakestEnemy ) ) - then - if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) or (HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana)) - then - return BOT_ACTION_DESIRE_HIGH; - end - end - end - end - -------------------------------------- - -- Mode based usage - -------------------------------------- - -- If we're seriously retreating, see if we can land a stun on someone who's damaged us recently - if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) - then - if ( npcBot:WasRecentlyDamagedByHero( npcEnemy, 2.0 ) ) - then - return BOT_ACTION_DESIRE_MODERATE; - end - end - - --Laning - if ( npcBot:GetActiveMode() == BOT_MODE_LANING ) - then - if((ManaPercentage>0.4 or npcBot:GetMana()>ComboMana) and #enemys >=2) - then - return BOT_ACTION_DESIRE_LOW; - end - end - - -- If we're pushing or defending a lane and can hit 4+ creeps, go for it - if ( npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_TOP or - npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_BOT or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_TOP or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_BOT or - npcBot:GetActiveMode() == BOT_MODE_FARM ) - then - if ( #enemys==0 and #creeps>=2 and (ManaPercentage>0.4 or npcBot:GetMana()>ComboMana)) - then - return BOT_ACTION_DESIRE_LOW; - end - end - - -- If we're going after someone - if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or - npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or - npcBot:GetActiveMode() == BOT_MODE_ATTACK ) - then - local npcEnemy = npcBot:GetTarget(); - - if ( npcEnemy ~= nil ) - then - if ( CanCast[abilityNumber]( npcEnemy ) ) - then - return BOT_ACTION_DESIRE_MODERATE; - end - end - end - - return BOT_ACTION_DESIRE_NONE; - +local function ShouldGoToFountainFromLane() + return healthPercent <= 0.25 and not AbilityExtensions:HasAvailableItem("item_flask") or healthPercent <= 0.4 and manaPercent <= 0.1 end -Consider[4]=function() - local abilityNumber=4 - -------------------------------------- - -- Generic Variable Setting - -------------------------------------- - local ability=AbilitiesReal[abilityNumber]; - - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then - return BOT_ACTION_DESIRE_NONE, 0; - end - - local CastRange = ability:GetCastRange(); - local Damage = ability:GetAbilityDamage(); - - local HeroHealth=10000 - local CreepHealth=10000 - local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) - local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(1600,true) - local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - - if(npcBot.ult==nil) - then - npcBot.ult={} - end - for _,i in pairs(npcBot.ult) - do - if(DotaTime()>=i[1]+45) - then - table.remove(npcBot.ult,_) - end - end - -------------------------------------- - -- Global high-priorty usage - -------------------------------------- - --Try to kill enemy hero - if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) - then - if (WeakestEnemy~=nil) - then - if ( CanCast[abilityNumber]( WeakestEnemy ) ) - then - if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) or (HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana)) - then - local d=GetUnitToUnitDistance(npcBot,WeakestEnemy) - return BOT_ACTION_DESIRE_HIGH,utility.GetUnitsTowardsLocation(npcBot,WeakestEnemy,d+300) - end - end - end - end - - -------------------------------------- - -- Mode based usage - -------------------------------------- - -- If we're seriously retreating - if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= 0.75 and #npcBot.ult==0) - then - if ( npcBot:WasRecentlyDamagedByAnyHero(2) or #enemys >=1) - then - return BOT_ACTION_DESIRE_HIGH, utility.GetUnitsTowardsLocation(enemys[1],npcBot,CastRange); - end - end - - -- If we're pushing or defending a lane - if ( npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_TOP or - npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_BOT or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_TOP or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_BOT or - npcBot:GetActiveMode() == BOT_MODE_LANING or - npcBot:GetActiveMode() == BOT_MODE_FARM) - then - if(#npcBot.ult<1 and (npcBot.ult_time==nil or DotaTime()-npcBot.ult_time>=2)) - then - npcBot.ult_time=DotaTime() - return BOT_ACTION_DESIRE_HIGH, npcBot:GetLocation()+utility.GetSafeVector(npcBot,1500) - end - end - - -- If we're going after someone - if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or - npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or - npcBot:GetActiveMode() == BOT_MODE_ATTACK ) - then - local npcEnemy = npcBot:GetTarget(); - if ( npcEnemy ~= nil ) - then - local d=GetUnitToUnitDistance(npcBot,npcEnemy) - if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and d< CastRange + 75*#allys) - then - return BOT_ACTION_DESIRE_MODERATE, utility.GetUnitsTowardsLocation(npcBot,npcEnemy,d+300) - end - end - end - - return BOT_ACTION_DESIRE_NONE, 0; - +Consider[5] = function() + local ability = Abilities[5] + if not ability:IsFullyCastable() or ability:GetCurrentCharges() == 0 then + return 0 + end + local abilityLevel = ability:GetLevel() + local castRange = ability:GetCastRange() + local radius = ability:GetAOERadius()-100 + local castPoint = ability:GetCastPoint() + local manaCost = ability:GetManaCost() + local duration = ability:GetDuration() + local damage = Abilities[4]:GetAbilityDamage() + local friends = AbilityExtensions:GetNearbyHeroes(npcBot, 1200, true) + local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) + local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, 900) + local friendCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, npcBot:GetAttackRange()+150, false) + local neutralCreeps = npcBot:GetNearbyNeutralCreeps(castRange) + local weakCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) return t:GetHealth() < t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) end) + local weakestCreep = utility.GetWeakestUnit(weakCreeps) + local forbiddenCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) + return t:GetHealth() > t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) and t:GetHealth() <= t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) + AbilityExtensions:AttackOnceDamage(npcBot, t) * (0.9+#enemyCreeps*0.1) + end) + if #friendCreeps == 0 then + forbiddenCreeps = {} + end + local charge = ability:GetCurrentCharges() + if charge == 0 then + return 0 + end + local remnantSpeed = npcBot:GetCurrentMovementSpeed() * ability:GetSpecialValueInt("speed_multiplier") / 100 + + if AbilityExtensions:IsFarmingOrPushing(npcBot) and AbilityExtensions:GetManaPercent(npcBot) >= 0.9 then + local nearbyTowers = npcBot:GetNearbyTowers(1100, true) + if #nearbyTowers == 1 and (nearbyTowers[1] == GetTower(GetTeam(), TOWER_MID_1) or nearbyTowers[1] == GetTower(GetTeam(), TOWER_MID_2)) then + if ShouldGoToFountainFromLane() then + if #activeRemnants == 0 then + return BOT_ACTION_DESIRE_HIGH, nearbyTowers[1]:GetLocation() + RandomVector(200) + else + local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, 800) + local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) + if #realEnemies == 0 then + AbilityExtensions:TryUseTp(npcBot) + end + end + end + end + end + + if AbilityExtensions:IsRetreating(npcBot) then + if IsUsingRemnant() then + return 0 + end + local enemies = AbilityExtensions:GetNearbyHeroes(npcBot) + if npcBot:WasRecentlyDamagedByAnyHero(1.5) and #enemies ~= 0 then + if #activeRemnants ~= 0 then + return 0 + end + local useRange = castRange - 80 + local nearestEnemy = enemies[1] + local strangeFacing = npcBot:GetFacing() + if nearestEnemy:IsFacingLocation(npcBot:GetLocation(), 20) then + strangeFacing = nearestEnemy:GetFacing() + 75 + end + local extraLocation = npcBot:GetLocation() + Vector(useRange * math.cos(strangeFacing), useRange * math.sin(strangeFacing)) + if npcBot:HasScepter() then + extraLocation = AbilityExtensions:GetPointFromLineByDistance(npcBot:GetLocation(), AbilityExtensions:GetAncient(npcBot), useRange) + end + if npcBot:GetCurrentMovementSpeed() >= 285 or npcBot:GetCurrentMovementSpeed() >= 240 and IsUsingSleightOfFist() then + return BOT_ACTION_DESIRE_HIGH, extraLocation + end + end + else + local target = AbilityExtensions:GetTargetIfGood(npcBot) + if target ~= nil and target:CanBeSeen() and AbilityExtensions:NormalCanCast(target, false) then + if AbilityExtensions:GetHealthPercent(target) <= 0.7 then + local remnantNumber = AbilityExtensions:Count(activeRemnants, function(t) + return GetUnitToUnitDistance(t, target) <= radius + end) + local damageOnce = target:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) + if target:GetHealth() <= (0.9+0.18*friendCount) * damageOnce * remnantNumber + charge then + return BOT_ACTION_DESIRE_HIGH, target:GetExtrapolatedLocation(GetUnitToUnitDistance(target, npcBot) / Clamp((remnantSpeed - target:GetCurrentMovementSpeed()), 100, 1000)) + end + end + end + end + return 0 end -function Consider5_r() - - local abilityNumber=5 - -------------------------------------- - -- Generic Variable Setting - -------------------------------------- - local ability=AbilitiesReal[abilityNumber]; - - if (not ability:IsFullyCastable()) then - return BOT_ACTION_DESIRE_NONE, 0; - end - - local CastRange = ability:GetCastRange(); - local Damage = ability:GetAbilityDamage(); - - local HeroHealth=10000 - local CreepHealth=10000 - local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) - local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(1600,true) - local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - -------------------------------------- - -- Global high-priorty usage - -------------------------------------- - --Try to kill enemy hero - if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) - then - if (WeakestEnemy~=nil) - then - if ( CanCast[abilityNumber]( WeakestEnemy ) ) - then - if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) or (HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana)) - then - return BOT_ACTION_DESIRE_HIGH,WeakestEnemy:GetLocation() - end - end - end - end - - -------------------------------------- - -- Mode based usage - -------------------------------------- - -- If we're seriously retreating - if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= 0.5) - then - if ( npcBot:WasRecentlyDamagedByAnyHero(2) or #enemys >=1) - then - return BOT_ACTION_DESIRE_HIGH,utility.Fountain(GetTeam()) - end - end - - -- If we're going after someone - if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or - npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or - npcBot:GetActiveMode() == BOT_MODE_ATTACK ) - then - local npcEnemy = npcBot:GetTarget(); - if ( npcEnemy ~= nil ) - then - local d=GetUnitToUnitDistance(npcBot,npcEnemy) - if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and d< CastRange + 75*#allys) - then - return BOT_ACTION_DESIRE_MODERATE, utility.GetUnitsTowardsLocation(npcBot,npcEnemy,d+300) - end - end - end - - return BOT_ACTION_DESIRE_NONE, 0; - -end +AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, Abilities) -Consider[5]=function() - if(npcBot:HasModifier("modifier_ember_spirit_fire_remnant_timer")==false and npcBot.ult~=nil) - then - --print("remove"..DotaTime().." "..#npcBot.ult) - npcBot.ult={} - return BOT_ACTION_DESIRE_NONE, 0; - end - - if(npcBot.ult==nil or #npcBot.ult==0) - then - return BOT_ACTION_DESIRE_NONE, 0; - end - - local desire,location=Consider5_r() - if(desire==0) - then - return BOT_ACTION_DESIRE_NONE, 0; - end - - local min_distance =10000 - local q=-1 - for _,i in pairs(npcBot.ult) - do - if(DotaTime()>i[1]+i[3]) - then - d=utility.PointToPointDistance(i[2],location) - if(d=0.4) then for k,creep in pairs(creepsNeutral) do - if(IsGoodNeutralCreeps(creep) and not creep:WasRecentlyDamagedByAnyHero(1.5) or (creep:IsAncientCreep() and npcBot:HasScepter())) + if IsGoodNeutralCreeps(creep) and not creep:WasRecentlyDamagedByAnyHero(1.5) then return BOT_ACTION_DESIRE_MODERATE, creep; end @@ -179,7 +179,7 @@ Consider[2]=function() if ( npcEnemy ~= nil ) then - if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange + 75*#allys) + if ( CanCast[abilityNumber]( npcEnemy ) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange + 75*#allys) then return BOT_ACTION_DESIRE_MODERATE, npcEnemy end @@ -204,9 +204,8 @@ Consider[3]=function() local Radius = ability:GetAOERadius(); local Damage = 0 - local HeroHealth=10000 - local CreepHealth=10000 - local allys = npcBot:GetNearbyHeroes( Radius+300, false, BOT_MODE_NONE ); + local allys = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, Radius+100, false) + allys = AbilityExtensions:Filter(npcBot, function(t) return not t:HasModifier("modifier_ice_blast") end) local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(Radius+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -218,7 +217,7 @@ Consider[3]=function() -- If we're seriously retreating if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) then - if ( HealthPercentage<=0.5 and npcBot:WasRecentlyDamagedByAnyHero(2.0)) + if HealthPercentage<=0.5 and npcBot:WasRecentlyDamagedByAnyHero(2.0) and not npcBot:HasModifier("modifier_ice_blast") then return BOT_ACTION_DESIRE_HIGH end @@ -249,10 +248,10 @@ Consider[3]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_MID or npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_BOT) then - if #creeps2<=2 then + if #creeps2<=1 then for _,npcTarget in pairs( allys ) do - if(npcTarget:GetHealth()/npcTarget:GetMaxHealth()<(0.4+0.4*ManaPercentage)) + if(npcTarget:GetHealth()/npcTarget:GetMaxHealth()<(0.4+0.4*ManaPercentage)) and not npcTarget:HasModifier("modifier_ice_blast") then return BOT_ACTION_DESIRE_MODERATE end @@ -260,105 +259,7 @@ Consider[3]=function() end end - return BOT_ACTION_DESIRE_NONE, 0; - -end - -Consider[1]=function() - local abilityNumber=1 - -------------------------------------- - -- Generic Variable Setting - -------------------------------------- - local ability=AbilitiesReal[abilityNumber]; - - if not ability:IsFullyCastable() or AbilityExtensions:IsPhysicalOutputDisabled(npcBot) then - return BOT_ACTION_DESIRE_NONE, 0; - end - - local CastRange = ability:GetCastRange(); - local Damage = 0 - - local HeroHealth=10000 - local CreepHealth=10000 - local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(CastRange+100,true,BOT_MODE_NONE) - local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(CastRange+100,true) - local creeps2 = npcBot:GetNearbyCreeps(300,true) - local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - - if(ability:GetToggleState()==false) - then - local t=npcBot:GetAttackTarget() - if(t~=nil) - then - if (t:IsHero() or t:IsTower()) or AbilityExtensions:MustBeIllusion(npcBot, t) and (AbilityExtensions:GetManaPercent(npcBot) >= 0.8) - then - ability:ToggleAutoCast() - return BOT_ACTION_DESIRE_NONE, 0; - end - end - else - local t=npcBot:GetAttackTarget() - if(t~=nil) - then - if (not(t:IsHero() or t:IsTower())) - then - ability:ToggleAutoCast() - return BOT_ACTION_DESIRE_NONE, 0; - end - end - end - - --try to kill enemy hero - if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT) - then - if (WeakestEnemy~=nil) - then - if ( CanCast[abilityNumber]( WeakestEnemy ) ) - then - if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_ALL)) - then - return BOT_ACTION_DESIRE_HIGH,WeakestEnemy; - end - end - end - end - -------------------------------------- - -- Mode based usage - -------------------------------------- - if ( npcBot:GetActiveMode() == BOT_MODE_LANING ) - then - if AbilityExtensions:HasEnoughManaToUseAttackAttachedAbility(npcBot, AbilitiesReal[abilityNumber]) and #creeps2<=1 - then - if (WeakestEnemy~=nil) - then - if ( CanCast[abilityNumber]( WeakestEnemy ) ) - then - return BOT_ACTION_DESIRE_LOW-0.01,WeakestEnemy - end - end - end - end - - -- If we're going after someone - if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or - npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or - npcBot:GetActiveMode() == BOT_MODE_ATTACK ) - then - local npcEnemy = npcBot:GetTarget(); - - if ( npcEnemy ~= nil ) - then - if ( CanCast[abilityNumber]( npcEnemy ) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange+100) - then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy; - end - end - end - - return BOT_ACTION_DESIRE_NONE, 0; + return BOT_ACTION_DESIRE_NONE end diff --git a/ability_item_usage_enigma.lua b/ability_item_usage_enigma.lua index 4202bc75..4402e08d 100644 --- a/ability_item_usage_enigma.lua +++ b/ability_item_usage_enigma.lua @@ -416,109 +416,92 @@ Consider[3]=function() end Consider[4]=function() - local abilityNumber=4 - -------------------------------------- - -- Generic Variable Setting - -------------------------------------- - local ability=AbilitiesReal[abilityNumber]; - - if not ability:IsFullyCastable() then - return BOT_ACTION_DESIRE_NONE, 0; - end - - local CastRange = ability:GetCastRange(); - local Damage = 0 - local Radius = ability:GetAOERadius()-50; - local CastPoint = ability:GetCastPoint() - - local HeroHealth=10000 - local CreepHealth=10000 - local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) - local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) + local abilityNumber=4 + -------------------------------------- + -- Generic Variable Setting + -------------------------------------- + local ability=AbilitiesReal[abilityNumber]; + + if not ability:IsFullyCastable() then + return BOT_ACTION_DESIRE_NONE, 0; + end + + local CastRange = ability:GetCastRange() + local Radius = ability:GetAOERadius()-50 + local CastPoint = ability:GetCastPoint() + + local allys = AbilityExtensions:Filter(AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot), function(t) return AbilityExtensions:NotRetreating(t) end) + local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) + local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) + + local blink = AbilityExtensions:GetAvailableBlink(npcBot) + if(blink~=nil and blink:IsFullyCastable()) + then + CastRange=CastRange+1200 + if(npcBot:GetActiveMode() == BOT_MODE_ATTACK ) + then + local locationAoE = npcBot:FindAoELocation( true, true, npcBot:GetLocation(), CastRange, Radius, 0, 0 ); + if ( locationAoE.count >= 2 ) + then + npcBot:Action_UseAbilityOnLocation( blink, locationAoE.targetloc ); + return 0 + end + end + end + + local channelingEnemies = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot) + channelingEnemies = AbilityExtensions:Filter(channelingEnemies, function(t) return AbilityExtensions:IsChannelingAbility(t) and not t:IsInvulnerable() and t:CanBeSeen() end) + channelingEnemies = AbilityExtensions:Map(channelingEnemies, function(t) return { t, t:GetCurrentActiveAbility() } end) + channelingEnemies = AbilityExtensions:Map(channelingEnemies, function(t) return { t[1], t[2] and t[2]:GetCooldown() or 25 } end) + channelingEnemies = AbilityExtensions:SortByMaxFirst(channelingEnemies, function(t) return t[2] end) + if AbilityExtensions:Any(channelingEnemies) then + for _, channelingEnemy in ipairs(channelingEnemies) do + if channelingEnemy[1]:IsMagicImmune() or not AbilitiesReal[1]:IsFullyCastable() then + if channelingEnemy[2] > 60 then + return RemapValClamped(channelingEnemy[2], 60, 120, 0.5, 0.7), channelingEnemy[1]:GetLocation() + end + end + end + end - local i=npcBot:FindItemSlot("item_blink") - if(i>=0 and i<=5) - then - blink=npcBot:GetItemInSlot(i) - i=nil - end - if(blink~=nil and blink:IsFullyCastable()) - then - CastRange=CastRange+1200 - if(npcBot:GetActiveMode() == BOT_MODE_ATTACK ) - then - local locationAoE = npcBot:FindAoELocation( true, true, npcBot:GetLocation(), CastRange, Radius, 0, 0 ); - if ( locationAoE.count >= 2 ) - then - npcBot:Action_UseAbilityOnLocation( blink, locationAoE.targetloc ); - return 0 - end - end - end - -------------------------------------- - -- Global high-priorty usage - -------------------------------------- - -- Check for a channeling enemy - -- If we're in a teamfight, use it on the scariest enemy - local tableNearbyAttackingAlliedHeroes = npcBot:GetNearbyHeroes( 1000, false, BOT_MODE_ATTACK ); - if ( #tableNearbyAttackingAlliedHeroes >= 2 ) - then - for _,npcEnemy in pairs( enemys ) - do - if ( npcEnemy:IsChanneling() ) - then - return BOT_ACTION_DESIRE_MODERATE-0.15, npcEnemy:GetLocation() - end - end - end -------------------------------------- -- Mode based usage - -------------------------------------- - -- If we're seriously retreating, see if we can land a stun on someone who's damaged us recently + -------------------------------------- + + local enemies = AbilityExtensions:Filter(AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot), function(t) return CanCast[4](t) end) + local enemyCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, enemies) + local locationAoE = npcBot:FindAoELocation( true, true, npcBot:GetLocation(), CastRange, Radius, CastPoint, 0 ) + if locationAoE.count >= 2 and locationAoE.count == enemyCount and #allys <= enemyCount/2 then + return RemapValClamped(locationAoE.count/enemyCount, 0.7, 1, 0.5, 1), locationAoE.targetloc + end + + -- If we're seriously retreating, see if we can land a stun on someone who's damaged us recently if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) then - local locationAoE = npcBot:FindAoELocation( true, true, npcBot:GetLocation(), CastRange, Radius, CastPoint, 0 ); - if ( locationAoE.count >= 2 ) + if ( locationAoE.count >= 2 ) then return BOT_ACTION_DESIRE_LOW-0.15, locationAoE.targetloc end end - -- If we're pushing or defending a lane and can hit 4+ creeps, go for it - if ( npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_TOP or - npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_BOT or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_TOP or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_BOT ) - then - local locationAoE = npcBot:FindAoELocation( true, true, npcBot:GetLocation(), CastRange, Radius, CastPoint, 0 ); - if ( locationAoE.count >= 3 ) - then - return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc - end - end - -- If we're going after someone if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local locationAoE = npcBot:FindAoELocation( true, true, npcBot:GetLocation(), CastRange, Radius, CastPoint, 0 ); if ( locationAoE.count >= 2 ) then return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc end end - -- If we're in a teamfight, use it + -- If we're in a teamfight, use it local tableNearbyAttackingAlliedHeroes = npcBot:GetNearbyHeroes( 1000, false, BOT_MODE_ATTACK ); if ( #tableNearbyAttackingAlliedHeroes >= 2 ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) - if ( npcEnemy ~= nil and Enemys~=nil and #Enemys >= 2) + if ( npcEnemy ~= nil and enemys~=nil and #enemys >= 2) then return BOT_ACTION_DESIRE_HIGH, locationAoE.targetloc end diff --git a/ability_item_usage_faceless_void.lua b/ability_item_usage_faceless_void.lua index c0b4798d..83469076 100644 --- a/ability_item_usage_faceless_void.lua +++ b/ability_item_usage_faceless_void.lua @@ -91,14 +91,13 @@ Consider[1]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotMove(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end local CastRange = ability:GetSpecialValueInt( "range" ); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -201,8 +200,7 @@ Consider[2]=function() local Radius = ability:GetAOERadius() local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes(Radius, false, BOT_MODE_NONE ); local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) @@ -248,7 +246,7 @@ Consider[2]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil and #enemys==1) then @@ -294,8 +292,7 @@ Consider[5]=function() local Radius = ability:GetAOERadius()-50; local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_furion.lua b/ability_item_usage_furion.lua index 2045944f..bedcc5b9 100644 --- a/ability_item_usage_furion.lua +++ b/ability_item_usage_furion.lua @@ -173,8 +173,7 @@ Consider[1]=function() then local tableNearbyEnemyHeroes = npcBot:GetNearbyHeroes( 150, true, BOT_MODE_NONE ); - if ( npcBot:WasRecentlyDamagedByAnyHero(3) and #tableNearbyEnemyHeroes==0) - then + if AbilityExtensions:MayNotBeSeen(npcBot) then return UseAtTarget(BOT_ACTION_DESIRE_VERYHIGH, npcBot) end end @@ -183,7 +182,7 @@ Consider[1]=function() if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT) then local tableNearbyEnemyHeroes = npcBot:GetNearbyHeroes( 200, true, BOT_MODE_NONE ); - if #tableNearbyEnemyHeroes==0 and npcBot:WasRecentlyDamagedByAnyHero(3) then + if AbilityExtensions:MayNotBeSeen(npcBot) then return UseAtTarget(BOT_ACTION_DESIRE_VERYHIGH, npcBot) end end @@ -220,7 +219,7 @@ Consider[2]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotTeleport(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end @@ -353,8 +352,7 @@ Consider[4]=function() local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local CastRange=1600; local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(1200,true,BOT_MODE_NONE) @@ -387,7 +385,7 @@ Consider[4]=function() then if(WeakestCreep~=nil) then - return BOT_ACTION_DESIRE_HIGH,WeakestCreep; + return BOT_ACTION_DESIRE_HIGH,WeakestCreep,"Target" end if(WeakestEnemy~=nil) then @@ -412,18 +410,6 @@ Consider[4]=function() end end end - - -- If we're farming and can hit 2+ creeps and kill 1+ - if ( npcBot:GetActiveMode() == BOT_MODE_FARM ) - then - if ( #Allcreeps >= 2 ) - then - if(CreepHealth<=Allcreeps[1]:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) and ManaPercentage>0.45 and npcBot:GetMana()>ComboMana) - then - return BOT_ACTION_DESIRE_LOW, Allcreeps[1],"Target"; - end - end - end -- If we're pushing or defending a lane and can hit 3+ creeps, go for it if ( npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_TOP or diff --git a/ability_item_usage_generic.lua b/ability_item_usage_generic.lua index 714d9dc4..872f8308 100644 --- a/ability_item_usage_generic.lua +++ b/ability_item_usage_generic.lua @@ -11,29 +11,46 @@ local ItemUsageSystem = dofile(GetScriptDirectory() .. "/util/ItemUsageSystem") local ChatSystem = dofile(GetScriptDirectory() .. "/util/ChatSystem") local AbilityExtensions = require(GetScriptDirectory().."/util/AbilityAbstraction") -local function ConsiderGlyph() - local Towers = { - TOWER_TOP_1, - TOWER_TOP_2, - TOWER_TOP_3, - TOWER_MID_1, - TOWER_MID_2, - TOWER_MID_3, - TOWER_BOT_1, - TOWER_BOT_2, - TOWER_BOT_3, - TOWER_BASE_1, - TOWER_BASE_2 - } +local towerId = { + TOWER_TOP_1, + TOWER_TOP_2, + TOWER_TOP_3, + TOWER_MID_1, + TOWER_MID_2, + TOWER_MID_3, + TOWER_BOT_1, + TOWER_BOT_2, + TOWER_BOT_3, + TOWER_BASE_1, + TOWER_BASE_2, +} +local RefreshBuildingHealth = AbilityExtensions:SingleForTeam(AbilityExtensions:EveryManySeconds(0.5, function() + for _, id in ipairs(towerId) do + local tower = GetTower(GetTeam(), id) + if tower ~= nil and tower:GetHealth() > 0 then + tower.health0SecondsAgo = tower:GetHealth() + if tower:IsAlive() then + for _, i in ipairs({0.5,1,1.5,2}) do + tower["health"..tostring(i).."SecondsAgo"] = tower["health"..tostring(i-0.5).."SecondsAgo"] + end + end + end + end +end)) +local function ConsiderGlyph() + RefreshBuildingHealth() if GetGlyphCooldown() > 0 then return false end - for i, BuildingID in pairs(Towers) do + for i, BuildingID in pairs(towerId) do local tower = GetTower(GetTeam(), BuildingID) - if tower ~= nil then + if tower ~= nil and tower:GetHealth() > 0 then local tableNearbyEnemyHeroes = utility.GetEnemiesNearLocation(tower:GetLocation(), 700) + if tableNearbyEnemyHeroes ~= nil and #tableNearbyEnemyHeroes >= 1 and tower["health1SecondsAgo"] and tower:GetHealth() - tower["health1SecondsAgo"] >= 7.5 * DotaTime() / 60 and DotaTime() >= 12 * 60 then + GetBot():ActionImmediate_Glyph() + end if tower:GetHealth() >= 200 and tower:GetHealth() <= 1000 and #tableNearbyEnemyHeroes >= 2 then GetBot():ActionImmediate_Glyph() break @@ -59,6 +76,11 @@ local function RecordStuckState() end end +local function AncientBelow(team, health) + local ancient = GetAncient(team) + return ancient:IsInvulnerable() and ancient:GetHealth() < health +end + local function SecondaryOperation() ConsiderGlyph() ItemUsageSystem.UnImplementedItemUsage() @@ -68,10 +90,20 @@ local function SecondaryOperation() then ChatSystem.SendVersionAnnouncement() end + if AncientBelow(TEAM_RADIANT, 1500) or AncientBelow(TEAM_DIRE, 1500) then + AbilityExtensions:AnnounceGroups1(GetBot()) + end + if AncientBelow(TEAM_RADIANT, 1200) or AncientBelow(TEAM_DIRE, 1200) then + AbilityExtensions:AnnounceGroups2(GetBot()) + end end function CourierUsageThink() - Courier.CourierUsageThink() + if not GetBot():IsAlive() then + return + end + AbilityExtensions:TickFromDota() + --Courier.CourierUsageThink() SecondaryOperation() end @@ -84,7 +116,7 @@ local ExecuteAbilityLevelUp = function(AbilityToLevelUp, TalentTree) local npcBot = GetBot() local function GetNextTalent() return AbilityExtensions:First(AbilityExtensions:GetTalents(npcBot), function(t) - return t:CanAbilityBeUpgraded() + return not t:IsTrained() end) end @@ -329,6 +361,30 @@ function ConsiderAbility(AbilitiesReal, Consider) return cast end +function ConsiderAbilityCoroutine(AbilitiesReal, Consider) + local npcBot = GetBot() + local cast = {} + cast.Desire = {} + cast.Target = {} + cast.Type = {} + for i, ability in pairs(AbilitiesReal) do + if Consider[i] ~= nil then + local consider1 = AbilityExtensions:ResumeUntilReturn(Consider[i]) + consider1 = AbilityExtensions:Max(consider1, function(t) return t[1] end) + if consider1 then + cast.Desire[i], cast.Target[i], cast.Type[i] = AbilityExtensions:Unpack(consider1) + else + cast.Desire[i] = 0 + end + end + end + return cast +end + +local worldBounds = GetWorldBounds() +local function OutOfBound(vector) + return worldBounds[1] >= vector.x or worldBounds[2] >= vector.y or worldBounds[3] <= vector.x or worldBounds[4] <= vector.y +end function UseAbility(AbilitiesReal, cast) local npcBot = GetBot() local HighestDesire = 0 @@ -343,24 +399,78 @@ function UseAbility(AbilitiesReal, cast) if (HighestDesire > 0) then local j = HighestDesireAbilityNumber local ability = AbilitiesReal[j] + if not ability:IsCooldownReady() then + print("Ability still in cooldown: "..ability:GetName()) + AbilityExtensions:DebugPause() + return + end + if npcBot:GetMana() < ability:GetManaCost() then + print("Ability mana not enough: "..ability:GetName()) + AbilityExtensions:DebugPause() + return + end + if ability:IsHidden() then + print("Ability is hidden: "..ability:GetName()) + AbilityExtensions:DebugPause() + return + end + -- if npcBot:IsRooted() then + -- print("use when rooted: "..ability:GetName()) + -- end + + local function CallWithTarget() + cast.Type[j] = "Target" + -- if not AbilityExtensions:IsHero(cast.Target[j]) then + -- print("target at creep"..ability:GetName()) + -- end + -- print("target ability :"..ability:GetName()) + if AbilityExtensions:IsVector(cast.Target[j]) then + print("Wrong target type") + print(ability:GetName(), cast.Target[j], cast.Type[j]) + AbilityExtensions:DebugPause() + return + else + npcBot:Action_UseAbilityOnEntity(ability, cast.Target[j]) + end + end + local function CallWithLocation() + cast.Type[j] = "Location" + if not AbilityExtensions:IsVector(cast.Target[j]) then + print("Wrong target type") + print(ability:GetName(), cast.Target[j], cast.Type[j]) + AbilityExtensions:DebugPause() + return + elseif OutOfBound(cast.Target[j]) then + print("Ability cast out of world bounds!") + print(ability:GetName(), cast.Target[j], cast.Type[j]) + AbilityExtensions:DebugPause() + return + else + npcBot:Action_UseAbilityOnLocation(ability, cast.Target[j]) + end + end + if (cast.Type[j] == nil) then if (utility.CheckFlag(ability:GetBehavior(), ABILITY_BEHAVIOR_NO_TARGET)) then npcBot:Action_UseAbility(ability) elseif (utility.CheckFlag(ability:GetBehavior(), ABILITY_BEHAVIOR_POINT)) then - npcBot:Action_UseAbilityOnLocation(ability, cast.Target[j]) + CallWithLocation() elseif (utility.CheckFlag(ability:GetTargetType(), ABILITY_TARGET_TYPE_TREE)) then + cast.Type[j] = "Tree" npcBot:Action_UseAbilityOnTree(ability, cast.Target[j]) else - npcBot:Action_UseAbilityOnEntity(ability, cast.Target[j]) + CallWithTarget() end else - if (cast.Type[j] == "Target") then - npcBot:Action_UseAbilityOnEntity(ability, cast.Target[j]) - elseif (cast.Type[j] == "Location") then - npcBot:Action_UseAbilityOnLocation(ability, cast.Target[j]) - else - npcBot:Action_UseAbility(ability) - end + if cast.Type[j] == "Target" then + CallWithTarget() + elseif cast.Type[j] == "Location" then + CallWithLocation() + elseif cast.Type[j] == "Tree" then + npcBot:Action_UseAbilityOnTree(ability, cast.Target[j]) + else + npcBot:Action_UseAbility(ability) + end end return j, cast.Target[j], cast.Type[j] end diff --git a/ability_item_usage_gyrocopter.lua b/ability_item_usage_gyrocopter.lua index b847a235..a3541584 100644 --- a/ability_item_usage_gyrocopter.lua +++ b/ability_item_usage_gyrocopter.lua @@ -100,8 +100,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius() local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes(Radius, false, BOT_MODE_NONE ); local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) @@ -223,7 +222,7 @@ Consider[2]=function() -- Check for a channeling enemy for _,npcEnemy in pairs( enemys ) do - if ( npcEnemy:IsChanneling() and CanCast[abilityNumber]( npcEnemy )) + if ( npcEnemy:IsChanneling() and CanCast[abilityNumber]( npcEnemy )) then return BOT_ACTION_DESIRE_HIGH, npcEnemy end @@ -332,7 +331,7 @@ Consider[2]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -508,7 +507,7 @@ Consider[4]=function() return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc; end - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then diff --git a/ability_item_usage_hoodwink.lua b/ability_item_usage_hoodwink.lua index 43f8cde6..9c61e3a8 100644 --- a/ability_item_usage_hoodwink.lua +++ b/ability_item_usage_hoodwink.lua @@ -24,19 +24,19 @@ local AbilityToLevelUp= Abilities[1], --3 Abilities[3], --4 Abilities[1], --5 - Abilities[4], --6 + Abilities[6], --6 Abilities[1], --7 Abilities[3], --8 Abilities[3], --9 Abilities[2], --10 "talent", --11 - Abilities[4], --12 + Abilities[6], --12 Abilities[2], --13 Abilities[2], --14 "talent", --15 Abilities[2], --16 "nil", --17 - Abilities[4], --18 + Abilities[6], --18 "nil", --19 "talent", --20 "nil", --21 @@ -100,8 +100,7 @@ Consider[1]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+0,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -117,7 +116,7 @@ Consider[1]=function() then if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) or (HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana)) then - return BOT_ACTION_DESIRE_HIGH,WeakestEnemy:GetLocation(); + return BOT_ACTION_DESIRE_HIGH,WeakestEnemy:GetLocation(),"Location" end end end @@ -134,7 +133,7 @@ Consider[1]=function() then local locationAoE = npcBot:FindAoELocation( true, false, npcBot:GetLocation(), CastRange, Radius, 0, Damage ); if ( locationAoE.count >= 1 ) then - return BOT_ACTION_DESIRE_LOW-0.02, locationAoE.targetloc; + return BOT_ACTION_DESIRE_LOW-0.02, locationAoE.targetloc,"Location" end end end @@ -146,7 +145,7 @@ Consider[1]=function() then local locationAoE = npcBot:FindAoELocation( true, true, npcBot:GetLocation(), CastRange, Radius, 0, 0 ); if ( locationAoE.count >= 2 ) then - return BOT_ACTION_DESIRE_LOW-0.01, locationAoE.targetloc; + return BOT_ACTION_DESIRE_LOW-0.01, locationAoE.targetloc,"Location" end end end @@ -156,7 +155,7 @@ Consider[1]=function() local locationAoE = npcBot:FindAoELocation( true, false, npcBot:GetLocation(), CastRange, Radius, 0, Damage ); if ( locationAoE.count >= 3 ) then - return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc; + return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc,"Location" end end @@ -172,7 +171,7 @@ Consider[1]=function() if ( locationAoE.count >= 4 ) then - return BOT_ACTION_DESIRE_LOW+0.01, locationAoE.targetloc; + return BOT_ACTION_DESIRE_LOW+0.01, locationAoE.targetloc,"Location" end end @@ -188,7 +187,7 @@ Consider[1]=function() then if ( CanCast[abilityNumber]( npcTarget ) ) then - return BOT_ACTION_DESIRE_MODERATE, npcTarget:GetLocation(); + return BOT_ACTION_DESIRE_MODERATE, npcTarget:GetLocation(),"Location" end end end @@ -232,11 +231,11 @@ Consider[2]=function() for _,myFriend in pairs(allys) do if ( GetUnitToUnitDistance( myFriend, npcBot ) < CastRange and not myFriend:HasModifier(modifierName) ) then - return BOT_ACTION_DESIRE_MODERATE, myFriend, "Target" + return BOT_ACTION_DESIRE_MODERATE, myFriend:GetLocation() end end if not npcBot:HasModifier(modifierName) then - return BOT_ACTION_DESIRE_MODERATE, npcBot, "Target" + return BOT_ACTION_DESIRE_MODERATE, npcBot:GetLocation() end end end @@ -248,12 +247,12 @@ Consider[2]=function() do if ( not ally:HasModifier(modifierName) ) then - return BOT_ACTION_DESIRE_MODERATE,ally, "Target" + return BOT_ACTION_DESIRE_MODERATE,ally:GetLocation() end end if not npcBot:HasModifier(modifierName) then - return BOT_ACTION_DESIRE_MODERATE, npcBot, "Target" + return BOT_ACTION_DESIRE_MODERATE, npcBot:GetLocation() end end @@ -287,33 +286,18 @@ Consider[3]=function() -------------------------------------- -- Global high-priorty usage -------------------------------------- - -- Check for a channeling enemy - for _,npcEnemy in pairs( enemys ) - do - if ( npcEnemy:IsChanneling() ) - then - return BOT_ACTION_DESIRE_HIGH, npcEnemy:GetLocation(), "Location" - end - end -------------------------------------- -- Mode based usage -------------------------------------- - -- If we're farming and can kill 3+ creeps with LSA - if ( npcBot:GetActiveMode() == BOT_MODE_FARM ) then - local locationAoE = npcBot:FindAoELocation( true, false, npcBot:GetLocation(), CastRange, Radius, 0, Damage ); - if ( locationAoE.count >= 3 ) then - return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc, "Location" - end - end -- If we're seriously retreating, see if we can land a stun on someone who's damaged us recently if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) then if ( npcBot:WasRecentlyDamagedByAnyHero( 2.0 ) ) then - return BOT_ACTION_DESIRE_HIGH, utility.Fountain(GetTeam()), "Location" + return BOT_ACTION_DESIRE_HIGH end end @@ -325,7 +309,7 @@ Consider[3]=function() then local locationAoE = npcBot:FindAoELocation( true, true, npcBot:GetLocation(), CastRange, Radius, 0, 0 ); if ( locationAoE.count >= 2 ) then - return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc, "Location" + return BOT_ACTION_DESIRE_LOW end local npcEnemy = npcBot:GetTarget(); @@ -334,7 +318,7 @@ Consider[3]=function() then if ( CanCast[abilityNumber]( npcEnemy ) ) then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy:GetExtrapolatedLocation(CastPoint), "Location" + return BOT_ACTION_DESIRE_MODERATE end end end @@ -359,12 +343,7 @@ Consider[6]=function() local Radius = ability:GetAOERadius()-50 local CastPoint = ability:GetCastPoint() - local i=npcBot:FindItemSlot("item_blink") - if(i>=0 and i<=5) - then - blink=npcBot:GetItemInSlot(i) - i=nil - end + local blink = AbilityExtensions:GetAvailableBlink(npcBot) if(blink~=nil and blink:IsFullyCastable()) then CastRange=CastRange+1200 @@ -379,8 +358,7 @@ Consider[6]=function() end end - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_huskar.lua b/ability_item_usage_huskar.lua index 0446f3f2..272a20f6 100644 --- a/ability_item_usage_huskar.lua +++ b/ability_item_usage_huskar.lua @@ -160,8 +160,7 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+100,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -245,8 +244,7 @@ Consider[4]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -277,7 +275,7 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then diff --git a/ability_item_usage_jakiro.lua b/ability_item_usage_jakiro.lua index 2fc7129f..6d6fae58 100644 --- a/ability_item_usage_jakiro.lua +++ b/ability_item_usage_jakiro.lua @@ -17,9 +17,6 @@ local AbilitiesReal ={} ability_item_usage_generic.InitAbility(Abilities,AbilitiesReal,Talents) --- utility.PrintAbilityName(Abilities) -local abilityName = { "jakiro_dual_breath", "jakiro_ice_path", "jakiro_liquid_fire", "jakiro_liquid_ice", "jakiro_macropyre" } -local abilityIndex = utility.ReverseTable(abilityName) local AbilityToLevelUp= { @@ -77,7 +74,9 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} +local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.NCanCast,function(t) + return AbilityExtensions:NormalCanCast(t, true, AbilityExtensions:HasScepter(npcBot) and DAMAGE_TYPE_PURE or DAMAGE_TYPE_MAGICAL, false, false) +end} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -88,6 +87,7 @@ function GetComboMana() return ability_item_usage_generic.GetComboMana(AbilitiesReal) end + Consider[1]=function() local abilityNumber=1 -------------------------------------- @@ -103,8 +103,7 @@ Consider[1]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -236,8 +235,7 @@ Consider[2]=function() --Target AOE Ability Example local CastPoint=ability:GetCastPoint(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -319,7 +317,7 @@ Consider[2]=function() --Target AOE Ability Example return BOT_ACTION_DESIRE_MODERATE, locationAoE.targetloc end - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -350,8 +348,7 @@ Consider[3]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -460,11 +457,10 @@ Consider[3]=function() end end - return BOT_ACTION_DESIRE_NONE, 0; - - + return BOT_ACTION_DESIRE_NONE end + Consider[4] = function() local abilityNumber=4 -------------------------------------- @@ -480,8 +476,7 @@ Consider[4] = function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -579,7 +574,7 @@ Consider[4] = function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -610,24 +605,33 @@ Consider[5]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) local creeps = npcBot:GetNearbyCreeps(1600,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) + + local damagePerSecond = ability:GetSpecialValueInt("damage") + local lingerTime = ability:GetSpecialValueInt("linger_duration") + local damageType = AbilityExtensions:HasScepter(npcBot) and DAMAGE_TYPE_PURE or DAMAGE_TYPE_MAGICAL + local pathRadius = ability:GetSpecialValueInt("path_radius") + + local function GetDamage(target) + local damageAtLeast = damagePerSecond * (lingerTime + AbilityExtensions:GetStunRemainingDuration(target) + pathRadius / target:GetCurrentMovementSpeed()) + return target:GetActualIncomingDamage(damageAtLeast, damageType) + end -------------------------------------- -- Global high-priorty usage -------------------------------------- --Try to kill enemy hero - if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) + if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) then if (WeakestEnemy~=nil) then if ( CanCast[abilityNumber]( WeakestEnemy ) ) then - if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) or (HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana)) + if HeroHealth<=GetDamage(WeakestEnemy) * (0.9+#allys*0.1) then local d=GetUnitToUnitDistance(npcBot,WeakestEnemy) if(d<=CastRange+Radius) @@ -669,13 +673,10 @@ end AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) function AbilityUsageThink() - - -- Check if we're already using an ability if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() ) - then + then return end - ComboMana=GetComboMana() AttackRange=npcBot:GetAttackRange() ManaPercentage=npcBot:GetMana()/npcBot:GetMaxMana() diff --git a/ability_item_usage_juggernaut.lua b/ability_item_usage_juggernaut.lua index 29e624d2..8fbce339 100644 --- a/ability_item_usage_juggernaut.lua +++ b/ability_item_usage_juggernaut.lua @@ -19,22 +19,22 @@ ability_item_usage_generic.InitAbility(Abilities,AbilitiesReal,Talents) local AbilityToLevelUp= { - Abilities[1], - Abilities[2], Abilities[1], Abilities[3], Abilities[1], - Abilities[5], + Abilities[2], Abilities[1], - Abilities[3], - Abilities[3], - "talent", - Abilities[3], Abilities[5], + Abilities[1], Abilities[2], Abilities[2], "talent", Abilities[2], + Abilities[5], + Abilities[3], + Abilities[3], + "talent", + Abilities[3], "nil", Abilities[5], "nil", diff --git a/ability_item_usage_keeper_of_the_light.lua b/ability_item_usage_keeper_of_the_light.lua index ed2a2e1e..d147d322 100644 --- a/ability_item_usage_keeper_of_the_light.lua +++ b/ability_item_usage_keeper_of_the_light.lua @@ -593,9 +593,9 @@ Consider[abilityIndex.keeper_of_the_light_blind_light] = function() then local npcEnemy = npcBot:GetTarget(); - if ( npcEnemy ~= nil and Enemys~=nil and #Enemys >= 2) + if ( npcEnemy ~= nil and enemys~=nil and #enemys >= 2) then - return BOT_ACTION_DESIRE_HIGH, locationAoE.targetloc + return BOT_ACTION_DESIRE_HIGH, npcEnemy:GetLocation() end end @@ -676,9 +676,9 @@ Consider[5] = function() then local npcEnemy = npcBot:GetTarget(); - if ( npcEnemy ~= nil and Enemys~=nil and #Enemys >= 2) + if ( npcEnemy ~= nil and enemys~=nil and #enemys >= 2) then - return BOT_ACTION_DESIRE_HIGH, locationAoE.targetloc + return BOT_ACTION_DESIRE_HIGH, npcEnemy:GetLocation() end end @@ -723,7 +723,7 @@ Consider[6]=function() -- If we're in a teamfight, use it local tableNearbyAttackingAlliedHeroes = npcBot:GetNearbyHeroes( 1000, false, BOT_MODE_ATTACK ) if #tableNearbyAttackingAlliedHeroes >= 2 then - local npcEnemy = npcBot:GetTarget() + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then return BOT_ACTION_DESIRE_HIGH diff --git a/ability_item_usage_kunkka.lua b/ability_item_usage_kunkka.lua index db716a3f..11a45a8b 100644 --- a/ability_item_usage_kunkka.lua +++ b/ability_item_usage_kunkka.lua @@ -99,9 +99,8 @@ local useTorrentAtXMark local useTorrentAtXMarkTime local function XMarksEnemy() if xMarkTarget ~= nil then - print(xMarkTarget:GetUnitName()) - print(AbilityExtensions:ToStringVector(xMarkLocation)) - AbilityExtensions:DebugTable(xMarkTarget) + -- print(xMarkTarget:GetUnitName()) + -- print(AbilityExtensions:ToStringVector(xMarkLocation)) end return xMarkTarget ~= nil and xMarkTarget:GetTeam() ~= npcBot:GetTeam() end @@ -122,8 +121,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius() local CastPoint = 2; - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -281,8 +279,7 @@ Consider[3]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -453,7 +450,7 @@ Consider[6]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -470,6 +467,30 @@ Consider[6]=function() return BOT_ACTION_DESIRE_NONE, 0; end +Consider[4] = function() + local ability = AbilitiesReal[4] + if not ability:IsFullyCastable() or ability:GetCurrentCharges() == 0 then + return 0 + end + local abilityLevel = ability:GetLevel() + local castRange = ability:GetCastRange() + 200 + local radius = ability:GetAOERadius() + local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, castRange + radius) + local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) + local targettableEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:NormalCanCast(t, false) and not AbilityExtensions:CannotBeAttacked(t) end) + local target = npcBot:GetTarget() + + if AbilityExtensions:GetEnemyHeroNumber(npcBot, enemies) >= 2 then + return RemapValClamped(AbilityExtensions:GetEnemyHeroNumber(npcBot, enemies), 2, 4, 0.3, 0.9) + end + if AbilityExtensions:Contains(targettableEnemies, target) then + return BOT_ACTION_DESIRE_MODERATE, true + end + return 0 +end + + + -- this initialisation doesn't work, because ability values cannot be queried before they are learned --local torrentDelay = AbilitiesReal[1]:GetSpecialValueFloat("delay") --local xMarksReturnCastPoint = AbilitiesReal[1]:GetCastPoint() @@ -489,8 +510,12 @@ Consider[7] = function() if XMarksEnemy() and npcBot:GetActiveMode() == BOT_MODE_RETREAT and (GetUnitToUnitDistance(npcBot, xMarkTarget) <= 300 or npcBot:WasRecentlyDamagedByHero(xMarkTarget, 1)) and DotaTime() > 1 + xMarkTime and GetUnitToLocationDistance(xMarkTarget, xMarkLocation) then return BOT_ACTION_DESIRE_HIGH end - if XMarksEnemy() and useTorrentAtXMarkTime and useTorrentAtXMarkTime >= DotaTime() - AbilitiesReal[1]:GetSpecialValueFloat("delay") + AbilitiesReal[7]:GetCastPoint() + 0.1 then - return BOT_ACTION_DESIRE_VERYHIGH + if XMarksEnemy() and useTorrentAtXMark then + local timing = useTorrentAtXMarkTime + AbilitiesReal[1]:GetSpecialValueFloat("delay") - ability:GetCastPoint() + print("Kunkka return: "..DotaTime().." "..timing) + if DotaTime() >= timing-0.1 and DotaTime() <= timing+AbilitiesReal[1]:GetAOERadius()/xMarkTarget:GetVelocity() then + return BOT_ACTION_DESIRE_VERYHIGH + end end end @@ -529,12 +554,12 @@ function AbilityUsageThink() xMarkTime = DotaTime()+AbilitiesReal[3]:GetCastPoint() xMarkLocation = target:GetLocation() if target:GetTeam() == npcBot:GetTeam() then - xMarkDuration = AbilitiesReal[3]:GetSpecialValueFloat("allied_duration") + xMarkDuration = AbilitiesReal[3]:GetSpecialValueFloat("allied_duration") or 8 else - xMarkDuration = AbilitiesReal[3]:GetSpecialValueFloat("duration") + xMarkDuration = AbilitiesReal[3]:GetSpecialValueFloat("duration") or 4 end - elseif index == 1 and xMarkTarget then + elseif index == 1 and xMarkTarget and GetUnitToLocationDistance(xMarkTarget, target) <= 180 then useTorrentAtXMark = true useTorrentAtXMarkTime = DotaTime()+AbilitiesReal[1]:GetCastPoint() end diff --git a/ability_item_usage_legion_commander.lua b/ability_item_usage_legion_commander.lua index 992b16cf..3abe5689 100644 --- a/ability_item_usage_legion_commander.lua +++ b/ability_item_usage_legion_commander.lua @@ -99,8 +99,7 @@ Consider[1]=function() local Damage = ability:GetLevel()*75 local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+150,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -218,9 +217,9 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( CastRange+300, false, BOT_MODE_NONE ); + allys = AbilityExtensions:Filter(npcBot, function(t) return not t:HasModifier("modifier_ice_blast") end) local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -242,7 +241,7 @@ Consider[2]=function() end if( npcBot:GetActiveMode() == BOT_MODE_ATTACK or - npcBot:GetActiveMode() == BOT_DEFEND_ALLY or + npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or ManaPercentage>0.4) then for _,npcTarget in pairs( allys ) @@ -261,7 +260,7 @@ Consider[2]=function() --Protect myself if ( (npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:WasRecentlyDamagedByAnyHero(2)) or HealthPercentage<=0.4+#enemys*0.05+0.2*ManaPercentage) then - if(#enemys>=1) + if(#enemys>=1) and not npcBot:HasModifier("modifier_ice_blast") then return BOT_ACTION_DESIRE_HIGH,npcBot; end @@ -351,8 +350,7 @@ Consider[4]=function() local CastRange = ability:GetCastRange(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( CastRange+300, false, BOT_MODE_NONE ); local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) @@ -387,7 +385,7 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then diff --git a/ability_item_usage_leshrac.lua b/ability_item_usage_leshrac.lua index e7e4dc11..3c5d11c4 100644 --- a/ability_item_usage_leshrac.lua +++ b/ability_item_usage_leshrac.lua @@ -73,7 +73,9 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} +local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.NCanCast,function(t) + return AbilityExtensions:NormalCanCast(t) +end} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -100,8 +102,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius() local CastPoint = ability:GetCastPoint()+ability:GetSpecialValueFloat( "delay" ); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -235,8 +236,7 @@ Consider[2]=function() local Radius = ability:GetAOERadius() local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes(Radius, false, BOT_MODE_NONE ); local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) @@ -346,8 +346,7 @@ Consider[3]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -478,8 +477,7 @@ Consider[5]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_lich.lua b/ability_item_usage_lich.lua index 44946ea3..fde51ed3 100644 --- a/ability_item_usage_lich.lua +++ b/ability_item_usage_lich.lua @@ -88,7 +88,7 @@ local activeModeDesire local caster = {Desire = {}, Target = {}, Type = {}} local consider = {} -local canCast = { +local CanCast = { AbilityHelper.normalCanCast, AbilityHelper.normalCanCast, AbilityHelper.normalCanCast, @@ -128,7 +128,7 @@ consider[1] = function() -------------------------------------- -- Try to kill enemy hero if (activeMode ~= BOT_MODE_RETREAT) then - if (weakestEnemy ~= nil and canCast[abilityIndex](weakestEnemy) and healthPercent > 0.4) then + if (weakestEnemy ~= nil and CanCast[abilityIndex](weakestEnemy) and healthPercent > 0.4) then local realDamage = weakestEnemy:GetActualIncomingDamage(damage, damageType) local realcomboDamage = weakestEnemy:GetActualIncomingDamage(comboDamage, damageType) if (heroHealth <= realDamage or (heroHealth <= realcomboDamage and npcBot:GetMana() > comboMana)) then @@ -143,7 +143,7 @@ consider[1] = function() local nearyByEnemys = npcBot:GetNearbyHeroes(const.WARNING_DISTANCE, true, BOT_MODE_NONE) if ((activeMode == BOT_MODE_RETREAT and activeModeDesire >= BOT_MODE_DESIRE_HIGH) or #nearyByEnemys > 0) then for _, npcEnemy in pairs(enemys) do - if (canCast[abilityIndex](npcEnemy)) then + if (CanCast[abilityIndex](npcEnemy)) then if (npcBot:WasRecentlyDamagedByHero(npcEnemy, 2.0) or GetUnitToUnitDistance(npcBot, npcEnemy) < const.WARNING_DISTANCE) then @@ -165,7 +165,7 @@ consider[1] = function() -- If my mana is enough, use it at enemy if (activeMode == BOT_MODE_LANING) then - if (weakestEnemy ~= nil and canCast[abilityIndex](weakestEnemy)) then + if (weakestEnemy ~= nil and CanCast[abilityIndex](weakestEnemy)) then if (isManaEnough and ability:GetLevel() >= 1) then return BOT_ACTION_DESIRE_LOW, weakestEnemy end @@ -174,7 +174,7 @@ consider[1] = function() -- Get last hit if (activeMode == BOT_MODE_LANING) then - if (weakestCreep ~= nil and canCast[abilityIndex](weakestCreep)) then + if (weakestCreep ~= nil and CanCast[abilityIndex](weakestCreep)) then if (isManaEnough and GetUnitToUnitDistance(npcBot, weakestCreep) >= attackRange + 100) then if (creepHealth <= weakestCreep:GetActualIncomingDamage(damage, damageType)) then return BOT_ACTION_DESIRE_LOW, weakestCreep @@ -185,7 +185,7 @@ consider[1] = function() -- If we're farming if (activeMode == BOT_MODE_FARM) then - if (#creeps >= 2 and canCast[abilityIndex](weakestCreep)) then + if (#creeps >= 2 and CanCast[abilityIndex](weakestCreep)) then if (isManaEnough and creepHealth <= weakestCreep:GetActualIncomingDamage(damage, damageType)) then return BOT_ACTION_DESIRE_LOW, weakestCreep end @@ -202,7 +202,7 @@ consider[1] = function() then if (isManaEnough and abilityHandles[abilityIndex]:GetLevel() >= 1) then if (#enemys >= 1) then - if (canCast[abilityIndex](weakestEnemy)) then + if (CanCast[abilityIndex](weakestEnemy)) then if (GetUnitToUnitDistance(npcBot, weakestEnemy) < castRange + 75 * #allys) then return BOT_ACTION_DESIRE_LOW, weakestEnemy end @@ -210,7 +210,7 @@ consider[1] = function() end for _, creep in pairs(creeps) do - if (canCast[abilityIndex](creep) and GetUnitToUnitDistance(npcBot, creep) < castRange + 75 * #allys) then + if (CanCast[abilityIndex](creep) and GetUnitToUnitDistance(npcBot, creep) < castRange + 75 * #allys) then return BOT_ACTION_DESIRE_LOW, creep end end @@ -225,7 +225,7 @@ consider[1] = function() then local npcEnemy = npcBot:GetTarget() - if (AbilityHelper.isValidTarget(npcEnemy) and canCast[abilityIndex](npcEnemy)) then + if (AbilityHelper.isValidTarget(npcEnemy) and CanCast[abilityIndex](npcEnemy)) then if (GetUnitToUnitDistance(npcBot, npcEnemy) < castRange + 75 * #allys) then return BOT_ACTION_DESIRE_MODERATE, npcEnemy end @@ -284,7 +284,7 @@ consider[2] = function() npcTarget:WasRecentlyDamagedByAnyHero(5.0) or #allyNeaybyEnemys >= 2) then - if (canCast[abilityIndex](npcTarget)) then + if (CanCast[abilityIndex](npcTarget)) then return BOT_ACTION_DESIRE_MODERATE, npcTarget end end @@ -302,24 +302,24 @@ consider[2] = function() end -- Attack roshan - if (npcBot:GetActiveMode() == BOT_MODE_ROSHAN) then - local npcTarget - for _, creep in pairs(creeps) do - if (AbilityHelper.isRoshan(creep)) then - npcTarget = creep - break - end - end - - local roshanTarget = npcTarget:GetAttackTarget() - if (isManaEnough and AbilityHelper.isValidTarget(roshanTarget)) then - return BOT_ACTION_DESIRE_HIGH, roshanTarget - end - end + --if (npcBot:GetActiveMode() == BOT_MODE_ROSHAN) then + -- local npcTarget + -- for _, creep in pairs(creeps) do + -- if (AbilityHelper.isRoshan(creep)) then + -- npcTarget = creep + -- break + -- end + -- end + -- + -- local roshanTarget = npcTarget:GetAttackTarget() + -- if (isManaEnough and AbilityHelper.isValidTarget(roshanTarget)) then + -- return BOT_ACTION_DESIRE_HIGH, roshanTarget + -- end + --end -- If we're farming if (activeMode == BOT_MODE_FARM) then - if (#creeps >= 2 and canCast[abilityIndex](weakestCreep)) then + if (#creeps >= 2 and CanCast[abilityIndex](weakestCreep)) then if (isManaEnough) then return BOT_ACTION_DESIRE_LOW, npcBot end @@ -338,7 +338,7 @@ consider[2] = function() local strongestAllyCreep = AbilityHelper.getStrongestUnit(allyCreeps) if (isManaEnough and abilityHandles[abilityIndex]:GetLevel() >= 1) then if (#allyCreeps >= 1) then - if (canCast[abilityIndex](strongestAllyCreep)) then + if (CanCast[abilityIndex](strongestAllyCreep)) then if (GetUnitToUnitDistance(npcBot, strongestAllyCreep) < castRange + 75 * #allys) then return BOT_ACTION_DESIRE_LOW, strongestAllyCreep end @@ -353,14 +353,14 @@ consider[2] = function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK) then - local npcEnemy = npcBot:GetTarget() + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if (AbilityHelper.isValidTarget(npcEnemy)) then local npcEnemyNearbyAllys = npcEnemy:GetNearbyHeroes(serachDistance, false, BOT_MODE_NONE) if (npcEnemyNearbyAllys ~= nil and #npcEnemyNearbyAllys >= 1) then for _, npcTarget in pairs(npcEnemyNearbyAllys) do if (GetUnitToUnitDistance(npcBot, npcTarget) <= castRange) then - return BOT_ACTION_DESIRE_MODERATE, npcTarget + return BOT_ACTION_DESIRE_MODERATE, npcBot end end end @@ -399,7 +399,7 @@ consider[3] = function() -------------------------------------- -- Check for a channeling enemy for _, npcEnemy in pairs(enemys) do - if (npcEnemy:IsChanneling() and canCast[abilityIndex](npcEnemy)) then + if (npcEnemy:IsChanneling() and CanCast[abilityIndex](npcEnemy)) then return BOT_ACTION_DESIRE_HIGH, npcEnemy end end @@ -411,7 +411,7 @@ consider[3] = function() local mostDangerousDamage = 0 for _, npcEnemy in pairs(enemys) do - if (canCast[abilityIndex](npcEnemy) and not isDisabled(npcEnemy)) then + if (CanCast[abilityIndex](npcEnemy) and not isDisabled(npcEnemy)) then local realDamage = npcEnemy:GetEstimatedDamageToTarget(false, npcBot, 3.0, DAMAGE_TYPE_ALL) if (realDamage > mostDangerousDamage) then mostDangerousDamage = realDamage @@ -431,7 +431,7 @@ consider[3] = function() local nearyByEnemys = npcBot:GetNearbyHeroes(const.WARNING_DISTANCE, true, BOT_MODE_NONE) if ((activeMode == BOT_MODE_RETREAT and activeModeDesire >= BOT_MODE_DESIRE_HIGH) or #nearyByEnemys > 0) then for _, npcEnemy in pairs(enemys) do - if (canCast[abilityIndex](npcEnemy) and not isDisabled(npcEnemy)) then + if (CanCast[abilityIndex](npcEnemy) and not isDisabled(npcEnemy)) then if (npcBot:WasRecentlyDamagedByHero(npcEnemy, 2.0) or GetUnitToUnitDistance(npcBot, npcEnemy) < const.WARNING_DISTANCE) then @@ -459,7 +459,7 @@ consider[3] = function() then local npcEnemy = npcBot:GetTarget() - if (AbilityHelper.isValidTarget(npcEnemy) and canCast[abilityIndex](npcEnemy) and not isDisabled(npcEnemy)) then + if (AbilityHelper.isValidTarget(npcEnemy) and CanCast[abilityIndex](npcEnemy) and not isDisabled(npcEnemy)) then if (GetUnitToUnitDistance(npcBot, npcEnemy) < castRange + 75 * #allys) then return BOT_ACTION_DESIRE_MODERATE, npcEnemy end @@ -573,7 +573,7 @@ consider[5] = function() local mostDangerousDamage = 0 for _, npcEnemy in pairs(enemys) do - if (canCast[abilityIndex](npcEnemy) and not isDisabled(npcEnemy)) then + if (CanCast[abilityIndex](npcEnemy) and not isDisabled(npcEnemy)) then local realDamage = npcEnemy:GetEstimatedDamageToTarget(false, npcBot, 3.0, DAMAGE_TYPE_ALL) if (realDamage > mostDangerousDamage) then mostDangerousDamage = realDamage @@ -593,7 +593,7 @@ consider[5] = function() local nearyByEnemys = npcBot:GetNearbyHeroes(const.WARNING_DISTANCE, true, BOT_MODE_NONE) if ((activeMode == BOT_MODE_RETREAT and activeModeDesire >= BOT_MODE_DESIRE_HIGH) or #nearyByEnemys > 0) then for _, npcEnemy in pairs(enemys) do - if (canCast[abilityIndex](npcEnemy) and not isDisabled(npcEnemy)) then + if (CanCast[abilityIndex](npcEnemy) and not isDisabled(npcEnemy)) then if (npcBot:WasRecentlyDamagedByHero(npcEnemy, 2.0) or GetUnitToUnitDistance(npcBot, npcEnemy) < const.WARNING_DISTANCE) then @@ -609,9 +609,9 @@ consider[5] = function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK) then - local npcEnemy = npcBot:GetTarget() + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) - if (AbilityHelper.isValidTarget(npcEnemy) and canCast[abilityIndex](npcEnemy) and not isDisabled(npcEnemy)) then + if (AbilityHelper.isValidTarget(npcEnemy) and CanCast[abilityIndex](npcEnemy) and not isDisabled(npcEnemy)) then if (GetUnitToUnitDistance(npcBot, npcEnemy) < castRange + 75 * #allys) then return BOT_ACTION_DESIRE_MODERATE, npcEnemy end diff --git a/ability_item_usage_life_stealer.lua b/ability_item_usage_life_stealer.lua index a3d1ba5f..7f757385 100644 --- a/ability_item_usage_life_stealer.lua +++ b/ability_item_usage_life_stealer.lua @@ -17,10 +17,6 @@ local AbilitiesReal ={} ability_item_usage_generic.InitAbility(Abilities,AbilitiesReal,Talents) --- utility.PrintAbilityName(Abilities) -local abilityName = { "life_stealer_rage", "life_stealer_feast", "life_stealer_ghoul_frenzy", "life_stealer_open_wounds", "life_stealer_infest", "life_stealer_consume" } -local abilityIndex = utility.ReverseTable(abilityName) - local AbilityToLevelUp= { @@ -78,7 +74,15 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.NCanCast} +local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast, +utility.NCanCast,function(t) + if npcBot:GetTeam() == t:GetTeam() then + return AbilityExtensions:SpellCanCast(t, true) + else + return AbilityExtensions:HasScepter(t) and AbilityExtensions:SpellCanCast(t) + end +end,utility.NCanCast, +utility.NCanCast,utility.NCanCast,utility.NCanCast} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -104,8 +108,7 @@ Consider[1]=function() local Damage = ability:GetAbilityDamage(); local CastPoint = ability:GetCastPoint(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+150,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -175,8 +178,7 @@ Consider[4]=function() local Damage = ability:GetAbilityDamage(); local CastPoint = ability:GetCastPoint(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -265,16 +267,6 @@ Consider[4]=function() end -function RemoveMyself(allys) - for _,hero in pairs (allys) - do - if (hero==npcBot) - then - table.remove(allys,_) - end - end -end - Consider[5]=function() local abilityNumber=5 @@ -283,7 +275,7 @@ Consider[5]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or AbilityExtensions:CannotMove(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end @@ -292,10 +284,9 @@ Consider[5]=function() local CastPoint = ability:GetCastPoint(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - RemoveMyself(allys) + allys = AbilityExtensions:Remove(allys, npcBot) local StrongestAlly,AllyHealth=utility.GetStrongestUnit(allys) local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -315,7 +306,7 @@ Consider[5]=function() if ( CanCast[abilityNumber]( WeakestEnemy ) ) then local allys2 = WeakestEnemy:GetNearbyHeroes( Radius-50, true, BOT_MODE_NONE ); - RemoveMyself(allys2) + allys2 = AbilityExtensions:Remove(allys2, npcBot) if(allys2~=nil and HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana) then return BOT_ACTION_DESIRE_HIGH,allys2[#allys2]; @@ -323,6 +314,18 @@ Consider[5]=function() end end end + + if AbilityExtensions:HasScepter(npcBot) and (AbilityExtensions:IsSeverelyDisabled(npcBot) or AbilityExtensions:GetHealthPercent(npcBot) <= 0.3) then + local enemies = npcBot:GetNearbyHeroes(CastRange,true,BOT_MODE_NONE) + enemies = AbilityExtensions:Filter(enemies, CanCast[5]) + local realEnemies = AbilityExtensions:Filter(npcBot, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) + if #realEnemies ~= 0 then + return BOT_ACTION_DESIRE_HIGH, AbilityExtensions:Max(realEnemies, function(t) return t:GetMaxHealth() * RemapValClamped(AbilityExtensions:GetHealthPercent(t), 0, 0.4, 2, 1) end) + end + if #enemies ~= 0 then + return BOT_ACTION_DESIRE_HIGH, AbilityExtensions:Max(enemies, function(t) return t:GetMaxHealth() * RemapValClamped(AbilityExtensions:GetHealthPercent(t), 0, 0.4, 2, 1) end) + end + end -------------------------------------- -- Mode based usage -------------------------------------- @@ -370,9 +373,7 @@ Consider[5]=function() end end end - - return BOT_ACTION_DESIRE_NONE, 0; - + return BOT_ACTION_DESIRE_NONE end Consider[7]=function() @@ -383,8 +384,8 @@ Consider[7]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if (not ability:IsFullyCastable() or ability:IsHidden()) then - return BOT_ACTION_DESIRE_NONE, 0; + if not ability:IsFullyCastable() or ability:IsHidden() then + return BOT_ACTION_DESIRE_NONE end local CastRange = ability:GetCastRange(); @@ -392,8 +393,7 @@ Consider[7]=function() local CastPoint = ability:GetCastPoint(); local Radius = 600 - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -416,46 +416,45 @@ Consider[7]=function() -- If we're going after someone if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or - npcBot:GetActiveMode() == BOT_MODE_GANK or npcBot:GetActiveMode() == BOT_MODE_ATTACK or npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY ) then local npcTarget = npcBot:GetTarget(); if ( npcTarget~= nil and GetUnitToUnitDistance( npcTarget, npcBot ) < Radius ) then - return BOT_ACTION_DESIRE_ABSOLUTE; + return BOT_ACTION_DESIRE_VERYHIGH end end - return BOT_ACTION_DESIRE_NONE; - + return BOT_ACTION_DESIRE_NONE end local lastInfestTime local lastInfestTarget -local lastInfestTable = {} + Consider[6] = function() local ability = AbilitiesReal[6] if not ability:IsFullyCastable() or ability:IsHidden() or lastInfestTarget == nil then return 0 end - if lastInfestTarget ~= nil and not lastInfestTarget:IsAlive() then + if lastInfestTarget ~= nil or not lastInfestTarget:IsAlive() or not npcBot:IsInvulnerable() then lastInfestTarget = nil lastInfestTime = nil end - local infest3 = AbilityExtensions:LastForAtLeastSeconds(function() return lastInfestTarget ~= nil end, 3, lastInfestTable) - local infest10 = AbilityExtensions:LastForAtLeastSeconds(function() return lastInfestTarget ~= nil end, 10, lastInfestTable) + local infestTime = DotaTime() - lastInfestTime + local infest3 = infestTime > 3 + local infest10 = infestTime > 10 local enemies = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, 1000, true) local friends = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, 1200, false) if AbilityExtensions:IsAttackingEnemies(npcBot) then local nearbyEnemies = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, ability:GetAOERadius(), true) - if #nearbyEnemies >= 3 or AbilityExtensions:IsSeverlyDisabled(lastInfestTarget) and #nearbyEnemies <= 2 then - return BOT_ACTION_DESIRE_MODERATE + if #nearbyEnemies >= 3 or npcBot:GetTeam() == lastInfestTarget:GetTeam() and AbilityExtensions:IsSeverelyDisabled(lastInfestTarget) and #nearbyEnemies <= 2 or #nearbyEnemies == 1 then + return BOT_ACTION_DESIRE_MODERATE + 0.1 end end - if infest3 and (#enemies == 0 or AbilityExtensions:Outnumber(friends, enemies)) then + if infest3 and (#enemies == 0 or AbilityExtensions:Outnumber(npcBot, friends, enemies)) then return BOT_ACTION_DESIRE_HIGH end if infest10 then diff --git a/ability_item_usage_lina.lua b/ability_item_usage_lina.lua index 5a059151..c9c9af5c 100644 --- a/ability_item_usage_lina.lua +++ b/ability_item_usage_lina.lua @@ -83,8 +83,12 @@ function GetComboMana() return ability_item_usage_generic.GetComboMana(AbilitiesReal) end -function CanCast4( npcTarget ) - return npcTarget:CanBeSeen() and npcTarget:IsHero() and ( GetBot():HasScepter() or not npcTarget:IsMagicImmune() ) and not npcTarget:IsInvulnerable(); +local function GetLagunaBladeDamageType() + return AbilityExtensions:HasScepter(npcBot) and DAMAGE_TYPE_PURE or DAMAGE_TYPE_MAGICAL +end +function CanCast4(t) + local hasShard = AbilityExtensions:HasShard(t) + return AbilityExtensions:NormalCanCast(t, false, GetLagunaBladeDamageType(), nil, not hasShard, not hasShard) end local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,CanCast4} @@ -102,8 +106,7 @@ Consider[1]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetSpecialValueInt( "dragon_slave_width_end" ); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+0,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -214,8 +217,7 @@ Consider[2]=function() local Radius = ability:GetSpecialValueInt( "light_strike_array_aoe" ); local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -344,8 +346,8 @@ end ---------------------------------------------------------------------------------------------------- -Consider[4]=function() +local function NormalLagnuaBladeConsider() local ability=AbilitiesReal[4]; if not ability:IsFullyCastable() then @@ -353,17 +355,12 @@ Consider[4]=function() end local CastRange = ability:GetCastRange(); - local Damage = ability:GetSpecialValueInt( "damage" ); - local Radius = ability:GetSpecialValueInt( "light_strike_array_aoe" ); - local DamageType = npcBot:HasScepter() and DAMAGE_TYPE_PURE or DAMAGE_TYPE_MAGICAL; - - local HeroHealth=10000 - local CreepHealth=10000 + local Damage = ability:GetAbilityDamage() + local DamageType = GetLagunaBladeDamageType() + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) - local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) --try to kill enemy hero if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) @@ -374,19 +371,19 @@ Consider[4]=function() then if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DamageType) or HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DamageType)) then - return BOT_ACTION_DESIRE_HIGH,WeakestEnemy; + return BOT_ACTION_DESIRE_HIGH, WeakestEnemy, "Target" end end end end -- If a mode has set a target, and we can kill them, do it - local npcTarget = npcBot:GetTarget(); + local npcTarget = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcTarget ~= nil and CanCast[4]( npcTarget ) ) then if ( npcTarget:GetActualIncomingDamage( Damage, DamageType ) > npcTarget:GetHealth() and GetUnitToUnitDistance( npcTarget, npcBot ) < ( CastRange + 200 ) ) then - return BOT_ACTION_DESIRE_HIGH, npcTarget; + return BOT_ACTION_DESIRE_HIGH, npcTarget, "Target" end end @@ -414,12 +411,57 @@ Consider[4]=function() if ( npcMostDangerousEnemy ~= nil ) then - return BOT_ACTION_DESIRE_HIGH, npcMostDangerousEnemy; + return BOT_ACTION_DESIRE_HIGH, npcMostDangerousEnemy, "Target" end end - return BOT_ACTION_DESIRE_NONE, 0; + return BOT_ACTION_DESIRE_NONE +end +local function TryUseShardLagunaAt(location, possibleEnemies) + local scepter_width = AbilitiesReal[4]:GetSpecialValueInt("scepter_width") + local line = AbilityExtensions:GetLine(npcBot:GetLocation(), location) + return AbilityExtensions:Count(possibleEnemies, function(t) + return CanCast[4](t) and AbilityExtensions:GetPointToLineDistance(t:GetLocation(), line) <= (AbilityExtensions:CannotMove() and scepter_width + t:GetBoundingRadius() or scepter_width * 0.75 + t:GetBoundingRadius()) + end) +end + +local ShardLagunaBlade = function() + local ability = AbilitiesReal[4] + if not ability:IsFullyCastable() then + return 0 + end + local castRange = ability:GetCastRange() + local enemies = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, castRange) + local oDesire, oTarget = NormalLagnuaBladeConsider() + local myLocation = npcBot:GetLocation() + local scepter_width = ability:GetSpecialValueInt("scepter_width") / 2 + local deltaDegree = scepter_width / castRange * 180 / math.pi -- at a low degree, tan(x) ~= x + if oDesire > 0 then + local enemyLocation = oTarget:GetLocation() + local distance = GetUnitToUnitDistance(npcBot, oTarget) + local degree1 = AbilityExtensions:GetDegree(enemyLocation, myLocation) + local degree2 = degree1 + deltaDegree + local degree3 = degree1 - deltaDegree + local degree = { degree1, degree2, degree3 } + local guess = AbilityExtensions:Map(degree, function(t) return { t, myLocation + Vector(distance*math.cos(t), distance*math.sin(t)) } end) + local count = AbilityExtensions:Map(guess, function(t) return { t[1], t[2], TryUseShardLagunaAt(t[3], enemies) } end) + count = AbilityExtensions:Max(count, function(t) return t[3] end) + if count[3] > 1 or AbilityExtensions:HasAbilityRetargetModifier(oTarget) or AbilityExtensions:CannotBeTargetted(oTarget) then + return oDesire, count[2], "Location" + else + return oDesire, oTarget, "Target" -- Why still use at target sometimes? Because laguna used at location can be dodged with forced movement! + end + end + return 0 +end + +Consider[4] = function() + if AbilityExtensions:HasShard(npcBot) then + return NormalLagnuaBladeConsider() + else + return ShardLagunaBlade() + end end AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) @@ -443,7 +485,9 @@ function AbilityUsageThink() then ability_item_usage_generic.PrintDebugInfo(AbilitiesReal,cast) end - ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + local a,b,c = ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + AbilityExtensions:RecordAbility(npcBot, a, b, c, AbilitiesReal) + end function CourierUsageThink() diff --git a/ability_item_usage_lion.lua b/ability_item_usage_lion.lua index f0ff844f..b50d4f4a 100644 --- a/ability_item_usage_lion.lua +++ b/ability_item_usage_lion.lua @@ -101,8 +101,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius() local CastPoint=ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -250,8 +249,7 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -348,8 +346,7 @@ Consider[3]=function() local Damage = ability:GetAbilityDamage(); local DrainMana=ability:GetSpecialValueFloat("duration")*ability:GetSpecialValueInt("mana_per_second") - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+150,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -434,8 +431,7 @@ Consider[4]=function() local Damage = ability:GetSpecialValueInt( "damage" ); local Radius = ability:GetSpecialValueInt( "light_strike_array_aoe" ); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -456,7 +452,7 @@ Consider[4]=function() end -- If a mode has set a target, and we can kill them, do it - local npcTarget = npcBot:GetTarget(); + local npcTarget = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcTarget ~= nil and CanCast[abilityNumber]( npcTarget ) ) then if ( npcTarget:GetActualIncomingDamage( Damage, DAMAGE_TYPE_MAGICAL ) > npcTarget:GetHealth() and GetUnitToUnitDistance( npcTarget, npcBot ) < ( CastRange + 200 ) ) diff --git a/ability_item_usage_luna.lua b/ability_item_usage_luna.lua index 80aa5a83..ac540f4b 100644 --- a/ability_item_usage_luna.lua +++ b/ability_item_usage_luna.lua @@ -97,8 +97,7 @@ Consider[1]=function() --Target Ability Example local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -214,13 +213,14 @@ Consider[4]=function() local Damage = 5*AbilitiesReal[1]:GetAbilityDamage() local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1600, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) local creeps = npcBot:GetNearbyCreeps(Radius,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) + local damage = AbilitiesReal[1]:GetAbilityDamage() + damage = damage * (1 + ability:GetSpecialValueInt("beams" + 1)) -------------------------------------- -- Global high-priorty usage -------------------------------------- @@ -256,16 +256,17 @@ Consider[4]=function() end -- If we're going after someone - if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or - npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or - npcBot:GetActiveMode() == BOT_MODE_ATTACK ) - then - local npcEnemy = npcBot:GetTarget(); - local creeps2 = npcAlly:GetNearbyCreeps(Radius,true) + if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or + npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or + npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or + npcBot:GetActiveMode() == BOT_MODE_ATTACK ) + then + local npcEnemy = npcBot:GetTarget(); + local creeps2 = npcBot:GetNearbyCreeps(Radius,true) + local incomingDamage = npcEnemy:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) if ( npcEnemy ~= nil and #creeps2<=1) then - if ( CanCast[abilityNumber]( npcEnemy ) and (npcEnemy:GetHealth()<=npcEnemy:GetActualIncomingDamage(npcBot:GetOffensivePower(),DAMAGE_TYPE_MAGICAL) or npcEnemy:GetHealth()<=Damage ) and GetUnitToUnitDistance(npcEnemy,npcBot)<=CastRange) + if not (npcEnemy:GetHealth() <= incomingDamage * 0.4 and #allys >= 2 ) and CanCast[abilityNumber]( npcEnemy ) and (npcEnemy:GetHealth()<=npcEnemy:GetActualIncomingDamage(damage,DAMAGE_TYPE_MAGICAL) or npcEnemy:GetHealth()<=Damage ) and GetUnitToUnitDistance(npcEnemy,npcBot)<=CastRange then return BOT_ACTION_DESIRE_MODERATE,npcEnemy:GetExtrapolatedLocation(0.5),"Location" end @@ -273,16 +274,17 @@ Consider[4]=function() end else - if ( npcBot:GetActiveMode() == BOT_MODE_ATTACK ) - then - if ( #enemys+disabledheronum-#creeps>=2) - then - if ( npcMostDangerousEnemy ~= nil ) - then - return BOT_ACTION_DESIRE_HIGH - end - end - end + -- npcMostDangerousEnemy is never assigned + -- if ( npcBot:GetActiveMode() == BOT_MODE_ATTACK ) + -- then + -- if ( #enemys+disabledheronum-#creeps>=2) + -- then + -- if ( npcMostDangerousEnemy ~= nil ) + -- then + -- return BOT_ACTION_DESIRE_HIGH + -- end + -- end + -- end -- If we're going after someone if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or @@ -290,9 +292,9 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) - if ( npcEnemy ~= nil and #creeps<=1) + if ( npcEnemy ~= nil and #creeps<=1) then if ( CanCast[abilityNumber]( npcEnemy ) and (npcEnemy:GetHealth()<=npcEnemy:GetActualIncomingDamage(npcBot:GetOffensivePower(),DAMAGE_TYPE_MAGICAL) or npcEnemy:GetHealth()<=Damage ) and GetUnitToUnitDistance(npcEnemy,npcBot)<=Radius) then diff --git a/ability_item_usage_lycan.lua b/ability_item_usage_lycan.lua index df2ec4d3..beae43d7 100644 --- a/ability_item_usage_lycan.lua +++ b/ability_item_usage_lycan.lua @@ -299,7 +299,7 @@ Consider[5]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -314,7 +314,7 @@ Consider[5]=function() local tableNearbyAttackingAlliedHeroes = npcBot:GetNearbyHeroes( 700, false, BOT_MODE_ATTACK ); if ( #tableNearbyAttackingAlliedHeroes >= 2 ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then diff --git a/ability_item_usage_magnataur.lua b/ability_item_usage_magnataur.lua index da8ddebc..4ed43629 100644 --- a/ability_item_usage_magnataur.lua +++ b/ability_item_usage_magnataur.lua @@ -73,7 +73,9 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} +local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,function(t) + return not AbilityExtensions:IsInvulnerable(t) +end} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -100,8 +102,7 @@ Consider[1]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+0,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -197,6 +198,9 @@ Consider[1]=function() end +CanCast[2] = function(t) + return not t:IsInvulnerable() and not AbilityExtensions:CannotBeTargetted(t) +end Consider[2]=function() local abilityNumber=2 @@ -222,10 +226,10 @@ Consider[2]=function() -- If we're pushing or defending a lane if ( npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_TOP or npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_BOTTOM or + npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_BOT or npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_TOP or npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_BOTTOM) + npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_BOT) then if(ManaPercentage>0.6) then @@ -269,7 +273,7 @@ Consider[3]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotMove(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end @@ -350,7 +354,7 @@ Consider[4] = function() -------------------------------------- local ability=AbilitiesReal[abilityNumber] - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or ability:IsHidden() then return BOT_ACTION_DESIRE_NONE, 0; end local radius = ability:GetSpecialValueInt("radius") @@ -361,6 +365,7 @@ Consider[4] = function() return GetUnitToLocationDistance(npcBot, loc) <= radius and npcBot:IsFacingLocation(loc, pullAngle) end local f = AbilityExtensions:Filter(AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, 500, true), CanToss) + f = AbilityExtensions:Filter(f, function(t) AbilityExtensions:NormalCanCast(t) end) f = AbilityExtensions:GetEnemyHeroNumber(f) if AbilityExtensions:NotRetreating(npcBot) and f >= 2 or f == 1 and #AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, 1200, true) == 1 then return BOT_MODE_DESIRE_HIGH @@ -371,6 +376,7 @@ Consider[4] = function() return GetUnitToLocationDistance(npcBot, loc) <= radius and not npcBot:IsFacingLocation(loc, 180-pullAngle) end f = AbilityExtensions:Filter(AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, 500, true), CanTossAfterTurnBack) + f = AbilityExtensions:Filter(f, function(t) AbilityExtensions:NormalCanCast(t) end) f = AbilityExtensions:GetEnemyHeroNumber(f) if AbilityExtensions:NotRetreating(npcBot) and f >= 1 then npcBot:Action_MoveDirectly(utility.GetUnitsTowardsLocation(npcBot, f[1]:GetLocation(), 10)) @@ -397,12 +403,7 @@ Consider[5]=function() local Radius = ability:GetAOERadius()-50 local CastPoint = ability:GetCastPoint() - local i=npcBot:FindItemSlot("item_blink") - if(i>=0 and i<=5) - then - blink=npcBot:GetItemInSlot(i) - i=nil - end + local blink = AbilityExtensions:GetAvailableBlink(npcBot) if(blink~=nil and blink:IsFullyCastable()) then CastRange=CastRange+1200 @@ -416,9 +417,7 @@ Consider[5]=function() end end end - - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -471,7 +470,7 @@ Consider[5]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -494,14 +493,26 @@ Consider[5]=function() end AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) + +local abilityUsedInfo = {} + function AbilityUsageThink() -- Check if we're already using an ability - if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() ) - then + if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() )then + if npcBot:IsCastingAbility() then + if npcBot:GetCurrentActiveAbility() == AbilitiesReal[5] then + local radius = AbilitiesReal[5]:GetAOERadius() + if AbilityExtensions:Count(AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, radius), CanCast[5]) == 0 then + print("Magnataur: cancel ultimate") + npcBot:Action_ClearActions(true) + end + end + end return end - + abilityUsedInfo.index = nil + ComboMana=GetComboMana() AttackRange=npcBot:GetAttackRange() ManaPercentage=npcBot:GetMana()/npcBot:GetMaxMana() @@ -513,7 +524,10 @@ function AbilityUsageThink() then ability_item_usage_generic.PrintDebugInfo(AbilitiesReal,cast) end - ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + local usedAbilityIndex, target, castType = ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + if usedAbilityIndex ~= nil then + abilityUsedInfo.index = usedAbilityIndex + end end function CourierUsageThink() diff --git a/ability_item_usage_medusa.lua b/ability_item_usage_medusa.lua index 64553713..1db7d5a5 100644 --- a/ability_item_usage_medusa.lua +++ b/ability_item_usage_medusa.lua @@ -310,7 +310,7 @@ Consider[5]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then diff --git a/ability_item_usage_mirana.lua b/ability_item_usage_mirana.lua index 3f8e82ae..7bfbae72 100644 --- a/ability_item_usage_mirana.lua +++ b/ability_item_usage_mirana.lua @@ -276,7 +276,7 @@ Consider[3]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotMove(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end @@ -298,7 +298,7 @@ Consider[3]=function() local ancient = GetAncient(GetTeam()); if ( npcBot:WasRecentlyDamagedByAnyHero( 2.0 ) and npcBot:IsFacingLocation(ancient:GetLocation(),10)) then - return BOT_ACTION_DESIRE_HIGH, npcEnemy; + return BOT_ACTION_DESIRE_HIGH end end @@ -318,13 +318,13 @@ Consider[3]=function() local tableNearbyEnemyHeroes = npcEnemy:GetNearbyHeroes( 1000, false, BOT_MODE_NONE ); if ( tableNearbyEnemyHeroes ~= nil and #tableNearbyEnemyHeroes <= 2 ) then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy + return BOT_ACTION_DESIRE_MODERATE end end end end - return BOT_ACTION_DESIRE_NONE, 0; + return BOT_ACTION_DESIRE_NONE end diff --git a/ability_item_usage_monkey_king.lua b/ability_item_usage_monkey_king.lua index 7238fbed..d0d6b358 100644 --- a/ability_item_usage_monkey_king.lua +++ b/ability_item_usage_monkey_king.lua @@ -508,8 +508,7 @@ Consider[6]=function() local Radius = ability:GetAOERadius()-50; local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_naga_siren.lua b/ability_item_usage_naga_siren.lua index 12a41e01..97b73128 100644 --- a/ability_item_usage_naga_siren.lua +++ b/ability_item_usage_naga_siren.lua @@ -73,7 +73,7 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} +local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.NCanCast} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -148,15 +148,14 @@ Consider[2]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotMove(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -270,8 +269,7 @@ Consider[4]=function() local Radius = ability:GetAOERadius() local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -308,6 +306,29 @@ Consider[4]=function() end +Consider[5] = function() + local abilityNumber=5 + -------------------------------------- + -- Generic Variable Setting + -------------------------------------- + local ability=AbilitiesReal[abilityNumber] + + if not ability:IsFullyCastable() or ability:IsHidden() then + return BOT_ACTION_DESIRE_NONE + end + local Radius = ability:GetAOERadius() + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ) + local enemys = npcBot:GetNearbyHeroes(1500,true,BOT_MODE_NONE) + if --AbilityExtensions:Outnumber(npcBot, allys, enemys) and + HealthPercentage>=0.5 and not npcBot:WasRecentlyDamagedByAnyHero(1.5) then + return BOT_ACTION_DESIRE_HIGH + end + if #enemys == 0 and not npcBot:WasRecentlyDamagedByAnyHero(1.5) then + return BOT_ACTION_DESIRE_HIGH + end + return 0 +end + AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) function AbilityUsageThink() diff --git a/ability_item_usage_necrolyte.lua b/ability_item_usage_necrolyte.lua index f757718c..18844a35 100644 --- a/ability_item_usage_necrolyte.lua +++ b/ability_item_usage_necrolyte.lua @@ -100,8 +100,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius() local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes(Radius, false, BOT_MODE_NONE ); local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) @@ -240,8 +239,7 @@ Consider[2]=function() local Damage = 0 local Radius = 750 - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -303,8 +301,7 @@ Consider[5]=function() local CastRange = ability:GetCastRange(); local DamagePercent = ability:GetSpecialValueFloat("damage_per_health") - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_night_stalker.lua b/ability_item_usage_night_stalker.lua index c0a9ca0c..8907299c 100644 --- a/ability_item_usage_night_stalker.lua +++ b/ability_item_usage_night_stalker.lua @@ -264,7 +264,7 @@ Consider[2]=function() --Target AOE Ability Example npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -303,11 +303,11 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then - if ( CanCast[abilityNumber]( npcEnemy )) + if ( CanCast[abilityNumber]( npcEnemy )) and GetUnitToUnitDistance(npcBot, npcEnemy) <= 1800 then return BOT_ACTION_DESIRE_MODERATE end diff --git a/ability_item_usage_nyx_assassin.lua b/ability_item_usage_nyx_assassin.lua index 6b19681b..e1e86a0b 100644 --- a/ability_item_usage_nyx_assassin.lua +++ b/ability_item_usage_nyx_assassin.lua @@ -186,7 +186,7 @@ Consider[1]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -212,8 +212,7 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -259,7 +258,7 @@ Consider[2]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcTarget = npcBot:GetTarget(); + local npcTarget = AbilityExtensions:GetTargetIfGood(npcBot) if(ManaPercentage>0.4 or npcBot:GetMana()>ComboMana) then @@ -393,7 +392,7 @@ Consider[5]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then if (GetUnitToUnitDistance(npcBot,npcEnemy)<=2000) diff --git a/ability_item_usage_obsidian_destroyer.lua b/ability_item_usage_obsidian_destroyer.lua index 115f6c4b..963fc02b 100644 --- a/ability_item_usage_obsidian_destroyer.lua +++ b/ability_item_usage_obsidian_destroyer.lua @@ -16,7 +16,7 @@ local Talents ={} local Abilities ={} local AbilitiesReal ={} -ability_item_usage_generic.InitAbility(Abilities,AbilitiesReal,Talents) +ability_item_usage_generic.InitAbility(Abilities,AbilitiesReal,Talents) local AbilityToLevelUp= { @@ -73,7 +73,16 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} +local CanCast={AbilityExtensions.PhysicalCanCastFunction,function(t) + if npcBot:GetTeam() == t:GetTeam() then + return AbilityExtensions:SpellCanCast(t, true, true, true) and not AbilityExtensions:DontInterruptAlly(t) and not t:IsMagicImmune() + else + return AbilityExtensions:NormalCanCast(t, false, DAMAGE_TYPE_MAGICAL) and not t:HasModifier("modifier_antimage_counterspell") + end +end,utility.NCanCast, +function(t) + return t:HasModifier("modifier_obsidian_destroyer_astral_imprisonment_prison") or AbilityExtensions:NormalCanCast(t) +end} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -98,8 +107,7 @@ Consider[1]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetSpecialValueInt("damage_bonus")+npcBot:GetAttackDamage() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+100,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -191,43 +199,19 @@ local dazzle_shadow_grave = function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local allys = npcBot:GetNearbyHeroes( CastRange+300, false, BOT_MODE_NONE ); - local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) - local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) - local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) - local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - -------------------------------------- - -- Global high-priorty usage - -------------------------------------- - -- If we're seriously retreating - if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) - then - if(HealthPercentage<=0.3) - then - return BOT_ACTION_DESIRE_VERYHIGH, npcBot - end - end + local allys = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, CastRange+300, false) + local enemys2 = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, 1000) + local enemyCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, enemys2) - --protect teammate,save allys from control for _,npcTarget in pairs( allys ) do - local enemys2 = npcTarget:GetNearbyHeroes(600,true,BOT_MODE_NONE) - if not npcTarget:IsIllusion() and (npcTarget:GetHealth()/npcTarget:GetMaxHealth()<=0.2+0.05*#enemys2) and npcTarget:WasRecentlyDamagedByAnyHero(3) + if (npcTarget:GetHealth()/npcTarget:GetMaxHealth()<=0.2+0.05*enemyCount) and AbilityExtensions:IsOrGoingToBeSeverelyDisabled(npcTarget) and CanCast[2](npcTarget) then - local Damage2=0 - for _,npcEnemy in pairs( enemys2 ) - do - Damage2 =Damage2 + npcEnemy:GetEstimatedDamageToTarget( true, npcBot, 2.0, DAMAGE_TYPE_ALL ); - end - if not npcTarget:IsIllusion() and (npcTarget:GetHealth() nMostDangerousDamage ) @@ -285,12 +269,23 @@ local oldConsider2 = function() end end - if ( npcMostDangerousEnemy ~= nil and not enemyDisabled(npcMostDangerousEnemy)) + if ( npcMostDangerousEnemy ~= nil and not AbilityExtensions:IsOrGoingToBeSeverelyDisabled(npcMostDangerousEnemy)) then return BOT_ACTION_DESIRE_LOW, npcMostDangerousEnemy; end end - + + local enemys2 = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, 1000) + local enemyCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, enemys2) + + for _,npcTarget in pairs( allys ) + do + if (npcTarget:GetHealth()/npcTarget:GetMaxHealth()<=0.2+0.05*enemyCount) and AbilityExtensions:IsOrGoingToBeSeverelyDisabled(npcTarget) and CanCast[2](npcTarget) + then + return BOT_ACTION_DESIRE_MODERATE, npcTarget + end + end + --try to kill enemy hero if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) then @@ -298,7 +293,7 @@ local oldConsider2 = function() then if ( CanCast[abilityNumber]( WeakestEnemy ) ) then - if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL)- 100 and #allys <= 1 and not enemyDisabled(WeakestEnemy)) + if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) and #allys <= 1 and not AbilityExtensions:IsOrGoingToBeSeverelyDisabled(WeakestEnemy)) then return BOT_ACTION_DESIRE_HIGH,WeakestEnemy; end @@ -317,7 +312,7 @@ local oldConsider2 = function() do if ( npcBot:WasRecentlyDamagedByHero( npcEnemy, 2.0 ) ) then - if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy)) + if ( CanCast[abilityNumber]( npcEnemy ) and not AbilityExtensions:IsOrGoingToBeSeverelyDisabled(npcEnemy)) then return BOT_ACTION_DESIRE_HIGH, npcEnemy; end @@ -325,14 +320,13 @@ local oldConsider2 = function() end end - --消耗 if ( npcBot:GetActiveMode() == BOT_MODE_LANING ) then if(ManaPercentage>0.4 or npcBot:GetMana()>ComboMana) then if (WeakestEnemy~=nil) then - if ( CanCast[abilityNumber]( WeakestEnemy ) and GetUnitToUnitDistance(npcBot,WeakestEnemy)< CastRange+200) + if ( CanCast[abilityNumber]( WeakestEnemy ) and GetUnitToUnitDistance(npcBot,WeakestEnemy)< CastRange+200 and not AbilityExtensions:IsOrGoingToBeSeverelyDisabled(WeakestEnemy)) then return BOT_ACTION_DESIRE_LOW,WeakestEnemy end @@ -350,7 +344,7 @@ local oldConsider2 = function() if ( npcTarget ~= nil ) then - if ( CanCast[abilityNumber]( npcTarget ) and not enemyDisabled(npcTarget) and GetUnitToUnitDistance(npcBot,npcTarget) > 75 * #allys + if ( CanCast[abilityNumber]( npcTarget ) and not AbilityExtensions:IsOrGoingToBeSeverelyDisabled(npcTarget) and GetUnitToUnitDistance(npcBot,npcTarget) > 75 * #allys and GetUnitToUnitDistance(npcBot,npcTarget) < CastRange + 100) then return BOT_ACTION_DESIRE_MODERATE, npcTarget @@ -370,27 +364,6 @@ local oldConsider2 = function() end end - -- If we're going after someone - if ( npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_TOP or - npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_BOT or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_TOP or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_BOT) - then - for _,npcTarget in pairs( allys ) - do - if(npcTarget:GetHealth()/npcTarget:GetMaxHealth()<0.2 and #enemys >= 2) - then - if ( CanCast[abilityNumber]( npcTarget ) and not enemyDisabled(npcTarget)) - then - return BOT_ACTION_DESIRE_MODERATE, npcTarget - end - end - end - end - - return BOT_ACTION_DESIRE_NONE, 0 end @@ -464,7 +437,7 @@ Consider[4]=function() local CastPoint = ability:GetCastPoint(); local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) + local enemys = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) @@ -512,8 +485,6 @@ end AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) - -AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) function AbilityUsageThink() -- Check if we're already using an ability diff --git a/ability_item_usage_ogre_magi.lua b/ability_item_usage_ogre_magi.lua index 6d3cfd86..cbc91c57 100644 --- a/ability_item_usage_ogre_magi.lua +++ b/ability_item_usage_ogre_magi.lua @@ -17,10 +17,6 @@ local AbilitiesReal ={} ability_item_usage_generic.InitAbility(Abilities,AbilitiesReal,Talents) --- utility.PrintAbilityName(Abilities) -local abilityName = { "ogre_magi_fireblast", "ogre_magi_ignite", "ogre_magi_bloodlust", "ogre_magi_unrefined_fireblast", "ogre_magi_smash", "ogre_magi_multicast" } -local abilityIndex = utility.ReverseTable(abilityName) - local AbilityToLevelUp= { @@ -100,8 +96,7 @@ Consider[1]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -224,8 +219,7 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = (18+8*ability:GetLevel())*(4+ability:GetLevel()); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -346,8 +340,7 @@ Consider[3]=function() local CastRange = ability:GetCastRange(); local Damage = 0 - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -415,8 +408,7 @@ Consider[4]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_omniknight.lua b/ability_item_usage_omniknight.lua index 0de6408c..5c087004 100644 --- a/ability_item_usage_omniknight.lua +++ b/ability_item_usage_omniknight.lua @@ -190,6 +190,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius(); local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); + allys = AbilityExtensions:Filter(npcBot, function(t) return not t:HasModifier("modifier_ice_blast") end) local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) @@ -224,7 +225,7 @@ Consider[1]=function() -- If we're seriously retreating if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) then - if ( npcBot:WasRecentlyDamagedByAnyHero( 2.0 ) and (#enemys3>=1 or #enemys==0) or HealthPercentage<=0.2) + if ( npcBot:WasRecentlyDamagedByAnyHero( 2.0 ) and (#enemys3>=1 or #enemys==0) or HealthPercentage<=0.2) and not npcBot:HasModifier("modifier_ice_blast") then return BOT_ACTION_DESIRE_HIGH+0.08,npcBot; end @@ -234,7 +235,7 @@ Consider[1]=function() if( true ) then local HighestFactor,TempTarget=GetTargetFactor() - if(HighestFactor>0 and TempTarget~=nil) + if(HighestFactor>0 and TempTarget~=nil and not TempTarget:HasModifier("modifier_ice_blast")) then return BOT_ACTION_DESIRE_MODERATE-0.01, TempTarget end @@ -309,7 +310,7 @@ Consider[2]=function() local CastPoint = ability:GetCastPoint(); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) - local allys = npcBot:GetNearbyHeroes( CastRange+300, false, BOT_MODE_ATTACK ); + local allys = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, CastRange+300, false, BOT_MODE_ATTACK ); -------------------------------------- -- Global high-priorty usage -------------------------------------- @@ -333,7 +334,7 @@ Consider[2]=function() npcTarget:WasRecentlyDamagedByAnyHero(5.0) or #allyNeaybyEnemys >= 2) then - if (CanCast[abilityIndex](npcTarget)) then + if (CanCast[abilityNumber](npcTarget)) then return BOT_ACTION_DESIRE_MODERATE, npcTarget end end @@ -379,7 +380,8 @@ Consider[2]=function() end Consider[4] = function() - local ability = AbilitiesReal[4] + local abilityNumber = 4 + local ability = AbilitiesReal[abilityNumber] if not ability:IsFullyCastable() or AbilityExtensions:IsPhysicalOutputDisabled(npcBot) then return 0 end @@ -441,8 +443,7 @@ Consider[5]=function() local Damage = 0 local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( math.max(Radius,1600), false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_phantom_assassin.lua b/ability_item_usage_phantom_assassin.lua index cdaba6d6..ad303da0 100644 --- a/ability_item_usage_phantom_assassin.lua +++ b/ability_item_usage_phantom_assassin.lua @@ -72,7 +72,13 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.CanCastNoTarget,utility.CanCastPassive} +local CanCast={function(t) + return AbilityExtensions:NormalCanCast(t, false, DAMAGE_TYPE_PHYSICAL, true, true, true) and not AbilityExtensions:HasAbilityRetargetModifier(npcBot) +end,function(t) + return AbilityExtensions:SpellCanCast(t, true, true, true) and not AbilityExtensions:HasAbilityRetargetModifier(npcBot) +end,utility.NCanCast,function(t) + return AbilityExtensions:NormalCanCast(t, false, DAMAGE_TYPE_PHYSICAL, true, false, false) +end,utility.CanCastPassive} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -230,15 +236,13 @@ Consider[2]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or AbilityExtensions:CannotTeleport(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end local CastRange = ability:GetCastRange(); local Damage = 0 - local HeroHealth=10000 - local CreepHealth=10000 local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -269,11 +273,11 @@ Consider[2]=function() local npcEnemy for _,tempEnemy in pairs( allys ) do - tempdistance=tempEnemy:DistanceFromFountain() - if (tempdistance= BOT_MODE_DESIRE_MODERATE)) then - if (#enemys==0) + if (#realEnemiesNearby==0) then return BOT_ACTION_DESIRE_HIGH end end + if AbilityExtensions:HasScepter(npcBot) then + if AbilityExtensions:GetALlyDispellWorthModifiers(npcBot) then + return BOT_ACTION_DESIRE_HIGH + end + end + -- If we're going after someone if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or diff --git a/ability_item_usage_phantom_lancer.lua b/ability_item_usage_phantom_lancer.lua index 1af877a8..bdae8e4c 100644 --- a/ability_item_usage_phantom_lancer.lua +++ b/ability_item_usage_phantom_lancer.lua @@ -99,8 +99,7 @@ Consider[1]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -182,14 +181,13 @@ Consider[2]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or AbilityExtensions:CannotTeleport(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end local CastRange = ability:GetCastRange(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_puck.lua b/ability_item_usage_puck.lua index 0910bcb4..4a9886b5 100644 --- a/ability_item_usage_puck.lua +++ b/ability_item_usage_puck.lua @@ -1,34 +1,33 @@ -local utility = require( GetScriptDirectory().."/utility" ) -require(GetScriptDirectory() .. "/ability_item_usage_generic") +-- v1.7 template by AaronSong321 +local utility = require(GetScriptDirectory().."/utility") +local ability_item_usage_generic = require(GetScriptDirectory() .. "/ability_item_usage_generic") local AbilityExtensions = require(GetScriptDirectory().."/util/AbilityAbstraction") -local debugmode=false local npcBot = GetBot() -local Talents ={} -local Abilities ={} -local AbilitiesReal ={} - -ability_item_usage_generic.InitAbility(Abilities,AbilitiesReal,Talents) +if npcBot:IsIllusion() then + return +end +local AbilityNames, Abilities, Talents = AbilityExtensions:InitAbility() local AbilityToLevelUp = { - Abilities[1], - Abilities[3], - Abilities[3], - Abilities[2], - Abilities[3], - Abilities[4], - Abilities[3], - Abilities[2], - Abilities[2], + AbilityNames[1], + AbilityNames[3], + AbilityNames[1], + AbilityNames[2], + AbilityNames[1], + AbilityNames[5], + AbilityNames[1], + AbilityNames[3], + AbilityNames[2], "talent", - Abilities[2], - Abilities[4], - Abilities[1], - Abilities[1], + AbilityNames[2], + AbilityNames[5], + AbilityNames[2], + AbilityNames[3], "talent", - Abilities[1], + AbilityNames[3], "nil", - Abilities[4], + AbilityNames[5], "nil", "talent", "nil", @@ -39,85 +38,237 @@ local AbilityToLevelUp = { } local TalentTree = { - function() return Talents[1] end, - function() return Talents[3] end, - function() return Talents[6] end, - function() return Talents[7] end, - function() return Talents[2] end, - function() return Talents[4] end, - function() return Talents[5] end, - function() return Talents[8] end, + function() return Talents[2] end, + function() return Talents[3] end, + function() return Talents[6] end, + function() return Talents[8] end, } utility.CheckAbilityBuild(AbilityToLevelUp) function AbilityLevelUpThink() - ability_item_usage_generic.AbilityLevelUpThink2(AbilityToLevelUp,TalentTree) + ability_item_usage_generic.AbilityLevelUpThink2(AbilityToLevelUp, TalentTree) end - -------------------------------------- -- Ability Usage Thinking -------------------------------------- -local cast={} cast.Desire={} cast.Target={} cast.Type={} -local Consider ={} -local CanCast={utility.UCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} -local enemyDisabled=utility.enemyDisabled +local cast= {} cast.Desire= {} cast.Target= {} cast.Type= {} +local CanCast = {} +CanCast[1] = function(t) return AbilityExtensions:NormalCanCast(t, false) end +CanCast[2] = CanCast[1] +CanCast[3] = function(t) return not AbilityExtensions:IsInvulnerable(t) or not AbilityExtensions:ShouldNotBeAttacked(t) end +CanCast[4] = function() return true end +CanCast[5] = CanCast[1] + +local attackRange +local healthPercent +local mana +local manaPercent + +local illusoryOrbCastLocation +local illusoryOrbMaxTravelDistance + +local Consider = {} + +local function GetIllusoryOrb() + return AbilityExtensions:First(GetLinearProjectiles(), function(t) + return t.ability and t.ability:GetName() == "puck_illusory_orb" and t.caster == npcBot + end) +end +local illusoryOrb = GetIllusoryOrb() Consider[1] = function() - local ability = AbilitiesReal[1] - local enemies = npcBot:GetNearbyHeroes(1599, true, BOT_MODE_NONE) - local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(t) end) - local friends = npcBot:GetNearbyHeroes(1599, true, BOT_MODE_NONE) - local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, 900, true) + local ability = Abilities[1] + if not ability:IsFullyCastable() then + return 0 + end + local abilityLevel = ability:GetLevel() + local castRange = ability:GetCastRange() + local castPoint = ability:GetCastPoint() + local manaCost = ability:GetManaCost() + local duration = ability:GetDuration() + local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, 1599) + if #enemies > 0 then + enemies = AbilityExtensions:GetNearbyHeroes(npcBot, castRange) + end + local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) + local targettableEnemies = AbilityExtensions:Filter(realEnemies, function(t) return AbilityExtensions:NormalCanCast(t, true) end) + local friends = AbilityExtensions:GetNearbyHeroes(npcBot, 1200, true) + local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) + local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, castRange) + local friendCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, npcBot:GetAttackRange()+150, false) + local neutralCreeps = npcBot:GetNearbyNeutralCreeps(castRange) + local damage = ability:GetAbilityDamage() + local weakestEnemy, enemyHealth = utility.GetWeakestUnit(targettableEnemies) + local weakCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) return t:GetHealth() < t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) end) + local weakestCreep = utility.GetWeakestUnit(weakCreeps) + local tower = AbilityExtensions:GetLaningTower(npcBot) + local forbiddenCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) + return t:GetHealth() > t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) and (t:GetHealth() <= t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) + AbilityExtensions:AttackOnceDamage(npcBot, t) * (0.9+#enemyCreeps*0.1) or GetUnitToUnitDistance(tower, t) <= 700) + end) + if #friendCreeps == 0 then + forbiddenCreeps = {} + end + + if AbilityExtensions:IsFarmingOrPushing(npcBot) then + if #enemyCreeps > 3 and #forbiddenCreeps == 0 and manaPercent > 0.6 + manaCost then + return BOT_ACTION_DESIRE_MODERATE, enemyCreeps[2]:GetLocation() + end + elseif AbilityExtensions:IsRetreating(npcBot) then + + end +end + +Consider[2] = function() + local ability = Abilities[1] + if not ability:IsFullyCastable() or AbilityExtensions:CannotTeleport(npcBot) then + return 0 + end + local abilityLevel = ability:GetLevel() + local castRange = ability:GetCastRange() + local castPoint = ability:GetCastPoint() + local manaCost = ability:GetManaCost() + local duration = ability:GetDuration() + local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, castRange) + local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) + local targettableEnemies = AbilityExtensions:Filter(realEnemies, function(t) return AbilityExtensions:NormalCanCast(t, true) end) + local friends = AbilityExtensions:GetNearbyHeroes(npcBot, 1200, true) + local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) + local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, castRange) + local friendCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, npcBot:GetAttackRange()+150, false) + local neutralCreeps = npcBot:GetNearbyNeutralCreeps(castRange) local damage = ability:GetAbilityDamage() + local weakestEnemy, enemyHealth = utility.GetWeakestUnit(targettableEnemies) local weakCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) return t:GetHealth() < t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) end) + local weakestCreep = utility.GetWeakestUnit(weakCreeps) + local tower = AbilityExtensions:GetLaningTower(npcBot) + local forbiddenCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) + return t:GetHealth() > t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) and (t:GetHealth() <= t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) + AbilityExtensions:AttackOnceDamage(npcBot, t) * (0.9+#enemyCreeps*0.1) or GetUnitToUnitDistance(tower, t) <= 700) + end) + if #friendCreeps == 0 then + forbiddenCreeps = {} + end + + +end + +Consider[3] = function() + local ability = Abilities[1] if not ability:IsFullyCastable() then return 0 end + local abilityLevel = ability:GetLevel() + local castRange = ability:GetCastRange() + local castPoint = ability:GetCastPoint() + local manaCost = ability:GetManaCost() + local duration = ability:GetDuration() + local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, castRange) + local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) + local targettableEnemies = AbilityExtensions:Filter(realEnemies, function(t) return AbilityExtensions:NormalCanCast(t, true) end) + local friends = AbilityExtensions:GetNearbyHeroes(npcBot, 1200, true) + local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) + local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, castRange) + local friendCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, npcBot:GetAttackRange()+150, false) + local neutralCreeps = npcBot:GetNearbyNeutralCreeps(castRange) + local damage = ability:GetAbilityDamage() + local weakestEnemy, enemyHealth = utility.GetWeakestUnit(targettableEnemies) + local weakCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) return t:GetHealth() < t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) end) + local weakestCreep = utility.GetWeakestUnit(weakCreeps) + local tower = AbilityExtensions:GetLaningTower(npcBot) + local forbiddenCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) + return t:GetHealth() > t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) and (t:GetHealth() <= t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) + AbilityExtensions:AttackOnceDamage(npcBot, t) * (0.9+#enemyCreeps*0.1) or GetUnitToUnitDistance(tower, t) <= 700) + end) + if #friendCreeps == 0 then + forbiddenCreeps = {} + end - local distance = 1500 - local orbSpeed = 1500 - local radius = 150 - local function TryUseAt(location) - local botLocation = npcBot:GetLocation() - -- local +end + +Consider[4] = function() + local ability = Abilities[1] + if not ability:IsFullyCastable() or AbilityExtensions:CannotTeleport(npcBot) then + return 0 + end + local abilityLevel = ability:GetLevel() + local castRange = ability:GetCastRange() + local castPoint = ability:GetCastPoint() + local manaCost = ability:GetManaCost() + local duration = ability:GetDuration() + local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, castRange) + local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) + local targettableEnemies = AbilityExtensions:Filter(realEnemies, function(t) return AbilityExtensions:NormalCanCast(t, true) end) + local friends = AbilityExtensions:GetNearbyHeroes(npcBot, 1200, true) + local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) + local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, castRange) + local friendCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, npcBot:GetAttackRange()+150, false) + local neutralCreeps = npcBot:GetNearbyNeutralCreeps(castRange) + local damage = ability:GetAbilityDamage() + local weakestEnemy, enemyHealth = utility.GetWeakestUnit(targettableEnemies) + local weakCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) return t:GetHealth() < t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) end) + local weakestCreep = utility.GetWeakestUnit(weakCreeps) + local tower = AbilityExtensions:GetLaningTower(npcBot) + local forbiddenCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) + return t:GetHealth() > t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) and (t:GetHealth() <= t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) + AbilityExtensions:AttackOnceDamage(npcBot, t) * (0.9+#enemyCreeps*0.1) or GetUnitToUnitDistance(tower, t) <= 700) + end) + if #friendCreeps == 0 then + forbiddenCreeps = {} end - if npcBot:GetActiveMode() == BOT_MODE_LANING then - if #realEnemies ~= 0 then - if #weakCreeps > 1 and ManaPercentage >= 0.4+ability:GetManaCost() and (HealthPercentage>=0.7 or HealthPercentage<=0.3) then - local rates = AbilityExtensions:Map(AbilityExtensions:Concat(weakCreeps, realEnemies), function(t) - -- local - end) - end - end + +end + +Consider[5] = function() + local ability = Abilities[1] + if not ability:IsFullyCastable() then + return 0 + end + local abilityLevel = ability:GetLevel() + local castRange = ability:GetCastRange() + local castPoint = ability:GetCastPoint() + local manaCost = ability:GetManaCost() + local duration = ability:GetDuration() + local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, castRange) + local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) + local targettableEnemies = AbilityExtensions:Filter(realEnemies, function(t) return AbilityExtensions:NormalCanCast(t, true) end) + local friends = AbilityExtensions:GetNearbyHeroes(npcBot, 1200, true) + local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) + local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, castRange) + local friendCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, npcBot:GetAttackRange()+150, false) + local neutralCreeps = npcBot:GetNearbyNeutralCreeps(castRange) + local damage = ability:GetAbilityDamage() + local weakestEnemy, enemyHealth = utility.GetWeakestUnit(targettableEnemies) + local weakCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) return t:GetHealth() < t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) end) + local weakestCreep = utility.GetWeakestUnit(weakCreeps) + local tower = AbilityExtensions:GetLaningTower(npcBot) + local forbiddenCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) + return t:GetHealth() > t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) and (t:GetHealth() <= t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) + AbilityExtensions:AttackOnceDamage(npcBot, t) * (0.9+#enemyCreeps*0.1) or GetUnitToUnitDistance(tower, t) <= 700) + end) + if #friendCreeps == 0 then + forbiddenCreeps = {} end - return 0 + + end -AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) -function AbilityUsageThink() +AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, Abilities) - -- Check if we're already using an ability - if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() ) - then +function AbilityUsageThink() + if npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() then return end - - ComboMana=GetComboMana() - AttackRange=npcBot:GetAttackRange() - ManaPercentage=npcBot:GetMana()/npcBot:GetMaxMana() - HealthPercentage=npcBot:GetHealth()/npcBot:GetMaxHealth() - - cast=ability_item_usage_generic.ConsiderAbility(AbilitiesReal,Consider) - ---------------------------------debug-------------------------------------------- - if(debugmode==true) - then - ability_item_usage_generic.PrintDebugInfo(AbilitiesReal,cast) - end - ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + + attackRange = npcBot:GetAttackRange() + healthPercent = AbilityExtensions:GetHealthPercent(npcBot) + mana = npcBot:GetMana() + manaPercent = AbilityExtensions:GetManaPercent(npcBot) + cast=ability_item_usage_generic.ConsiderAbility(Abilities,Consider) + local abilityIndex, target, castType = ability_item_usage_generic.UseAbility(Abilities,cast) + if abilityIndex == 1 then + illusoryOrbCastLocation = npcBot:GetLocation() + illusoryOrbMaxTravelDistance = Abilities[1]:GetSpecialValueInt("max_distance") - 50 + end end function CourierUsageThink() diff --git a/ability_item_usage_pudge.lua b/ability_item_usage_pudge.lua index e22c6b6d..c5a68f88 100644 --- a/ability_item_usage_pudge.lua +++ b/ability_item_usage_pudge.lua @@ -2,9 +2,7 @@ -- Ranked Matchmaking AI v1.3 New Structure -- Author: adamqqq Email:adamqqq@163.com ---------------------------------------------------------------------------- --------------------------------------- --- General Initialization --------------------------------------- +-- v1.7 template local utility = require( GetScriptDirectory().."/utility" ) require(GetScriptDirectory() .. "/ability_item_usage_generic") local AbilityExtensions = require(GetScriptDirectory().."/util/AbilityAbstraction") @@ -73,15 +71,19 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} +local CanCast={function(t) + return AbilityExtensions:NormalCanCast(t, false, DAMAGE_TYPE_PURE, true, false) +end,utility.NCanCast,utility.NCanCast,utility.CanCastNoTarget,function(t) + return AbilityExtensions:NormalCanCast(t, false, DAMAGE_TYPE_MAGICAL, true, true) and not AbilityExtensions:HasAbilityRetargetModifier(t) +end} local enemyDisabled=utility.enemyDisabled Consider[1] = function() local ability = AbilitiesReal[1] - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or npcBot:IsChanneling() then return 0 end - local castPoint = 0.3 + local castPoint = ability:GetCastPoint() local range = ability:GetSpecialValueInt("hook_distance") local searchRadius = ability:GetSpecialValueInt("hook_width") local hookSpeed = ability:GetSpecialValueFloat("hook_speed") @@ -89,7 +91,7 @@ Consider[1] = function() local function NotBlockedByAnyUnit(line, target, distance) return AbilityExtensions:All(AbilityExtensions:Remove(allNearbyUnits, target), function(t) - local f = AbilityExtensions:GetPointToLineDistance(t:GetLocation(), line) <= searchRadius + target:GetBoundingRadius() and distance <= GetUnitToUnitDistance(npcBot, t) + local f = AbilityExtensions:GetPointToLineDistance(t:GetLocation(), line) <= searchRadius + target:GetBoundingRadius() and distance <= GetUnitToUnitDistance(npcBot, t) or t:IsInvulnerable() return f end) end @@ -98,28 +100,21 @@ Consider[1] = function() local point = target:GetExtrapolatedLocation(GetUnitToUnitDistance(npcBot, target) / hookSpeed + castPoint) local distance = GetUnitToLocationDistance(npcBot, point) local line = AbilityExtensions:GetLine(npcBot:GetLocation(), point) - if line == nil then - print("pudge: line == nil") - end - print("pudge: if I hook "..target:GetUnitName()) local result = GetUnitToLocationDistance(npcBot, point) <= range and NotBlockedByAnyUnit(line, target, distance) - if result then - print("pudge: I can hook "..target:GetUnitName()) - end return result end local enemies = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, range, true, BOT_MODE_NONE) enemies = AbilityExtensions:SortByMaxFirst(enemies, function(t) return GetUnitToUnitDistance(npcBot, t) end) enemies = AbilityExtensions:Filter(enemies, T) - if #enemies ~= 0 then + if #enemies ~= 0 and CanCast[1](enemies[1]) then return BOT_MODE_DESIRE_HIGH, enemies[1]:GetExtrapolatedLocation(GetUnitToUnitDistance(npcBot, enemies[1]) / 1450) end local allies = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, range, false, BOT_MODE_NONE) allies = AbilityExtensions:Filter(allies, function(t) return t:IsStunned() or t:IsRooted() end) allies = AbilityExtensions:Filter(allies, T) - if #allies ~= 0 then + if #allies ~= 0 and CanCast[1](allies[1]) then return BOT_MODE_DESIRE_HIGH, allies[1]:GetExtrapolatedLocation(GetUnitToUnitDistance(npcBot, enemies[1]) / 1450) end @@ -128,10 +123,7 @@ end Consider[2] = function() local ability = AbilitiesReal[2] - local radius = 250 - if npcBot:HasScepter() then - radius = 475 - end + local radius = ability:GetAOERadius() if not ability:IsFullyCastable() then return false end @@ -142,6 +134,13 @@ Consider[2] = function() end return false end + do + local target = npcBot:GetTarget() + if target and GetUnitToUnitDistance(target, npcBot) <= radius and AbilityExtensions:NormalCanCast(target, false) then + return true + end + end + return false end Consider[2] = AbilityExtensions:ToggleFunctionToAction(npcBot, Consider[2], AbilitiesReal[2]) @@ -150,7 +149,7 @@ local swallowingSomething local swallowTimer Consider[4] = function() local ability = AbilitiesReal[4] - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or npcBot:IsChanneling() then return 0 end swallowingSomething = npcBot:HasModifier("modifier_pudge_swallow") or npcBot:HasModifier("modifier_pudge_swallow_effect") or npcBot:HasModifier("modifier_pudge_swallow_hide") @@ -168,7 +167,7 @@ end Consider[5] = function() local ability = AbilitiesReal[5] - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or npcBot:IsChanneling() then return nil end local range = ability:GetCastRange() + 100 @@ -178,50 +177,49 @@ Consider[5] = function() if hookedEnemy ~= nil then return BOT_MODE_DESIRE_VERYHIGH, hookedEnemy end + + do + local target = AbilityExtensions:GetTargetIfGood(npcBot) + if target ~= nil and CanCast[5](target) and GetUnitToUnitDistance(npcBot, target) <= range then + return BOT_MODE_DESIRE_HIGH, target + end + end local nearbyEnemies = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, 900, true, BOT_MODE_NONE) if AbilityExtensions:IsAttackingEnemies(npcBot) then local u = utility.GetWeakestUnit(nearbyEnemies) - if u ~= nil then + if u ~= nil and CanCast[5](u) then return BOT_MODE_DESIRE_HIGH, u end end if AbilityExtensions:IsRetreating(npcBot) and #nearbyEnemies == 1 then local loneEnemy = nearbyEnemies[1] - if not AbilityExtensions:HasAbilityRetargetModifier(loneEnemy) then + if not AbilityExtensions:HasAbilityRetargetModifier(loneEnemy) and CanCast[5](loneEnemy) then return BOT_MODE_DESIRE_MODERATE, loneEnemy end end - local nearbyAllies = AbilityExtensions:Filter(AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, range+200, false, BOT_MODE_NONE), function(t) return AbilityExtensions:CanHardlyMove(t) end) - nearbyAllies = AbilityExtensions:SortByMinFirst(nearbyAllies, function(t) return t:GetHealth() end) - if #nearbyAllies ~= 0 then - return BOT_MODE_DESIRE_MODERATE, nearbyAllies[1] - end -end - -function GetComboDamage() - return ability_item_usage_generic.GetComboDamage(AbilitiesReal) + -- if has shard + -- local function CanCast5AtFriend(friend) + -- return not AbilityExtensions:IsInvulnerable(friend) and not AbilityExtensions:CannotBeTargetted() + -- end + -- local nearbyAllies = AbilityExtensions:Filter(AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, range+200, false, BOT_MODE_NONE), function(t) return AbilityExtensions:CanHardlyMove(t) end) + -- nearbyAllies = AbilityExtensions:SortByMinFirst(nearbyAllies, function(t) return t:GetHealth() end) + -- if #nearbyAllies ~= 0 and CanCast5AtFriend(nearbyAllies[1]) then + -- return BOT_MODE_DESIRE_MODERATE, nearbyAllies[1] + -- end + return 0 end -function GetComboMana() - return ability_item_usage_generic.GetComboMana(AbilitiesReal) -end function CourierUsageThink() ability_item_usage_generic.CourierUsageThink() end function AbilityUsageThink() - if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() ) - then + if npcBot:IsUsingAbility() or npcBot:IsSilenced() then return end - cast=ability_item_usage_generic.ConsiderAbility(AbilitiesReal,Consider) - ---------------------------------debug-------------------------------------------- - if true then - --ability_item_usage_generic.PrintDebugInfo(AbilitiesReal,cast) - end ability_item_usage_generic.UseAbility(AbilitiesReal,cast) end diff --git a/ability_item_usage_pugna.lua b/ability_item_usage_pugna.lua index 42724395..0e4d2d5d 100644 --- a/ability_item_usage_pugna.lua +++ b/ability_item_usage_pugna.lua @@ -133,8 +133,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius() local CastPoint = ability:GetCastPoint()+ability:GetSpecialValueFloat( "delay" ); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -373,8 +372,7 @@ Consider[3]=function() local Radius = ability:GetAOERadius() local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_queenofpain.lua b/ability_item_usage_queenofpain.lua index 476cad3b..3b647cbc 100644 --- a/ability_item_usage_queenofpain.lua +++ b/ability_item_usage_queenofpain.lua @@ -98,8 +98,7 @@ Consider[1]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -208,14 +207,13 @@ Consider[2]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotTeleport(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end local CastRange = ability:GetSpecialValueInt( "blink_range" ); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -308,8 +306,7 @@ Consider[3]=function() local Radius = ability:GetAOERadius() local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes(Radius, false, BOT_MODE_NONE ); local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) @@ -432,8 +429,7 @@ Consider[4]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+0,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -468,7 +464,7 @@ Consider[4]=function() return BOT_ACTION_DESIRE_MODERATE, locationAoE.targetloc; end else - local npcTarget = npcBot:GetTarget(); + local npcTarget = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcTarget ~= nil ) then if ( CanCast[abilityNumber]( npcTarget ) ) diff --git a/ability_item_usage_rattletrap.lua b/ability_item_usage_rattletrap.lua new file mode 100644 index 00000000..1307baad --- /dev/null +++ b/ability_item_usage_rattletrap.lua @@ -0,0 +1,138 @@ +-- v1.7 template by AaronSong321 +local utility = require(GetScriptDirectory().."/utility") +require(GetScriptDirectory() .. "/ability_item_usage_generic") +local AbilityExtensions = require(GetScriptDirectory().."/util/AbilityAbstraction") + +local npcBot = GetBot() +if npcBot:IsIllusion() then + return +end +local AbilityNames, Abilities, Talents = AbilityExtensions:InitAbility(npcBot) +--local CanCast = {utility.NCanCast,utility.UCanCast,utility.NCanCast,utility.UCanCast,utility.UCanCast} + +local AbilityToLevelUp = +{ + AbilityNames[2], + AbilityNames[3], + AbilityNames[3], + AbilityNames[1], + AbilityNames[3], + AbilityNames[5], + AbilityNames[3], + AbilityNames[2], + AbilityNames[2], + "talent", + AbilityNames[2], + AbilityNames[1], + AbilityNames[1], + AbilityNames[1], + "talent", + AbilityNames[5], + "nil", + AbilityNames[5], + "nil", + "talent", + "nil", + "nil", + "nil", + "nil", + "talent", +} +local TalentTree = { + function() + return Talents[1] + end, + function() + return Talents[4] + end, + function() + return Talents[5] + end, + function() + return Talents[8] + end +} +utility.CheckAbilityBuild(AbilityToLevelUp) + +function AbilityLevelUpThink() + ability_item_usage_generic.AbilityLevelUpThink2(AbilityToLevelUp, TalentTree) +end + +local cast= {} cast.Desire= {} cast.Target= {} cast.Type= {} + +local CanCast = {} +CanCast[1] = function(t) return AbilityExtensions:NormalCanCast(t, false, DAMAGE_TYPE_MAGICAL, false) end +CanCast[2] = CanCast[1] +CanCast[3] = function(t) + local ability = npcBot:GetAbilityByName("special_bonus_unique_clockwerk_6") + local breakInvisible = ability:GetLevel() == 1 and not ability:CanAbilityBeUpgraded() + if breakInvisible then + return AbilityExtensions:NormalCanCast(t, true, DAMAGE_TYPE_MAGICAL, false, false) + else + return AbilityExtensions:NormalCanCast(t, true, DAMAGE_TYPE_MAGICAL, false, t:IsInvisible()) + end +end +CanCast[4] = function() return true end +CanCast[5] = CanCast[4] +CanCast[6] = function(t) + return AbilityExtensions:NormalCanCast(t, false, DAMAGE_TYPE_MAGICAL, true) +end + +local Consider = {} + + +local attackRange +local healthPercent +local mana +local manaPercent + +Consider[1] = function() + local ability = Abilities[1] + if not ability:IsFullyCastable() then + return 0 + end + local abilityLevel = ability:GetLevel() + local castRange = ability:GetCastRange() + local castPoint = ability:GetCastPoint() + local manaCost = ability:GetManaCost() + local duration = ability:GetDuration() + local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, castRange) + local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) + local targettableEnemies = AbilityExtensions:Filter(realEnemies, function(t) return AbilityExtensions:NormalCanCast(t, true) end) + local friends = AbilityExtensions:GetNearbyHeroes(npcBot, 1200, true) + local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) + local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, castRange) + local friendCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, npcBot:GetAttackRange()+150, false) + local neutralCreeps = npcBot:GetNearbyNeutralCreeps(castRange) + local damage = ability:GetSpecialValueInt("total_damage") + local weakestEnemy, enemyHealth = utility.GetWeakestUnit(targettableEnemies) + local weakCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) return t:GetHealth() < t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) end) + local weakestCreep = utility.GetWeakestUnit(weakCreeps) + local forbiddenCreeps = AbilityExtensions:Filter(enemyCreeps, function(t) + return t:GetHealth() > t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) and t:GetHealth() <= t:GetActualIncomingDamage(damage, DAMAGE_TYPE_MAGICAL) + AbilityExtensions:AttackOnceDamage(npcBot, t) * (0.9+#enemyCreeps*0.1) + end) + if #friendCreeps == 0 then + forbiddenCreeps = {} + end + + return 0 +end + +AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, Abilities) + +function AbilityUsageThink() + if npcBot:IsChanneling() or npcBot:IsSilenced() then + return + end + attackRange = npcBot:GetAttackRange() + healthPercent = AbilityExtensions:GetHealthPercent(npcBot) + mana = npcBot:GetMana() + manaPercent = AbilityExtensions:GetManaPercent(npcBot) + + cast=ability_item_usage_generic.ConsiderAbility(Abilities,Consider) + local abilityIndex, target, castType = ability_item_usage_generic.UseAbility(Abilities,cast) +end + +function CourierUsageThink() + ability_item_usage_generic.CourierUsageThink() +end \ No newline at end of file diff --git a/ability_item_usage_razor.lua b/ability_item_usage_razor.lua index 02d1c8f9..faff32ca 100644 --- a/ability_item_usage_razor.lua +++ b/ability_item_usage_razor.lua @@ -393,7 +393,7 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -407,7 +407,7 @@ Consider[4]=function() return BOT_ACTION_DESIRE_NONE, 0; end - +debugmode=false AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) function AbilityUsageThink() -- Check if we're already using an ability diff --git a/ability_item_usage_riki.lua b/ability_item_usage_riki.lua index 9c1cbfda..d303245b 100644 --- a/ability_item_usage_riki.lua +++ b/ability_item_usage_riki.lua @@ -104,8 +104,7 @@ Consider[1]=function() --Target Ability Example local CastPoint = ability:GetCastPoint() local Radius=ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -214,15 +213,14 @@ Consider[2]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or AbilityExtensions:CannotTeleport(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end local CastRange = math.min(ability:GetCastRange(),1600) local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_shadow_demon.lua b/ability_item_usage_shadow_demon.lua index d07685bf..c7a543a6 100644 --- a/ability_item_usage_shadow_demon.lua +++ b/ability_item_usage_shadow_demon.lua @@ -76,7 +76,6 @@ local const = AbilityHelper.const local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast,utility.NCanCast} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -87,6 +86,29 @@ function GetComboMana() return ability_item_usage_generic.GetComboMana(AbilitiesReal) end +local CanCast = {} +CanCast[1] = function(t) + if target:HasModifier("modifier_shadow_demon_disruption") then + return false + end + if npcBot:GetTeam() == t:GetTeam() then + return AbilityExtensions:SpellCanCast(t, true, true, true) and not AbilityExtensions:DontInterruptAlly(t) and not t:IsMagicImmune() + else + return AbilityExtensions:NormalCanCast(t, false, DAMAGE_TYPE_MAGICAL) and not target:HasModifier("modifier_antimage_counterspell") + end +end +CanCast[2] = function(target) + return target:HasModifier("modifier_shadow_demon_disruption") or AbilityExtensions:NormalCanCast(target, false, DAMAGE_TYPE_PURE, false, false) +end +CanCast[3] = function(target) + return target:HasModifier("modifier_shadow_demon_disruption") or AbilityExtensions:NormalCanCast(target, false, DAMAGE_TYPE_MAGICAL, false, true) -- cannot calculate the position if the target is not seen +end +CanCast[4] = function(target) + return target:HasModifier("modifier_shadow_demon_disruption") or AbilityExtensions:NormalCanCast(target, false, DAMAGE_TYPE_MAGICAL, false, true) +end +CanCast[5] = function(target) + return not target:HasModifier("modifier_antimage_counterspell") and not target:HasModifier("modifier_shadow_demon_purge_slow") and (target:HasModifier("modifier_shadow_demon_disruption") or AbilityExtensions:NormalCanCast(target, false, DAMAGE_TYPE_MAGICAL, false, true)) +end Consider[1]=function() @@ -103,19 +125,15 @@ Consider[1]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local allys = npcBot:GetNearbyHeroes( CastRange+300, false, BOT_MODE_NONE ) + local allys = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, CastRange+300, false) local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) - local allys2 = GetUnitList(UNIT_LIST_ALLIED_HEROES) local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) - local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - local npcTarget -- Check for a channeling enemy for _,enemy in pairs( enemys ) do - if ( enemy:IsChanneling() and CanCast[abilityNumber]( enemy )) + if ( enemy:IsChanneling() and CanCast[abilityNumber]( enemy ) and not AbilityExtensions:IsOrGoingToBeSeverelyDisabled(enemy)) then return BOT_ACTION_DESIRE_HIGH, enemy end @@ -132,7 +150,7 @@ Consider[1]=function() local tableNearbyEnemyHeroes = npcBot:GetNearbyHeroes( CastRange, true, BOT_MODE_NONE ); for _,npcEnemy in pairs( tableNearbyEnemyHeroes ) do - if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy)) + if ( CanCast[abilityNumber]( npcEnemy ) and not AbilityExtensions:IsOrGoingToBeSeverelyDisabled(npcEnemy)) then local Damage2 = npcEnemy:GetEstimatedDamageToTarget( false, npcBot, 3.0, DAMAGE_TYPE_ALL ); if ( Damage2 > nMostDangerousDamage ) @@ -143,7 +161,7 @@ Consider[1]=function() end end - if ( npcMostDangerousEnemy ~= nil and not enemyDisabled(npcMostDangerousEnemy)) + if ( npcMostDangerousEnemy ~= nil and not AbilityExtensions:IsOrGoingToBeSeverelyDisabled(npcMostDangerousEnemy)) then return BOT_ACTION_DESIRE_LOW, npcMostDangerousEnemy; end @@ -156,7 +174,7 @@ Consider[1]=function() then if ( CanCast[abilityNumber]( WeakestEnemy ) ) then - if ( CanCast[abilityNumber]( WeakestEnemy ) and not enemyDisabled(WeakestEnemy)) + if ( CanCast[abilityNumber]( WeakestEnemy ) and not AbilityExtensions:IsOrGoingToBeSeverelyDisabled(WeakestEnemy)) then return BOT_ACTION_DESIRE_MODERATE,WeakestEnemy; end @@ -175,7 +193,7 @@ Consider[1]=function() do if ( npcBot:WasRecentlyDamagedByHero( npcEnemy, 2.0 ) ) then - if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy)) + if ( CanCast[abilityNumber]( npcEnemy ) and not AbilityExtensions:IsOrGoingToBeSeverelyDisabled(npcEnemy)) then return BOT_ACTION_DESIRE_HIGH, npcEnemy; end @@ -193,7 +211,7 @@ Consider[1]=function() if ( npcTarget ~= nil ) then - if ( CanCast[abilityNumber]( npcTarget ) and not enemyDisabled(npcTarget) and GetUnitToUnitDistance(npcBot,npcTarget) > 400 + if ( CanCast[abilityNumber]( npcTarget ) and not AbilityExtensions:IsOrGoingToBeSeverelyDisabled(npcTarget) and GetUnitToUnitDistance(npcBot,npcTarget) > 400 and GetUnitToUnitDistance(npcBot,npcTarget) < CastRange + 100) then return BOT_ACTION_DESIRE_MODERATE, npcTarget @@ -213,30 +231,65 @@ Consider[1]=function() end end - -- If we're going after someone - if ( npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_TOP or - npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_BOT or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_TOP or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_MID or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_BOT) - then - for _,npcTarget in pairs( allys ) - do - if(npcTarget:GetHealth()/npcTarget:GetMaxHealth()<0.25 and #enemys >= 2 and #allys >= #enemys) - then - if ( CanCast[abilityNumber]( npcTarget ) and not enemyDisabled(npcTarget)) - then - return BOT_ACTION_DESIRE_MODERATE, npcTarget - end - end - end - end + local enemys2 = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, 1000) + local enemyCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, enemys2) + + for _,npcTarget in pairs( allys ) + do + if (npcTarget:GetHealth()/npcTarget:GetMaxHealth()<=0.2+0.05*enemyCount) and AbilityExtensions:IsOrGoingToBeSeverelyDisabled(npcTarget) and CanCast[2](npcTarget) + then + return RemapValClamped(AbilityExtensions:GetIllusionBattlePower(npcTarget), 0.1, 0.4, BOT_ACTION_DESIRE_MODERATE, BOT_ACTION_DESIRE_VERYHIGH), npcTarget + end + end return BOT_ACTION_DESIRE_NONE, 0 end +Consider[2] = function() + local ability = AbilitiesReal[2] + if not ability:IsFullyCastable() or AbilityExtensions:CannotMove(npcBot) or ability:GetCurrentCharges() == 0 then + return 0 + end + local abilityLevel = ability:GetLevel() + local castRange = ability:GetCastRange() + 200 + local radius = ability:GetAOERadius() + local castPoint = ability:GetCastPoint() + local manaCost = ability:GetManaCost() + local duration = ability:GetDuration() + local enemies = AbilityExtensions:GetNearbyHeroes(npcBot, castRange + radius) + local realEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:MayNotBeIllusion(npcBot, t) end) + local targettableEnemies = AbilityExtensions:Filter(enemies, function(t) return AbilityExtensions:NormalCanCast(t, true, DAMAGE_TYPE_PHYSICAL, true) and not AbilityExtensions:CannotBeAttacked(t) end) + local friends = AbilityExtensions:GetNearbyHeroes(npcBot, 1200, true) + local friendCount = AbilityExtensions:GetEnemyHeroNumber(npcBot, friends) + local enemyCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, castRange + radius) + local friendCreeps = AbilityExtensions:GetNearbyAttackableCreeps(npcBot, npcBot:GetAttackRange()+150, false) + local neutralCreeps = npcBot:GetNearbyNeutralCreeps(castRange) + local weakestEnemy, enemyHealth = utility.GetWeakestUnit(targettableEnemies) + local target = npcBot:GetTarget() + + do + if target and CanCast[2](target) then + return BOT_ACTION_DESIRE_MODERATE, AbilityExtensions:FindAOELocationAtSingleTarget(npcBot, target, radius, castRange, castPoint) + end + end + if AbilityExtensions:NotRetreating(npcBot) then + local findPlace = npcBot:FindAoELocation(true, true, npcBot:GetLocation(), castRange+100, radius, 0, 0) + if findPlace.count >= 3 then + if GetUnitToLocationDistance(npcBot, findPlace) <= castRange then + return BOT_ACTION_DESIRE_VERYHIGH, findPlace.targetloc + else + return BOT_ACTION_DESIRE_MODERATE, findPlace.targetloc + end + elseif findPlace.count >= 2 then + return BOT_ACTION_DESIRE_MODERATE, findPlace.targetloc + elseif #realEnemies == 1 and findPlace.count == 1 then + return BOT_ACTION_DESIRE_MODERATE-0.1, findPlace.targetloc + end + end + return 0 +end + local function GetPoisonCount(npcTarget) local modifier=npcTarget:GetModifierByName("modifier_shadow_demon_shadow_poison") if(modifier~=nil) @@ -247,100 +300,6 @@ local function GetPoisonCount(npcTarget) end end -Consider[3] = function() - local abilityIndex = 3 - -------------------------------------- - -- Generic Variable Setting - -------------------------------------- - local ability = AbilitiesReal[abilityIndex] - - if not ability:IsFullyCastable() then - return BOT_ACTION_DESIRE_NONE, 0 - end - - local castRange = ability:GetCastRange() - local castPoint = ability:GetCastPoint() - local damage = ability:GetAbilityDamage() - local damageType = ability:GetDamageType() - local radius = ability:GetAOERadius() - - local serachDistance = Min(castRange + const.EXTRA_SEARCH_DISTANCE, const.MAX_SEARCH_DISTANCE) - local isManaEnough = ManaPercent > 0.6 or npcBot:GetMana() > ComboMana - local allys = npcBot:GetNearbyHeroes(const.MAX_ALLY_SEARCH_DISTANCE, false, BOT_MODE_NONE) - local enemys = npcBot:GetNearbyHeroes(serachDistance, true, BOT_MODE_NONE) - local weakestEnemy, heroHealth = AbilityHelper.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(serachDistance, true) - local weakestCreep, creepHealth = AbilityHelper.GetWeakestUnit(creeps) - - local activeMode=npcBot:GetActiveMode() - local activeModeDesire=npcBot:GetActiveModeDesire() - -------------------------------------- - -- Mode based usage - -------------------------------------- - -- Protect myself - local nearyByEnemys = npcBot:GetNearbyHeroes(const.WARNING_DISTANCE, true, BOT_MODE_NONE) - if ((activeMode == BOT_MODE_RETREAT and activeModeDesire >= BOT_MODE_DESIRE_HIGH) or #nearyByEnemys > 0) then - for _, npcEnemy in pairs(enemys) do - if (CanCast[abilityIndex](npcEnemy) and not enemyDisabled(npcEnemy)) then - if - (npcBot:WasRecentlyDamagedByHero(npcEnemy, 2.0) or GetUnitToUnitDistance(npcBot, npcEnemy) < const.WARNING_DISTANCE) - then - return BOT_ACTION_DESIRE_HIGH, npcEnemy:GetExtrapolatedLocation(castPoint) - end - end - end - end - - -- If we're farming - if (activeMode == BOT_MODE_FARM) then - if (isManaEnough) then - local locationAoE = npcBot:FindAoELocation(true, false, npcBot:GetLocation(), castRange, radius, 0, 0) - if (locationAoE.count >= 3) then - return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc - end - end - end - - -- If we're pushing or defending a lane - if - (activeMode == BOT_MODE_PUSH_TOWER_TOP or activeMode == BOT_MODE_PUSH_TOWER_MID or - activeMode == BOT_MODE_PUSH_TOWER_BOT or - activeMode == BOT_MODE_DEFEND_TOWER_TOP or - activeMode == BOT_MODE_DEFEND_TOWER_MID or - activeMode == BOT_MODE_DEFEND_TOWER_BOT) - then - if (isManaEnough and AbilitiesReal[abilityIndex]:GetLevel() >= 1) then - local locationAoE = npcBot:FindAoELocation(true, false, npcBot:GetLocation(), castRange, radius, 0, 0) - if (locationAoE.count >= 4) then - return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc - end - end - end - - -- If we're going after someone - if - (npcBot:GetActiveMode() == BOT_MODE_ROAM or npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or - npcBot:GetActiveMode() == BOT_MODE_ATTACK) - then - local locationAoE = npcBot:FindAoELocation(true, true, npcBot:GetLocation(), castRange, radius, 0, 0) - if (locationAoE.count >= 2) then - return BOT_ACTION_DESIRE_LOW, locationAoE.targetloc - end - - if (enemys == nil or #enemys <= 2) then - local npcEnemy = npcBot:GetTarget() - if (npcEnemy~=nil and CanCast[abilityIndex](npcEnemy)) then - if (GetUnitToUnitDistance(npcBot, npcEnemy) < const.MAX_SEARCH_DISTANCE) then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy:GetExtrapolatedLocation(castPoint) - end - end - end - end - - return BOT_ACTION_DESIRE_NONE, 0 -end - Consider[3]=function() local abilityNumber=3 @@ -487,8 +446,7 @@ Consider[5]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -535,7 +493,7 @@ Consider[5]=function() for _,npcEnemy in pairs( enemys ) do - if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy)) + if ( CanCast[abilityNumber]( npcEnemy ) and not AbilityExtensions:IsSeverelyDisabledOrSlowed(npcEnemy)) then local Damage2 = npcEnemy:GetEstimatedDamageToTarget( false, npcBot, 3.0, DAMAGE_TYPE_ALL ); if ( Damage2 > nMostDangerousDamage ) @@ -573,7 +531,7 @@ Consider[5]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then diff --git a/ability_item_usage_shadow_shaman.lua b/ability_item_usage_shadow_shaman.lua index dd39e030..6245d37c 100644 --- a/ability_item_usage_shadow_shaman.lua +++ b/ability_item_usage_shadow_shaman.lua @@ -98,8 +98,7 @@ Consider[1]=function() --Target Ability Example local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -251,8 +250,7 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -352,8 +350,7 @@ Consider[3]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -442,8 +439,7 @@ Consider[4]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_shredder.lua b/ability_item_usage_shredder.lua index 3d56c3b3..2c6287c9 100644 --- a/ability_item_usage_shredder.lua +++ b/ability_item_usage_shredder.lua @@ -101,8 +101,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius() local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -283,7 +282,7 @@ Consider[2]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotMove(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end @@ -293,8 +292,7 @@ Consider[2]=function() local CastPoint = ability:GetCastPoint(); local CastRange = ability:GetCastRange(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -379,8 +377,7 @@ Consider[5]=function() local CastPoint = ability:GetCastPoint(); local Speed = 900; - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -509,8 +506,7 @@ Consider[4]=function() --A杖大 local CastPoint = ability:GetCastPoint(); local Speed = 900; - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_silencer.lua b/ability_item_usage_silencer.lua index 92d862e0..fed4d15a 100644 --- a/ability_item_usage_silencer.lua +++ b/ability_item_usage_silencer.lua @@ -72,7 +72,7 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} +local CanCast={utility.NCanCast,AbilityExtensions.PhysicalCanCastFunction,utility.NCanCast,utility.UCanCast} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -99,8 +99,7 @@ Consider[1]=function() local Damage = ability:GetSpecialValueInt("duration")*ability:GetSpecialValueInt("damage") local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -214,109 +213,58 @@ Consider[1]=function() end -Consider[2]=function() - local abilityNumber=2 - -------------------------------------- - -- Generic Variable Setting - -------------------------------------- - local ability=AbilitiesReal[abilityNumber]; - - if not ability:IsFullyCastable() then - return BOT_ACTION_DESIRE_NONE, 0; - end - - local CastRange = ability:GetCastRange(); - local Damage = ability:GetAbilityDamage(); - - local HeroHealth=10000 - local CreepHealth=10000 - local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(CastRange+150,true,BOT_MODE_NONE) - local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(CastRange+150,true) - local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - - if(ability:GetToggleState()==false) - then - local t=npcBot:GetAttackTarget() - if(t~=nil) - then - if (t:IsHero() or t:IsTower()) - then - ability:ToggleAutoCast() - return BOT_ACTION_DESIRE_NONE, 0; - end - end - else - local t=npcBot:GetAttackTarget() - if(t~=nil) - then - if (not(t:IsHero() or t:IsTower())) - then - ability:ToggleAutoCast() - return BOT_ACTION_DESIRE_NONE, 0; - end - end - end - - --try to kill enemy hero - if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT) - then - if (WeakestEnemy~=nil) - then - if ( CanCast[abilityNumber]( WeakestEnemy ) ) - then - if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_ALL)) - then - return BOT_ACTION_DESIRE_HIGH,WeakestEnemy; - end - end - end - end - -------------------------------------- - -- Mode based usage - -------------------------------------- - - if ( npcBot:GetActiveMode() == BOT_MODE_LANING ) - then - if(CreepHealth>=150) - then - if (WeakestEnemy~=nil) - then - if ( CanCast[abilityNumber]( WeakestEnemy ) ) - then - return BOT_ACTION_DESIRE_LOW,WeakestEnemy - end - end - end - end - - -- If we're farming - if ( npcBot:GetActiveMode() == BOT_MODE_FARM ) - then - return BOT_ACTION_DESIRE_LOW, WeakestCreep; - end - - -- If we're going after someone - if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or - npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or - npcBot:GetActiveMode() == BOT_MODE_ATTACK ) - then - local npcEnemy = npcBot:GetTarget(); - if ( npcEnemy ~= nil ) - then - if ( CanCast[abilityNumber]( npcEnemy ) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange+100) - then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy; - end - end - end - - return BOT_ACTION_DESIRE_NONE, 0; - +Consider[2] = function() + local abilityNumber=2 + -------------------------------------- + -- Generic Variable Setting + -------------------------------------- + local ability=AbilitiesReal[abilityNumber] + + if not ability:IsFullyCastable() or AbilityExtensions:IsPhysicalOutputDisabled(npcBot) then + return 0 + end + + local CastRange = ability:GetCastRange() + local enemys = npcBot:GetNearbyHeroes(CastRange+100,true,BOT_MODE_NONE) + local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) + + local function UseAt(target) + if not CanCast[abilityNumber](target) then + return false + end + if target:IsHero() then + if AbilityExtensions:MustBeIllusion(npcBot, target) then + return AbilityExtensions:GetManaPercent(npcBot) >= 0.8 or AbilityExtensions:GetHealthPercent(target) <= 0.4 + else + return AbilityExtensions:GetManaPercent(npcBot) >= 0.4 or AbilityExtensions:GetManaPercent(npcBot) >= 0.2 + end + elseif target:IsBuilding() then + return false + else + return AbilityExtensions:GetManaPercent(npcBot) >= 0.8 + end + + end + + if AbilityExtensions:NotRetreating(npcBot) then + local target = npcBot:GetAttackTarget() or npcBot:GetTarget() + if target == nil then + if WeakestEnemy ~= nil then + local b = UseAt(WeakestEnemy) + if b then + return BOT_ACTION_DESIRE_HIGH, WeakestEnemy + else + return false + end + end + else + return UseAt(target) + end + end + return false end +Consider[2] = AbilityExtensions:ToggleFunctionToAutoCast(npcBot, Consider[2], AbilitiesReal[2]) Consider[3]=function() local abilityNumber=3 @@ -332,8 +280,7 @@ Consider[3]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -489,17 +436,15 @@ Consider[4]=function() local Damage = 0 local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(1200,true,BOT_MODE_NONE) + local enemys = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, 1200,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) -- Check for a channeling enemy for _,npcEnemy in pairs( enemys ) do - if ( npcEnemy:IsChanneling() and CanCast[abilityNumber]( npcEnemy ) and not npcEnemy:HasModifier("modifier_teleporting")) - then + if AbilityExtensions:IsChannelingAbility(npcEnemy) and CanCast[abilityNumber]( npcEnemy ) then return BOT_ACTION_DESIRE_HIGH, npcEnemy end end diff --git a/ability_item_usage_skeleton_king.lua b/ability_item_usage_skeleton_king.lua index fed2c7ba..cc3e959e 100644 --- a/ability_item_usage_skeleton_king.lua +++ b/ability_item_usage_skeleton_king.lua @@ -98,8 +98,7 @@ Consider[1]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -216,13 +215,13 @@ Consider[2]=function() local CastRange = ability:GetCastRange() local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) + local enemys = npcBot:GetNearbyHeroes(1200,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(Radius+300,true) + local creeps = npcBot:GetNearbyCreeps(1200,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) + local Damage = ability:GetLevel()*100 -------------------------------------- -- Global high-priorty usage -------------------------------------- @@ -270,7 +269,7 @@ Consider[2]=function() if ( npcEnemy ~= nil and npcBot:HasModifier("modifier_skeleton_king_mortal_strike") and npcBot:GetModifierStackCount(npcBot:GetModifierByName("modifier_skeleton_king_mortal_strike"))> ability:GetLevel() + 2) then - if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy) <= Radius-CastPoint* npcEnemy:GetCurrentMovementSpeed()) + if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy) <= 1200-CastPoint* npcEnemy:GetCurrentMovementSpeed()) then return BOT_ACTION_DESIRE_MODERATE end diff --git a/ability_item_usage_skywrath_mage.lua b/ability_item_usage_skywrath_mage.lua index 9029953f..d4784876 100644 --- a/ability_item_usage_skywrath_mage.lua +++ b/ability_item_usage_skywrath_mage.lua @@ -94,8 +94,7 @@ Consider[1]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -196,8 +195,7 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+0,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -271,8 +269,7 @@ Consider[3]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -348,7 +345,7 @@ Consider[3]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcTarget = npcBot:GetTarget(); + local npcTarget = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcTarget ~= nil ) then @@ -373,15 +370,14 @@ Consider[4]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) -- If a mode has set a target, and we can kill them, do it - local npcTarget = npcBot:GetTarget(); + local npcTarget = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcTarget ~= nil and CanCast[4]( npcTarget ) ) then if (GetComboDamage() > npcTarget:GetHealth() and GetUnitToUnitDistance ( npcTarget, npcBot ) < ( CastRange + 200 ) and diff --git a/ability_item_usage_slardar.lua b/ability_item_usage_slardar.lua index 79928ed2..7d96f313 100644 --- a/ability_item_usage_slardar.lua +++ b/ability_item_usage_slardar.lua @@ -96,8 +96,7 @@ Consider[1]=function() --Target Ability Example local CastRange = ability:GetCastRange(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -161,7 +160,7 @@ Consider[2]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotMove(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end @@ -170,12 +169,7 @@ Consider[2]=function() local Radius = ability:GetAOERadius()-50 local CastPoint = ability:GetCastPoint() - local i=npcBot:FindItemSlot("item_blink") - if(i>=0 and i<=5) - then - blink=npcBot:GetItemInSlot(i) - i=nil - end + local blink = AbilityExtensions:GetAvailableBlink(npcBot) if(blink~=nil and blink:IsFullyCastable()) then CastRange=CastRange+1200 @@ -190,8 +184,7 @@ Consider[2]=function() end end - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -304,8 +297,7 @@ Consider[4]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_slark.lua b/ability_item_usage_slark.lua index a4d8421a..6dc9a2c2 100644 --- a/ability_item_usage_slark.lua +++ b/ability_item_usage_slark.lua @@ -103,8 +103,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius() local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -226,15 +225,14 @@ Consider[2]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotMove(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end local CastRange = ability:GetSpecialValueInt( "pounce_distance" )-100 local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -253,7 +251,7 @@ Consider[2]=function() then if (WeakestEnemy~=nil) then - if ( CanCast[abilityNumber]( WeakestEnemy ) and npcBot:IsFacingUnit(WeakestEnemy, 10) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange) + if ( CanCast[abilityNumber]( WeakestEnemy ) and npcBot:IsFacingUnit(WeakestEnemy, 10) and GetUnitToUnitDistance(npcBot,WeakestEnemy)< CastRange) then if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) or (HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana)) then @@ -323,8 +321,7 @@ Consider[5]=function() local CastRange = 300 local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_sniper.lua b/ability_item_usage_sniper.lua index 6825d4b2..cd6dcd8c 100644 --- a/ability_item_usage_sniper.lua +++ b/ability_item_usage_sniper.lua @@ -117,8 +117,6 @@ Consider[1]=function() return desire,templocation end end -local ability1InfoTable = {} -Consider[1] = AbilityExtensions:AddCooldownToChargeAbility(Consider[1], AbilitiesReal[1], ability1InfoTable, 0.8) function Consider1() @@ -279,7 +277,7 @@ Consider[5]=function() if ( CanCast[abilityNumber]( WeakestEnemy ) ) then if(HeroHealth+WeakestEnemy:GetHealthRegen()*CastPoint<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) - and GetUnitToUnitDistance(WeakestEnemy,npcBot) > AttackRange and GetUnitToUnitDistance(npcBot,npcEnemy) AttackRange and GetUnitToUnitDistance(npcBot,WeakestEnemy)=0.7) @@ -269,20 +268,19 @@ Consider[2]=function() --Target AOE Ability Example local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); -------------------------------------- -- Mode based usage -------------------------------------- -- If we're seriously retreating - if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) - then - if ( npcBot:WasRecentlyDamagedByAnyHero( 2.0 ) ) - then - return BOT_ACTION_DESIRE_HIGH, npcEnemy; - end - end + -- if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) + -- then + -- if ( npcBot:WasRecentlyDamagedByAnyHero( 2.0 ) ) + -- then + -- return BOT_ACTION_DESIRE_HIGH, npcEnemy; + -- end + -- end -- If we're going after someone if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or @@ -315,15 +313,14 @@ Consider[4]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or AbilityExtensions:CannotTeleport(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_sven.lua b/ability_item_usage_sven.lua index 6ab0fc73..dfbe6767 100644 --- a/ability_item_usage_sven.lua +++ b/ability_item_usage_sven.lua @@ -101,12 +101,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius(); local blink - local i=npcBot:FindItemSlot("item_blink") - if(i>=0 and i<=5) - then - blink=npcBot:GetItemInSlot(i) - i=nil - end + local blink = AbilityExtensions:GetAvailableBlink(npcBot) if(blink~=nil and blink:IsFullyCastable()) then if(npcBot:GetActiveMode() == BOT_MODE_ATTACK ) @@ -362,7 +357,7 @@ Consider[4]=function() local CastPoint = ability:GetCastPoint(); local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) + local enemys = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot) local enemys2 = npcBot:GetNearbyHeroes(Radius,false,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) local creeps2 = npcBot:GetNearbyCreeps(Radius,false) @@ -372,9 +367,9 @@ Consider[4]=function() then if (WeakestEnemy~=nil) then - if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_PHYSICAL)) + if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_PHYSICAL)) and GetUnitToUnitDistance(npcBot, WeakestEnemy) <= 1800 then - return BOT_ACTION_DESIRE_HIGH,WeakestEnemy; + return BOT_ACTION_DESIRE_HIGH end end end @@ -385,9 +380,9 @@ Consider[4]=function() local tableNearbyAttackingAlliedHeroes = npcBot:GetNearbyHeroes( 1000, false, BOT_MODE_ATTACK ); if ( #tableNearbyAttackingAlliedHeroes >= 2 ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) - if ( npcEnemy ~= nil ) + if ( npcEnemy ~= nil ) and GetUnitToUnitDistance(npcBot, npcEnemy) <= 1800 then return BOT_ACTION_DESIRE_HIGH end diff --git a/ability_item_usage_templar_assassin.lua b/ability_item_usage_templar_assassin.lua index a29be3c8..7d95d9f0 100644 --- a/ability_item_usage_templar_assassin.lua +++ b/ability_item_usage_templar_assassin.lua @@ -100,8 +100,7 @@ Consider[1]=function() local Radius = 0 local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes(Radius, false, BOT_MODE_NONE ); local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) @@ -204,8 +203,7 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetSpecialValueInt("damage_bonus")+npcBot:GetAttackDamage() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+100,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -218,7 +216,7 @@ Consider[2]=function() then if (WeakestEnemy~=nil) then - if(WeakestEnemy:GetHealth()<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_ALL) and GetUnitToUnitDistance(npcBot,npcEnemy)< AttackRange - 50) + if(WeakestEnemy:GetHealth()<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_ALL) and GetUnitToUnitDistance(npcBot,WeakestEnemy)< AttackRange - 50) then return BOT_ACTION_DESIRE_HIGH end @@ -267,7 +265,13 @@ Consider[2]=function() end - +npcBot.trapTable = {} +local findSetTraps = AbilityExtensions:Filter(GetUnitList(UNIT_LIST_ALLIES), function(t) + return t:GetUnitName() == "npc_dota_templar_assassin_psionic_trap" and t:GetTeam() == npcBot:GetTeam() +end) +AbilityExtensions:ForEach(findSetTraps, function(t) + npcBot.trapTable[AbilityExtensions:ToStringVector(t:GetLocation())] = DotaTime() +end) Consider[6]=function() local abilityNumber=6 @@ -285,8 +289,7 @@ Consider[6]=function() local Radius = ability:GetAOERadius() local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -336,7 +339,7 @@ Consider[6]=function() then if (WeakestEnemy~=nil) then - if((ManaPercentage> 0.4 and GetUnitToUnitDistance(npcBot,npcEnemy) < 1600) or GetUnitToUnitDistance(npcBot,npcEnemy)< AttackRange) + if((ManaPercentage> 0.4 and GetUnitToUnitDistance(npcBot,WeakestEnemy) < 1600) or GetUnitToUnitDistance(npcBot,WeakestEnemy)< AttackRange) then return BOT_ACTION_DESIRE_HIGH,WeakestEnemy:GetLocation(); end @@ -396,7 +399,13 @@ function AbilityUsageThink() then ability_item_usage_generic.PrintDebugInfo(AbilitiesReal,cast) end - ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + local index, target, castType = ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + if index == 6 then + print("ta set trap at: "..AbilityExtensions:ToStringVector(target)) + npcBot.trapTable[AbilityExtensions:ToStringVector(target)] = DotaTime() + AbilitiesReal[6]:GetCastPoint() + end + AbilityExtensions:RecordAbility(npcBot, index, target, castType, AbilitiesReal) + end function CourierUsageThink() diff --git a/ability_item_usage_terrorblade.lua b/ability_item_usage_terrorblade.lua index 41f08488..d0f0d98c 100644 --- a/ability_item_usage_terrorblade.lua +++ b/ability_item_usage_terrorblade.lua @@ -100,8 +100,7 @@ Consider[5]=function() local Radius = ability:GetAOERadius()-100 local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes(Radius, false, BOT_MODE_NONE ); local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) @@ -152,7 +151,7 @@ Consider[5]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -323,8 +322,7 @@ Consider[3]=function() local CastRange = 600 local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -352,6 +350,23 @@ Consider[3]=function() local tableNearbyAttackingAlliedHeroes = npcBot:GetNearbyHeroes( 1000, false, BOT_MODE_ATTACK ); if ( #tableNearbyAttackingAlliedHeroes >= 2 ) then + + local npcMostDangerousEnemy = nil; + local nMostDangerousDamage = 0; + + for _,npcEnemy in pairs( enemys ) + do + if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy)) + then + local Damage2 = npcEnemy:GetEstimatedDamageToTarget( false, npcBot, 3.0, DAMAGE_TYPE_ALL ); + if ( Damage2 > nMostDangerousDamage ) + then + nMostDangerousDamage = Damage2; + npcMostDangerousEnemy = npcEnemy; + end + end + end + if ( npcMostDangerousEnemy ~= nil ) then return BOT_ACTION_DESIRE_HIGH @@ -388,8 +403,7 @@ Consider[6]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_tidehunter.lua b/ability_item_usage_tidehunter.lua index f8e5373a..2e09df64 100644 --- a/ability_item_usage_tidehunter.lua +++ b/ability_item_usage_tidehunter.lua @@ -73,7 +73,7 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} +local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.NCanCast} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -100,8 +100,7 @@ Consider[1]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -216,8 +215,7 @@ function Consider1New() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -312,9 +310,8 @@ Consider[3]=function() local Damage = ability:GetAbilityDamage() local Radius = ability:GetAOERadius() - 50 local CastPoint = ability:GetCastPoint() - - local HeroHealth=10000 - local CreepHealth=10000 + + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -373,7 +370,7 @@ Consider[3]=function() -- If we're farming and can hit 2+ creeps if ( npcBot:GetActiveMode() == BOT_MODE_FARM or npcBot:GetActiveMode() == BOT_MODE_LANING) then - if ( #creeps >= 2 ) + if ( #creeps >= 2 and WeakestCreep ~= nil) -- WeakestCreep can be nil on line 378, although I don't know why then if(CreepHealth<=WeakestCreep:GetActualIncomingDamage(Damage,DAMAGE_TYPE_PHYSICAL) and (ManaPercentage>0.4 or npcBot:GetMana()>ComboMana)) then @@ -436,12 +433,7 @@ Consider[4]=function() local CastPoint = ability:GetCastPoint() - local i=npcBot:FindItemSlot("item_blink") - if(i>=0 and i<=5) - then - blink=npcBot:GetItemInSlot(i) - i=nil - end + local blink = AbilityExtensions:GetAvailableBlink(npcBot) if(blink~=nil and blink:IsFullyCastable()) then CastRange=CastRange+1200 @@ -456,8 +448,7 @@ Consider[4]=function() end end - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius-300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -516,7 +507,7 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_MID or npcBot:GetActiveMode() == BOT_MODE_DEFEND_TOWER_BOT) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil and #enemys>=2) then @@ -526,23 +517,29 @@ Consider[4]=function() end end end - - return BOT_ACTION_DESIRE_NONE, 0; - + return BOT_ACTION_DESIRE_NONE end - AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) + +local abilityUsedInfo = {} + function AbilityUsageThink() -- Check if we're already using an ability - if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() ) - then - return - end - - if(npcBot:HasScepter() or npcBot:HasModifier("modifier_item_ultimate_scepter")) - then + if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() )then + if abilityUsedInfo.index == 4 then + local radius = AbilitiesReal[4]:GetAOERadius() + if AbilityExtensions:Count(AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot, radius), CanCast[4]) == 0 then + print("Tide hunter: cancel ultimate") + npcBot:Action_ClearActions(true) + end + end + return + end + abilityUsedInfo.index = nil + + if AbilityExtensions:HasScepter(npcBot) then Consider[1]=Consider1New; end @@ -557,7 +554,10 @@ function AbilityUsageThink() then ability_item_usage_generic.PrintDebugInfo(AbilitiesReal,cast) end - ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + local usedAbilityIndex, target, castType = ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + if usedAbilityIndex ~= nil then + abilityUsedInfo.index = usedAbilityIndex + end end function CourierUsageThink() diff --git a/ability_item_usage_tinker.lua b/ability_item_usage_tinker.lua index 5f020874..bc81c649 100644 --- a/ability_item_usage_tinker.lua +++ b/ability_item_usage_tinker.lua @@ -47,6 +47,8 @@ local TalentTree = { function() return Talents[7] end, } +local Consider = {} + utility.CheckAbilityBuild(AbilityToLevelUp) local function TryLastHitWithAttack(npc, target) @@ -64,7 +66,7 @@ end Consider[1] = function() local manaPercentage = AbilityExtensions:GetManaPercent(npcBot) local ability = AbilitiesReal[1] - if not ability:IsFullyCastable() + if not ability:IsFullyCastable() then return 0 end if npcBot:GetActiveMode() == BOT_MODE_LANING then diff --git a/ability_item_usage_treant.lua b/ability_item_usage_treant.lua index 59b0e64c..77ad07c8 100644 --- a/ability_item_usage_treant.lua +++ b/ability_item_usage_treant.lua @@ -99,12 +99,11 @@ Consider[1]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(1800,true,BOT_MODE_NONE) + local enemys = npcBot:GetNearbyHeroes(1599,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(1800,true) + local creeps = npcBot:GetNearbyCreeps(1599,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) -------------------------------------- -- Global high-priorty usage @@ -118,7 +117,7 @@ Consider[1]=function() then if(HeroHealth<=WeakestEnemy:GetActualIncomingDamage(Damage,DAMAGE_TYPE_MAGICAL) or (HeroHealth<=WeakestEnemy:GetActualIncomingDamage(GetComboDamage(),DAMAGE_TYPE_MAGICAL) and npcBot:GetMana()>ComboMana)) then - return BOT_ACTION_DESIRE_HIGH,WeakestEnemy,"Target"; + return BOT_ACTION_DESIRE_HIGH,WeakestEnemy:GetLocation() end end end @@ -136,7 +135,7 @@ Consider[1]=function() then if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy)) then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy,"Target"; + return BOT_ACTION_DESIRE_MODERATE, npcEnemy:GetLocation() end end end @@ -150,7 +149,7 @@ Consider[1]=function() local locationAoE = npcBot:FindAoELocation( true, false, npcBot:GetLocation(), CastRange, Radius, 0, 0 ); if ( locationAoE.count >= 3 ) then - return BOT_ACTION_DESIRE_MODERATE-0.03, locationAoE.targetloc,"Location"; + return BOT_ACTION_DESIRE_MODERATE-0.03, locationAoE.targetloc end end end @@ -168,7 +167,7 @@ Consider[1]=function() local locationAoE = npcBot:FindAoELocation( true, false, npcBot:GetLocation(), CastRange, Radius, 0, 0 ); if ( locationAoE.count >= 3 ) then - return BOT_ACTION_DESIRE_MODERATE-0.03, locationAoE.targetloc,"Location"; + return BOT_ACTION_DESIRE_MODERATE-0.03, locationAoE.targetloc end end end @@ -183,7 +182,7 @@ Consider[1]=function() then if ( CanCast[abilityNumber]( WeakestEnemy ) ) then - return BOT_ACTION_DESIRE_LOW,WeakestEnemy,"Target"; + return BOT_ACTION_DESIRE_LOW,WeakestEnemy:GetLocation() end end end @@ -198,7 +197,7 @@ Consider[1]=function() local locationAoE = npcBot:FindAoELocation( true, true, npcBot:GetLocation(), CastRange, Radius, 0, 0 ); if ( locationAoE.count >= 2 ) then - return BOT_ACTION_DESIRE_MODERATE, locationAoE.targetloc,"Location" + return BOT_ACTION_DESIRE_MODERATE, locationAoE.targetloc end local npcEnemy = npcBot:GetTarget(); @@ -207,7 +206,7 @@ Consider[1]=function() then if ( not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy)< CastRange + 75*#allys) then - return BOT_ACTION_DESIRE_MODERATE, npcEnemy,"Target" + return BOT_ACTION_DESIRE_MODERATE, npcEnemy:GetLocation() end end end @@ -234,8 +233,7 @@ Consider[2]=function() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -346,11 +344,11 @@ Consider[3]=function() local Damage = ability:GetAbilityDamage(); local HeroHealth=10000 - local allys = npcBot:GetNearbyHeroes( 1800, false, BOT_MODE_NONE ); + local allys = npcBot:GetNearbyHeroes( 1599, false, BOT_MODE_NONE ); local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local allys2 = GetUnitList(UNIT_LIST_ALLIED_HEROES) allys2 = AbilityExtensions:Filter(allys2, function(b) return not b:IsIllusion() end) - local enemys = npcBot:GetNearbyHeroes(1800,true,BOT_MODE_NONE) + local enemys = npcBot:GetNearbyHeroes(1599,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) -------------------------------------- -- Global high-priorty usage @@ -447,20 +445,7 @@ Consider[3]=function() end end - -- If we're farming - if ( npcBot:GetActiveMode() == BOT_MODE_FARM ) - then - if ( #creeps >= 2 ) - then - if(ManaPercentage>0.5) - then - return BOT_ACTION_DESIRE_LOW,npcBot:GetLocation() - end - end - end - - return BOT_ACTION_DESIRE_NONE, 0; - + return BOT_ACTION_DESIRE_NONE end Consider[6]=function() @@ -478,8 +463,7 @@ Consider[6]=function() local CastRange = ability:GetCastRange(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -532,7 +516,7 @@ Consider[4]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not npcBot:HasScepter() then + if not ability:IsFullyCastable() then return BOT_ACTION_DESIRE_NONE, 0; end diff --git a/ability_item_usage_troll_warlord.lua b/ability_item_usage_troll_warlord.lua index 114c100e..24a54f10 100644 --- a/ability_item_usage_troll_warlord.lua +++ b/ability_item_usage_troll_warlord.lua @@ -26,19 +26,19 @@ local AbilityToLevelUp= Abilities[1], Abilities[2], Abilities[2], - Abilities[5], + Abilities[6], Abilities[2], Abilities[4], Abilities[4], "talent", Abilities[4], - Abilities[5], + Abilities[6], Abilities[1], Abilities[1], "talent", Abilities[1], "nil", - Abilities[5], + Abilities[6], "nil", "talent", "nil", @@ -106,8 +106,7 @@ Consider[1]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -242,8 +241,7 @@ Consider[2]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+0,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -319,8 +317,7 @@ Consider[3]=function() local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -451,7 +448,7 @@ Consider[6]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil and GetUnitToUnitDistance(npcBot,npcEnemy)<=800 and HealthPercentage<=0.2 ) then diff --git a/ability_item_usage_tusk.lua b/ability_item_usage_tusk.lua index ea67d9a4..a1a7eba1 100644 --- a/ability_item_usage_tusk.lua +++ b/ability_item_usage_tusk.lua @@ -104,11 +104,10 @@ Consider[1]=function() local CastRange = 1600; local Damage = ability:GetSpecialValueInt("shard_damage"); local Radius = ability:GetSpecialValueInt( "shard_width" ); - local CastPoint = ability:GetCastPoint()+ability:GetSpecialValueFloat( "delay" ); + local CastPoint = ability:GetCastPoint()--+ability:GetSpecialValueFloat( "delay" ); local Speed = ability:GetSpecialValueInt("shard_speed"); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -207,6 +206,7 @@ end end]] + Consider[2]=function() local abilityNumber=2 @@ -215,21 +215,41 @@ Consider[2]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotMove(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end local CastRange = ability:GetCastRange(); local Damage = ability:GetSpecialValueInt( "snowball_damage" ); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) + if npcBot:HasModifier("tusk_snowball") then + local IsLongRanger = function(ally) + local longRangers = { + "npc_dota_hero_sniper", + "npc_dota_hero_enchantress", + "npc_dota_hero_drow_ranger", + } + return AbilityExtensions:Contains(longRangers, ally:GetUnitName()) + end + local CanCast = function(ally) + return ally:IsIllusion() or not ally:IsInvulnerable() and not AbilityExtensions:CannotBeTargetted(ally) and not AbilityExtensions:MayNotBeSeen(ally) and not AbilityExtensions:DontInterruptAlly(ally) and (not IsLongRanger(ally) or AbilityExtensions:IsSeverelyDisabled(ally)) + end + local radius = ability:GetSpecialValueInt("snowball_windup_radius") + local allys = npcBot:GetNearbyHeroes(radius, false, BOT_MODE_NONE) + allys = AbilityExtensions:Filter(allys, function(t) return not t:IsBot() or AbilityExtensions:NotRetreating(t) end) + allys = AbilityExtensions:Filter(allys, CanCast) + if allys[1] then + return BOT_ACTION_DESIRE_HIGH, allys[1] + end + end + -- Check for a channeling enemy for _,enemy in pairs( enemys ) do @@ -354,8 +374,6 @@ Consider[3]=function() -------------------------------------- -- Generic Variable Setting -------------------------------------- - --local ability=npcBot:GetAbilityByName( "tusk_frozen_sigil" ) - local ability=AbilitiesReal[abilityNumber]; if not ability:IsFullyCastable() then @@ -363,8 +381,7 @@ Consider[3]=function() end - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(1200,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -431,8 +448,7 @@ Consider[6]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -510,7 +526,7 @@ Consider[6]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcTarget = npcBot:GetTarget(); + local npcTarget = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcTarget ~= nil ) then @@ -524,6 +540,41 @@ Consider[6]=function() return BOT_ACTION_DESIRE_NONE, 0 end +local function IsSnowballTarget(t) return t:HasModifier("modifier_tusk_snowball_target") end +local snowballTarget +local function RefreshSnowballTarget() + snowballTarget = AbilityExtensions:First(GetUnitList(UNIT_LIST_ENEMY_HEROES), IsSnowballTarget) +end +RefreshSnowballTarget() + +Consider[7] = function() + local ability = AbilitiesReal[7] + if not ability:IsFullyCastable() or ability:IsHidden() then + return 0 + end + if snowballTarget == nil then + RefreshSnowballTarget() + end + + if AbilityExtensions:HasAbilityRetargetModifier(snowballTarget) and not snowballTarget:IsChanneling() then + return 0 + end + if snowballTarget:IsChanneling() or GetUnitToUnitDistance(snowballTarget, npcBot) >= 600 then + return BOT_ACTION_DESIRE_VERYHIGH + end + local snowballFriends = npcBot:GetNearbyHeroes(100, false, BOT_MODE_NONE) + snowballFriends = AbilityExtensions:Filter(snowballFriends, function (t) + return t:HasModifier("modifier_tusk_snowball_movement_friendly") + end) + if #snowballFriends > 0 and AbilityExtensions:All(snowballFriends, function (t) + return AbilityExtensions:MustBeIllusion(npcBot, t) or AbilityExtensions:GetHealthPercent(t) >= AbilityExtensions:GetHealthPercent(snowballTarget) * 1.5 + end) then + return BOT_ACTION_DESIRE_HIGH + end + return 0 +end + + Consider[4]=function() --A杖大 local abilityNumber=4 @@ -539,8 +590,7 @@ Consider[4]=function() --A杖大 local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -633,7 +683,10 @@ function AbilityUsageThink() then ability_item_usage_generic.PrintDebugInfo(AbilitiesReal,cast) end - ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + local index, target = ability_item_usage_generic.UseAbility(AbilitiesReal,cast) + if index == 2 then + snowballTarget = target + end end function CourierUsageThink() diff --git a/ability_item_usage_undying.lua b/ability_item_usage_undying.lua index 56ef0d7e..7070be80 100644 --- a/ability_item_usage_undying.lua +++ b/ability_item_usage_undying.lua @@ -100,8 +100,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius() local CastPoint = ability:GetCastPoint() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+150,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -245,8 +244,7 @@ Consider[2]=function() local searchcreeps = npcBot:GetNearbyCreeps(Radius,true) local Damage = math.min(#searchcreeps,ability:GetSpecialValueInt("max_units"))*ability:GetSpecialValueInt("damage_per_unit") - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( CastRange+300, false, BOT_MODE_NONE ); local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) @@ -347,8 +345,7 @@ Consider[3]=function() local CastRange = ability:GetCastRange(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+150,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -387,7 +384,7 @@ Consider[3]=function() then if ( npcBot:WasRecentlyDamagedByAnyHero(2) ) then - if(trees1~=nil and #trees>=1 and #enemys>=1) + if(trees~=nil and #trees>=1 and #enemys>=1) then return BOT_ACTION_DESIRE_MODERATE-0.05,GetTreeLocation(trees[#trees]) else @@ -411,7 +408,7 @@ Consider[3]=function() then return BOT_ACTION_DESIRE_MODERATE-0.03, locationAoE.targetloc; end - if(trees1~=nil and #trees>=1) + if(trees~=nil and #trees>=1) then return BOT_ACTION_DESIRE_MODERATE-0.03,GetTreeLocation(trees[#trees]) end @@ -424,7 +421,7 @@ Consider[3]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -471,8 +468,7 @@ Consider[4]=function() local CastRange = ability:GetCastRange(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -511,7 +507,7 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then diff --git a/ability_item_usage_ursa.lua b/ability_item_usage_ursa.lua index 03adc7e4..e679451a 100644 --- a/ability_item_usage_ursa.lua +++ b/ability_item_usage_ursa.lua @@ -90,7 +90,7 @@ Consider[1]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() or not AbilityExtensions:CanMove(npcBot) then + if not ability:IsFullyCastable() or AbilityExtensions:CannotMove(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end @@ -99,12 +99,7 @@ Consider[1]=function() local Radius = ability:GetAOERadius() - 50 local CastPoint = ability:GetCastPoint() - local i=npcBot:FindItemSlot("item_blink") - if(i>=0 and i<=5) - then - blink=npcBot:GetItemInSlot(i) - i=nil - end + local blink = AbilityExtensions:GetAvailableBlink(npcBot) if(blink~=nil and blink:IsFullyCastable()) then CastRange=CastRange+1200 @@ -119,8 +114,7 @@ Consider[1]=function() end end - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -232,8 +226,7 @@ Consider[2]=function() local CastRange = 300 - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -262,9 +255,9 @@ Consider[2]=function() then local npcTarget = npcBot:GetTarget(); local t=npcBot:GetAttackTarget() - if ( npcTarget ~= nil and t~=nil ) + if ( npcTarget ~= nil and t~=nil and npcBot:GetMana() >= AbilitiesReal[2]:GetManaCost() + AbilitiesReal[1]:GetManaCost() ) then - return BOT_ACTION_DESIRE_MODERATE; + return BOT_ACTION_DESIRE_VERYHIGH; end end @@ -326,14 +319,19 @@ Consider[4]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) + if AbilityExtensions:HasScepter(npcBot) then + if not npcBot:IsHexed() and AbilityExtensions:IsSeverelyDisabled(npcBot) and npcBot:GetMana() >= ability:GetManaCost() and #AbilityExtensions:GetNearbyNonIllusionHeroes(1599) > 0 then + return BOT_ACTION_DESIRE_HIGH + end + end + --Try to kill enemy hero if(npcBot:GetActiveMode() ~= BOT_MODE_RETREAT ) then @@ -368,7 +366,7 @@ Consider[4]=function() then local npcTarget = npcBot:GetTarget(); local t=npcBot:GetAttackTarget() - if ( npcTarget ~= nil and t~=nil ) + if ( npcTarget ~= nil and t~=nil )and not npcBot:HasModifier("modifier_stunned") then return BOT_ACTION_DESIRE_MODERATE; end @@ -380,7 +378,7 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then @@ -397,7 +395,6 @@ end AbilityExtensions:AutoModifyConsiderFunction(npcBot, Consider, AbilitiesReal) function AbilityUsageThink() - -- Check if we're already using an ability if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:IsSilenced() ) then diff --git a/ability_item_usage_vengefulspirit.lua b/ability_item_usage_vengefulspirit.lua index 99013499..578b0bbf 100644 --- a/ability_item_usage_vengefulspirit.lua +++ b/ability_item_usage_vengefulspirit.lua @@ -72,10 +72,14 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={function(target) return (npcBot:GetLevel()>=25 and utility.UCanCast(target)) or utility.NCanCast(target) end, - utility.NCanCast, - utility.NCanCast, - utility.UCanCast,} +local CanCast={function(target) + return (npcBot:GetLevel()>=25 and utility.UCanCast(target)) or utility.NCanCast(target) and not AbilityExtensions:HasAbilityRetargetModifier(target) +end, + utility.NCanCast, + utility.NCanCast, + function(target) + return AbilityExtensions:NormalCanCast(target, false, DAMAGE_TYPE_MAGICAL, true) and not target:HasModifier("modifier_item_mirror_shield_delay") and not target:HasModifier("modifier_item_sphere_target") + end} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -101,8 +105,7 @@ Consider[1]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -201,7 +204,7 @@ Consider[1]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcTarget = npcBot:GetTarget(); + local npcTarget = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcTarget ~= nil ) then @@ -230,8 +233,7 @@ Consider[2]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -320,15 +322,14 @@ Consider[4]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or AbilityExtensions:CannotTeleport(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -355,7 +356,7 @@ Consider[4]=function() local tableNearbyEnemyHeroes = npcBot:GetNearbyHeroes( CastRange, true, BOT_MODE_NONE ); for _,npcEnemy in pairs( tableNearbyEnemyHeroes ) do - if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcTarget)>=CastRange-300) + if ( CanCast[abilityNumber]( npcEnemy ) and not enemyDisabled(npcEnemy) and GetUnitToUnitDistance(npcBot,npcEnemy)>=CastRange-300) then local Damage2 = npcEnemy:GetEstimatedDamageToTarget( false, npcBot, 3.0, DAMAGE_TYPE_ALL ); if ( Damage2 > nMostDangerousDamage ) @@ -382,7 +383,7 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcTarget = npcBot:GetTarget(); + local npcTarget = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcTarget ~= nil ) then diff --git a/ability_item_usage_venomancer.lua b/ability_item_usage_venomancer.lua index 8bef23cb..e8859630 100644 --- a/ability_item_usage_venomancer.lua +++ b/ability_item_usage_venomancer.lua @@ -98,8 +98,7 @@ Consider[1]=function() --Target Ability Example local Damage = 25*ability:GetLevel()+5*(-20+30*ability:GetLevel()) -- 75/250/425/600 local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange + 75*#allys,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -231,8 +230,7 @@ Consider[3]=function() --Location AOE Example local CastRange = ability:GetCastRange(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -290,7 +288,7 @@ Consider[3]=function() --Location AOE Example then if ( #creeps >= 2 and (ManaPercentage>0.4 or npcBot:GetMana()>ComboMana)) then - return BOT_ACTION_DESIRE_LOW, utility.RandomInCastRangePoint(npcBot,npcEnemy,CastRange,RandomRange); + return BOT_ACTION_DESIRE_LOW, utility.RandomInCastRangePoint(npcBot,creeps[1],CastRange,RandomRange); end end @@ -337,8 +335,7 @@ Consider[4]=function() local Damage = 0--ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(Radius,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -368,7 +365,7 @@ Consider[4]=function() npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY or npcBot:GetActiveMode() == BOT_MODE_ATTACK ) then - local npcEnemy = npcBot:GetTarget(); + local npcEnemy = AbilityExtensions:GetTargetIfGood(npcBot) if ( npcEnemy ~= nil ) then diff --git a/ability_item_usage_warlock.lua b/ability_item_usage_warlock.lua index 7285ea5c..259f6012 100644 --- a/ability_item_usage_warlock.lua +++ b/ability_item_usage_warlock.lua @@ -73,7 +73,9 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} +local CanCast={utility.NCanCast,function(t) + return t:GetTeam() == npcBot:GetTeam() and AbilityExtensions:AllyCanCast(t) and not t:HasModifier("modifier_ice_blast") or AbilityExtensions:NormalCanCast(t) +end,utility.NCanCast,utility.UCanCast} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -240,8 +242,7 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetDuration()*ability:GetSpecialValueInt("AbilityDamage") - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( CastRange+300, false, BOT_MODE_NONE ); local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) @@ -530,18 +531,6 @@ local upheavelTimer local upheavelLocation local upheavelRadius -local function GetSpellImmuneRemainingTime(target) - local spellImmuneModifiers = { - "modifier_black_king_bar_immune", - "modifier_minotaur_horn_immune", - "modifier_life_stealer_rage", - } - local c = AbilityExtensions:Map(spellImmuneModifiers, function(t) return AbilityExtensions:GetModifierRemainingDuration(t) end) - c = AbilityExtensions:Filter(c, function(t) return t ~= nil end) - c = AbilityExtensions:SortByMaxFirst(c, function(t) return t end) - c = c[1] or 0 - return c -end function AbilityUsageThink() @@ -563,7 +552,7 @@ function AbilityUsageThink() local enemies = npcBot:GetNearbyHeroes(1500, true, BOT_MODE_NONE) enemies = AbilityExtensions:Count(enemies, function(t) return t:HasModifier("modifier_warlock_upheavel") - or GetUnitToLocationDistance(t, upheavelLocation) <= upheavelRadius and GetSpellImmuneRemainingTime(t) <= 1 + or GetUnitToLocationDistance(t, upheavelLocation) <= upheavelRadius and AbilityExtensions:GetMagicImmuneRemainingDuration(t) <= 1 end) if enemies == 0 then if DotaTime() > upheavelTimer + 1.5 then diff --git a/ability_item_usage_weaver.lua b/ability_item_usage_weaver.lua index 5aa59a93..10f179d3 100644 --- a/ability_item_usage_weaver.lua +++ b/ability_item_usage_weaver.lua @@ -99,8 +99,7 @@ Consider[1]=function() local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -273,15 +272,14 @@ Consider[4]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or AbilityExtensions:CannotTeleport(npcBot) then return BOT_ACTION_DESIRE_NONE, 0; end local CastRange = 0; local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_windrunner.lua b/ability_item_usage_windrunner.lua index 88743856..62605fc5 100644 --- a/ability_item_usage_windrunner.lua +++ b/ability_item_usage_windrunner.lua @@ -102,7 +102,7 @@ Consider[3]=function() -------------------------------------- local ability=AbilitiesReal[abilityNumber]; - if not ability:IsFullyCastable() then + if not ability:IsFullyCastable() or npcBot:HasModifier("modifier_windrunner_wind_walk") or npcBot:HasModifier("modifier_shadow_demon_purge_slow") then return BOT_ACTION_DESIRE_NONE, 0; end @@ -183,8 +183,7 @@ Consider[4]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/ability_item_usage_winter_wyvern.lua b/ability_item_usage_winter_wyvern.lua index 53fc04a0..2316ad07 100644 --- a/ability_item_usage_winter_wyvern.lua +++ b/ability_item_usage_winter_wyvern.lua @@ -73,7 +73,33 @@ end -------------------------------------- local cast={} cast.Desire={} cast.Target={} cast.Type={} local Consider ={} -local CanCast={utility.NCanCast,utility.NCanCast,utility.NCanCast,utility.UCanCast} + +local CanCast={utility.NCanCast,utility.NCanCast,function(t) + if not AbilityExtensions:AllyCanCast(t) or AbilityExtensions:MustBeIllusion(npcBot, t) and not AbilityExtensions:IsTempestDouble(t) or not AbilityExtensions:IsHero(t) and not AbilityExtensions:IsLoneDruidBear(t) then + return false + end + if AbilityExtensions:DontInterruptAlly(t) then + if t:HasModifier("modifier_medusa_stone_gaze") and AbilityExtensions:IsRetreating(t) then + return true + end + if t:HasModifier("modifier_monkey_king_fur_army_soldier_in_position") and AbilityExtensions:GetHealthPercent(t) <= 0.35 then + return true + end + return false + end + if t:GetUnitName() == "npc_dota_hero_faceless_void" then + local allUnits = AbilityExtensions:GetNearbyAllUnits(t, 1599) + -- GetUnitList(UNIT_LIST_ALL) + return AbilityExtensions:Any(allUnits, function(t) + return t:HasModifier("modifier_faceless_void_chronosphere_freeze") + end) or AbilityExtensions:Any(t:GetNearbyHeroes(300, true, BOT_MODE_NONE, function(t) + return t:HasModifier("modifier_faceless_void_timelock_freeze") + end)) + end + return AbilityExtensions:AllyCanCast(t) and (not AbilityExtensions:DontInterruptAlly(t) or t:HasModifier("modifier_medusa_stone_gaze") and t:GetActiveMode() == BOT_MODE_RETREAT) and not t:IsChanneling() +end,function(t) + return AbilityExtensions:SpellCanCast(t, true, true) +end} local enemyDisabled=utility.enemyDisabled function GetComboDamage() @@ -367,6 +393,9 @@ Consider[3]=function() local HeroHealth=10000 local allys = npcBot:GetNearbyHeroes( CastRange+300, false, BOT_MODE_NONE ); + allys = AbilityExtensions:Filter(allys, function(t) + return AbilityExtensions:MayNotBeIllusion(npcBot, t) and not AbilityExtensions:CannotBeTargetted(t) and not AbilityExtensions:IsInvulnerable(t) and not AbilityExtensions:CannotBeKilledNormally(t) + end) local WeakestAlly,AllyHealth=utility.GetWeakestUnit(allys) local allys2 = GetUnitList(UNIT_LIST_ALLIED_HEROES) local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) @@ -427,7 +456,7 @@ Consider[3]=function() then for _,npcTarget in pairs( allys ) do - if(npcTarget:GetHealth()/npcTarget:GetMaxHealth()<(0.35+0.4*ManaPercentage)) + if npcTarget:GetHealth()/npcTarget:GetMaxHealth()<(0.35+0.4*ManaPercentage) and npcTarget:WasRecentlyDamagedByAnyHero(3) then if ( CanCast[abilityNumber]( npcTarget ) and not npcTarget:IsChanneling() ) then @@ -441,6 +470,9 @@ Consider[3]=function() end +local function CanBeAffectedByCurse(t) + return AbilityExtensions:SpellCanCast(t, false, false) +end Consider[4]=function() local abilityNumber=4 @@ -478,7 +510,7 @@ Consider[4]=function() if(enemys~=nil and #enemys==1) then - return 0,0 + return 0 end --Try to kill enemy hero diff --git a/ability_item_usage_zuus.lua b/ability_item_usage_zuus.lua index 07687e3d..c7acc4b2 100644 --- a/ability_item_usage_zuus.lua +++ b/ability_item_usage_zuus.lua @@ -17,10 +17,6 @@ local AbilitiesReal ={} ability_item_usage_generic.InitAbility(Abilities,AbilitiesReal,Talents) --- utility.PrintAbilityName(Abilities) -local abilityName = { "zuus_arc_lightning", "zuus_lightning_bolt", "zuus_static_field", "zuus_cloud", "zuus_heavenly_jump", "zuus_thundergods_wrath" } -local abilityIndex = utility.ReverseTable(abilityName) - local AbilityToLevelUp= { @@ -99,8 +95,7 @@ Consider[1]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetSpecialValueInt("arc_damage"); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -238,8 +233,7 @@ Consider[2]=function() local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -252,7 +246,7 @@ Consider[2]=function() -- Check for a channeling enemy for _,enemy in pairs( enemys ) do - if ( enemy:IsChanneling() and CanCast[2]( enemy )) + if ( enemy:IsChanneling() and CanCast[2]( enemy ) and not enemy:HasModifier("modifier_antimage_counterspell")) then return BOT_ACTION_DESIRE_HIGH, enemy,"Target"; end @@ -279,7 +273,7 @@ Consider[2]=function() then for _,enemy in pairs( enemys2 ) do - if ( CanCast[2]( enemy ) ) + if ( CanCast[2]( enemy ) )and not enemy:HasModifier("modifier_antimage_counterspell") and not enemy:HasModifier("modifier_item_lotus_orb_active") and not enemy:HasModifier("modifier_item_blade_mail") then return BOT_ACTION_DESIRE_HIGH, enemy,"Target" end diff --git a/bot_beastmaster.lua b/bot_beastmaster.lua index 9a577f34..00091646 100644 --- a/bot_beastmaster.lua +++ b/bot_beastmaster.lua @@ -1,13 +1,36 @@ local minionutils = dofile( GetScriptDirectory().."/util/NewMinionUtil" ) +local AbilityExtensions = require(GetScriptDirectory().."/util/AbilityAbstraction") + + +local function DiveBombCanCast(target) + return target ~= nil and AbilityExtensions:NormalCanCast(target, false) and not AbilityExtensions:IsSeverelyDisabled(target) +end + +function HawkThink(minion) + local diveBomb = minion:GetAbilityByName("beastmaster_hawk_dive") + if diveBomb:IsHidden() or not diveBomb:IsFullyCastable() then + return + end + + local target = GetBot():GetTarget() + if DiveBombCanCast(target) then + minion:Action_UseAbilityOnEntity(diveBomb, target) + end + local nearbyEnemies = AbilityExtensions:Filter(AbilityExtensions:GetNearbyNonIllusionHeroes(minion), DiveBombCanCast) + if #nearbyEnemies > 0 then + minion:Action_UseAbilityOnEntity(nearbyEnemies[1], target) + end +end + function MinionThink( hMinionUnit ) if minionutils.IsValidUnit(hMinionUnit) then if minionutils.IsHawk(hMinionUnit:GetUnitName()) then - --minionutils.HawkThink(hMinionUnit); + HawkThink(hMinionUnit) elseif minionutils.IsMinionWithSkill(hMinionUnit:GetUnitName()) then minionutils.MinionWithSkillThink(hMinionUnit); else - minionutils.IllusionThink(hMinionUnit); + minionutils.IllusionThink(hMinionUnit) end end end \ No newline at end of file diff --git a/bot_brewmaster.lua b/bot_brewmaster.lua index cf552f5a..17b4d4a6 100644 --- a/bot_brewmaster.lua +++ b/bot_brewmaster.lua @@ -15,6 +15,13 @@ local castSCDesire = 0; local castCHDesire = 0; local castDBDesire = 0; local radius = 1000; +local abilityCH +local abilityCY +local abilityDB +local abilityDM +local abilityHB +local abilitySC +local abilityWW function MinionThink( hMinionUnit ) @@ -262,7 +269,7 @@ end function ConsiderDM(hMinionUnit) - if not abilityDM:IsFullyCastable() or abilityDM:IsHidden() then + if abilityDM == nil or not abilityDM:IsFullyCastable() or abilityDM:IsHidden() then return BOT_ACTION_DESIRE_NONE, 0; end @@ -289,7 +296,7 @@ end function ConsiderCY(hMinionUnit) - if not abilityCY:IsFullyCastable() or abilityCY:IsHidden() then + if abilityCY == nil or not abilityCY:IsFullyCastable() or abilityCY:IsHidden() then return BOT_ACTION_DESIRE_NONE, 0; end @@ -347,7 +354,7 @@ end function ConsiderCorrosiveHaze(hMinionUnit) - if not abilityCH:IsFullyCastable() or abilityCH:IsHidden() or not bot:HasScepter() then + if abilityCH == nil or not abilityCH:IsFullyCastable() or abilityCH:IsHidden() or not bot:HasScepter() then return BOT_ACTION_DESIRE_NONE, 0; end @@ -397,7 +404,7 @@ end function ConsiderWW(hMinionUnit) - if not abilityWW:IsFullyCastable() or abilityWW:IsHidden() then + if abilityWW == nil or not abilityWW:IsFullyCastable() or abilityWW:IsHidden() then return BOT_ACTION_DESIRE_NONE; end @@ -415,7 +422,7 @@ end function ConsiderSlithereenCrush(hMinionUnit) -- Make sure it's castable - if ( not abilitySC:IsFullyCastable() or abilitySC:IsHidden() or not bot:HasScepter() ) then + if abilitySC == nil or ( not abilitySC:IsFullyCastable() or abilitySC:IsHidden() or not bot:HasScepter() ) then return BOT_ACTION_DESIRE_NONE; end @@ -436,7 +443,7 @@ end function ConsiderHB(hMinionUnit) - if not abilityHB:IsFullyCastable() or abilityHB:IsHidden() then + if abilityHB == nil or not abilityHB:IsFullyCastable() or abilityHB:IsHidden() then return BOT_ACTION_DESIRE_NONE, 0; end @@ -457,7 +464,7 @@ end function ConsiderDrunkenBrawler(hMinionUnit) -- Make sure it's castable - if ( not abilityDB:IsFullyCastable() or abilityDB:IsHidden() or not bot:HasScepter() ) then + if abilityDB == nil or ( not abilityDB:IsFullyCastable() or abilityDB:IsHidden() or not bot:HasScepter() ) then return BOT_ACTION_DESIRE_NONE; end diff --git a/bot_earth_spirit.lua b/bot_earth_spirit.lua index e6db55c8..964bf03f 100644 --- a/bot_earth_spirit.lua +++ b/bot_earth_spirit.lua @@ -4,7 +4,6 @@ local MoveDesire = 0; function MinionThink( hMinionUnit ) - if hMinionUnit:IsIllusion() then local target = bot:GetAttackTarget() AttackDesire, Target = ConsiderAttack(hMinionUnit, target) diff --git a/bot_elder_titan.lua b/bot_elder_titan.lua index a697b496..c559c1c6 100644 --- a/bot_elder_titan.lua +++ b/bot_elder_titan.lua @@ -136,7 +136,6 @@ function ConsiderSlithereenCrush(hMinionUnit) -- If we're going after someone if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or - npcBot:GetActiveMode() == BOT_MODE_GANK or npcBot:GetActiveMode() == BOT_MODE_ATTACK or npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY ) then diff --git a/bot_ember_spirit.lua b/bot_ember_spirit.lua new file mode 100644 index 00000000..73f57f9f --- /dev/null +++ b/bot_ember_spirit.lua @@ -0,0 +1,9 @@ +local minionUtility = dofile( GetScriptDirectory().."/util/NewMinionUtil" ) + +function MinionThink(minion) + if minion:IsIllusion() then + minionUtility.IllusionThink(minion) + elseif minion:GetUnitName() == "npc_dota_ember_spirit_remnant" then + minionUtility.CantBeControlledThink(minion) + end +end diff --git a/bot_lone_druid.lua b/bot_lone_druid.lua index a857db55..dd5b6318 100644 --- a/bot_lone_druid.lua +++ b/bot_lone_druid.lua @@ -10,7 +10,6 @@ local ProxRange = 1300; local bearState = ""; local BearItem = { - "item_stout_shield", "item_boots", "item_orb_of_venom", "item_blight_stone" @@ -162,7 +161,6 @@ function ConsiderSavageRoar(hMinionUnit) -- If we're going after someone if ( npcBot:GetActiveMode() == BOT_MODE_ROAM or - npcBot:GetActiveMode() == BOT_MODE_GANK or npcBot:GetActiveMode() == BOT_MODE_ATTACK or npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY ) diff --git a/bot_razor.lua b/bot_razor.lua new file mode 100644 index 00000000..4a294bea --- /dev/null +++ b/bot_razor.lua @@ -0,0 +1,48 @@ +local bot = GetBot() +local AttackDesire = 0 +local MoveDesire = 0 + + +function MinionThink(hMinionUnit) + if hMinionUnit:IsIllusion() then + local target = bot:GetAttackTarget() + AttackDesire, Target = ConsiderAttack(hMinionUnit, target) + MoveDesire, Location = ConsiderMove(hMinionUnit, target) + + if AttackDesire > 0 then + hMinionUnit:Action_AttackUnit(Target, true) + return + end + + if MoveDesire > 0 then + hMinionUnit:Action_MoveToLocation(Location) + return + end + + end + +end + +function ConsiderAttack(hMinionUnit, target) + + if target ~= nil and target:IsAlive() and not target:IsInvulnerable() then + return BOT_ACTION_DESIRE_HIGH, target; + end + + return BOT_ACTION_DESIRE_NONE, nil; + +end + +function ConsiderMove(hMinionUnit, target) + + if AttackDesire > 0 then + return BOT_ACTION_DESIRE_NONE, 0; + end + + if target == nil then + return BOT_ACTION_DESIRE_HIGH, bot:GetLocation(); + end + + return BOT_ACTION_DESIRE_NONE, 0; + +end diff --git a/bot_templar_assassin.lua b/bot_templar_assassin.lua index 7a250ed4..968c3a6a 100644 --- a/bot_templar_assassin.lua +++ b/bot_templar_assassin.lua @@ -1,23 +1,36 @@ -local npcBot = nil; +local AbilityExtensions = require(GetScriptDirectory().."/util/AbilityAbstraction") -function MinionThink( hMinionUnit ) - - if npcBot == nil then npcBot = GetBot(); end - -if not hMinionUnit:IsNull() and hMinionUnit ~= nil then - if hMinionUnit:GetUnitName() == "npc_dota_templar_assassin_psionic_trap" and hMinionUnit ~= nil and hMinionUnit:GetHealth() > 0 - then - local abilitySTP = hMinionUnit:GetAbilityByName( "templar_assassin_self_trap" ); - local abilityTP = npcBot:GetAbilityByName( "templar_assassin_trap" ); - local nRadius = abilitySTP:GetSpecialValueInt("trap_radius"); - local nRange = npcBot:GetAttackRange(); - local Enemies = hMinionUnit:GetNearbyHeroes(nRadius, true, BOT_MODE_NONE); - local Allies = hMinionUnit:GetNearbyHeroes(2*nRadius, false, BOT_MODE_NONE); - local distance = GetUnitToUnitDistance(npcBot, hMinionUnit); - if Enemies ~= nil and #Enemies >=1 and ( distance < 800 or Allies ~= nil ) and abilityTP:IsFullyCastable() then - npcBot:Action_UseAbility( abilityTP ); - return; - end +local trapTable = GetBot().trapTable +local function GetCastTime(trap) + if trapTable ~= nil then + return trapTable[AbilityExtensions:ToStringVector(trap:GetLocation())] end end + +function MinionThink( hMinionUnit ) + local npcBot = GetBot() + if not hMinionUnit:IsNull() and hMinionUnit ~= nil then + if hMinionUnit:GetUnitName() == "npc_dota_templar_assassin_psionic_trap" and hMinionUnit:GetHealth() > 0 + then + local abilitySTP = hMinionUnit:GetAbilityByName( "templar_assassin_self_trap" ); + local abilityTP = npcBot:GetAbilityByName( "templar_assassin_trap" ); + local nRadius = abilitySTP:GetSpecialValueInt("trap_radius"); + local nRange = npcBot:GetAttackRange(); + local Enemies = hMinionUnit:GetNearbyHeroes(nRadius, true, BOT_MODE_NONE); + local Allies = hMinionUnit:GetNearbyHeroes(2*nRadius, false, BOT_MODE_NONE); + local distance = GetUnitToUnitDistance(npcBot, hMinionUnit); + local attackedTargets = AbilityExtensions:Filter(Enemies, function(t) return t:GetAttackTarget() ~= nil end) + attackedTargets = AbilityExtensions:Map(Enemies, function(t) return t:GetAttackTarget() end) + if Enemies ~= nil and #Enemies >=1 and ( distance < 800 or Allies ~= nil ) and abilityTP:IsFullyCastable() then + local castTime = GetCastTime(hMinionUnit) or DotaTime() + if DotaTime() - castTime < 1 then + if AbilityExtensions:IsRetreating(npcBot) or AbilityExtensions:Contains(attackedTargets, hMinionUnit) then + npcBot:Action_UseAbility( abilityTP ) + end + else + npcBot:Action_UseAbility( abilityTP ) + end + end + end + end end diff --git a/bot_undying.lua b/bot_undying.lua index 10d710d0..868631f7 100644 --- a/bot_undying.lua +++ b/bot_undying.lua @@ -7,7 +7,12 @@ function MinionThink( hMinionUnit ) elseif minionutils.CantBeControlled(hMinionUnit:GetUnitName()) then minionutils.CantBeControlledThink(hMinionUnit); else + print("unrecognised minion: "..hMinionUnit:GetUnitName()) return; end end -end \ No newline at end of file +end + +function CourierUsageThink() + +end \ No newline at end of file diff --git a/bot_weaver.lua b/bot_weaver.lua index 10d710d0..4e650ef2 100644 --- a/bot_weaver.lua +++ b/bot_weaver.lua @@ -1,6 +1,10 @@ local minionutils = dofile( GetScriptDirectory().."/util/NewMinionUtil" ) function MinionThink( hMinionUnit ) + local name = hMinionUnit:GetUnitName() + if string.match(name, "npc_dota_weaver_swarm") then + return + end if minionutils.IsValidUnit(hMinionUnit) then if hMinionUnit:IsIllusion() then minionutils.IllusionThink(hMinionUnit); diff --git a/bot_zuus.lua b/bot_zuus.lua index 3e48f437..b92eb8db 100644 --- a/bot_zuus.lua +++ b/bot_zuus.lua @@ -1,6 +1,10 @@ local minionutils = dofile( GetScriptDirectory().."/util/NewMinionUtil" ) function MinionThink( hMinionUnit ) + local name = hMinionUnit:GetUnitName() + if name == "npc_dota_zeus_cloud" then + return + end if minionutils.IsValidUnit(hMinionUnit) then if hMinionUnit:IsIllusion() then minionutils.IllusionThink(hMinionUnit); diff --git a/changelog/changelog_en.txt b/changelog/changelog_en.txt index 2fcdc64b..db9f924f 100644 --- a/changelog/changelog_en.txt +++ b/changelog/changelog_en.txt @@ -37,14 +37,14 @@ v1.1d(2017.5.7) 5.Improved spirit breaker's charge usage, he will use it more carefully. 6.Improved crystal maiden's nova usage. 7.AI will not pick rune when human player coming. -8.Improved usage and puchase of Anti-hidden item. +8.Improved usage and purchase of Anti-hidden item. V1.1e (2017.5.16) 1. Updated the 7.06 item recipe. 2. Now all heroes will try to purchase six items. 3. Optimized the item building of some heroes. 4. Improved the warding system (thanks to Improved Default Bots) 5. Fixed the bot will use tower glyph after tower destroyed. -6. Fixed the Queen of pain stucked in the woods. +6. Fixed the Queen of pain stuck in the woods. 7. Fixed the Axe the probability of stuck after blink. V1.1f (2017.5.21) 1. Added the Spectre, Sven, winter wyvern, pugna, antimage, faceless void. @@ -73,14 +73,14 @@ Now the program uses the GPLv3 open source protocol license, the use of the sour v1.1h(2017.7.10) 1. Added warlock, windrunner, omniknight, tiny, death prophet. 2. Fixed lich can not level up talents correctly. -3. Fixed lich can not bulid items correctly. +3. Fixed lich can not build items correctly. 4. Fixed skywrathmage,lina,huskar,abaddon can't use ability. 5. Fixed a bug where the necrolyte would cause the game to crash. 6. Improved some heroes item building. 7. Improved pugna's decrepify usage. 8. Fixed the bug that did not properly sell the other boots after buying the travel boots. 9. Improved the ability usage of some heroes. -10. Earthshaker will now buy ahalilius scepter. +10. Earthshaker will now buy aghanim's scepter. 11. Fixed silencer do not use ultimate ability. 12. Removed debugging information from the release version 13. Fixed the bug of contending for the courier. @@ -89,7 +89,7 @@ v1.2(2017.8.23) 1. Added Team Gank system: AI will buy and use the smoke to kill the enemy hero 2. Improve the Rune system, AI will recognize the type of the rune, and consider whether it is suitable to pick up the rune. AI will leave the rune to the most suitable hero. AI will avoid possible dangers. 3. Improve the lane assignment system, AI team will first consider the lane of human players, and then select the most suitable route. Thanks BOT EXPERIMENT author: Arizona, I used part of its function. -4. Improve the item purchase systeam, AI will ensure their own security before going to sideshop. +4. Improve the item purchase system, AI will ensure their own security before going to sideshop. 5. Improve the Shrine usage, AI will be waiting for the nearby human players before using shrine. (not tested.) 6. Improve the use of the courier, the courier will try to escape the danger zone. The courier will pick up the items in advance to save time. The courier may wait more time when the human player uses it. 7. Improve the use of tower Glyph. @@ -110,12 +110,12 @@ v1.2(2017.8.23) 22. Fixed spirit breaker wrongly calculate the enemy power in some cases. 23. Fixed winter wyvern wrongly calculation damage caused by the use of 4 abilitys 24. Fixed part of the hero can not use the ability to kill jungle creeps. -25. Improve Faceless void to use ult ablility better, it will avoid affecting friendly heroes. +25. Improve Faceless void to use ult ability better, it will avoid affecting friendly heroes. 26. Improve Bane to use nightmare better, to avoid interfering friendly heroes. -27. Improve slark to use ult ablility better, it will be more likely to use this ability when attacking. -28. Improve venovenomancer to use ability 3 better, it will be more active to damage enemy heroes -29. Improve sven to use ablility 1 better, it will be less used to clear the lane. -30. Improve warlock to use ablility 3 better, it will use this ability later +27. Improve slark to use ult ability better, it will be more likely to use this ability when attacking. +28. Improve venomancer to use ability 3 better, it will be more active to damage enemy heroes +29. Improve sven to use ability 1 better, it will be less used to clear the lane. +30. Improve warlock to use ability 3 better, it will use this ability later 31. Improve riki to use ability 2 more often, it will be more active consumption of enemy heroes 32. Improve axe to use ability 2 better, it will not use the abilitys before using the blink. 33. Improve necrolyte to use ability 2 better, it will use the skills in more cases @@ -134,7 +134,7 @@ V1.2b(2017.10.2) 7.Fixed can not correctly buy items in secret shops and side shops. 8.Fixed Life stealer will use ultimate ability to itself, thus solving the stuck problem 9.Improved Leshrac to use ability 2 better. -10.Improved Undying to use ablility 1 more accurate +10.Improved Undying to use ability 1 more accurate 11.Improved rune pick up in game starting. 12.Improved the purchase time of gem, and now a team will only buy a gem 13.Improved ability build of Venomancer. @@ -186,7 +186,7 @@ v1.4c (2018.2.28) 1.Improve the lineup selection, now AI will consider the player's heroic position to build a team with one hero in each position. (This change is done by DblTap, thanks for his effort! His Steam link: http://steamcommunity.com/profiles/76561197967823929/ Github link: https://github.com/adamqqqplay/dota2ai/pull/3) 2.Fixed some bugs. v1.4d (2018.3.3) -1. Improved Lane assaignment, now AI will choose more suitable for their own lane, and where possible, give player the lane. +1. Improved Lane assignment, now AI will choose more suitable for their own lane, and where possible, give player the lane. 2. Fixed AI can not choose all implemented heroes. 3. Improve: Now support heroes will give priority to ward on their own lanes. 4. Fixed heroes can not switch power treads. @@ -221,15 +221,15 @@ v1.4f(2018.3.25) Commit by zmcmcc 9. Updated the Treant's item and ability building. 10. Updated the Medusa's item and ability building. v1.4g(2018.3.25) commit by zmcmcc -11.Fixed some bugs casued by former updates. +11.Fixed some bugs caused by former updates. v1.4h(2018.3.31) committed by zmcmcc 1. Updated the hero selection and role allocation. Bots will try to avoid picking heros with duplicated roles. Also slightly changed the hero selection pace. now ally bots will not wait until you pick a hero, but the duration of two picks was slightly prolonged. 2. Temporarily remove these heros: Alchemist, Antimage, Spectre. 3. Get Chen back. -4. Optimized the Captian Mode. Now if you let Bots to ban/pick, they will try to ban/pick with the same hero pool as in AP mode, and will pick in this order: Offlaner, support1, midlaner,support2,safelane carry. I also try to let them have a 311 distribution, like professional game(If the feedback is bad,it's easy to go back to 212). +4. Optimized the Captain Mode. Now if you let Bots to ban/pick, they will try to ban/pick with the same hero pool as in AP mode, and will pick in this order: Offlaner, support1, midlaner, support2, safelane carry. I also try to let them have a 311 distribution, like professional game(If the feedback is bad,it's easy to go back to 212). Two important things:a.If you are the captain, please follow the Offlaner, support1, midlaner,support2,safelane carry order to pick! The bots will only go to the right place in this case. b.In some extreme cases bots will pick two same heros(I tested 15 games, one occurs). If that happened, just quit and start another game... 5. Now bots will be laning more peacefully in the first 6-7 minutes without frequent team fight in mid lane. -6. The following heros are either in item building, ability usage or bug fixed: Batrider, Centaur, Chen, Death prophet, Disruptor, Dragon kignt, Faceless void, Huskar, jakiro, Juggernaut, Legion commander, Leshrac, Lina, Luna, Mirana, Necrolyte, Phantom assassin, Pudge, Riki, Sniper, Sven, Tidehunter, Tiny, Treant, Undying, Windrunner, Zeus. +6. The following heroes are either in item building, ability usage or bug fixed: Batrider, Centaur, Chen, Death prophet, Disruptor, Dragon kignt, Faceless void, Huskar, jakiro, Juggernaut, Legion commander, Leshrac, Lina, Luna, Mirana, Necrolyte, Phantom assassin, Pudge, Riki, Sniper, Sven, Tidehunter, Tiny, Treant, Undying, Windrunner, Zeus. 7. Fixed some bugs. v1.5(2018.4.8) committed by zmcmcc Thanks the author of Bot Experiment Master, Arizona Fauzie。 I used and modified part of his code. @@ -247,13 +247,13 @@ Thanks the author of Bot Experiment Master, Arizona Fauzie。 I used and modifie v1.5b(2018.4.13) committed by zmcmcc 1. Added new hero Outworld Destroyer, Naga Siren, Terrorblade and Templar Assassin. 2. Now if bots didn't choose a safe lane support, the other support will buy the courier. -3. Some heros will now purchase Aeon Disk. +3. Some heroes will now purchase Aeon Disk. 4. Fixed the bug that bots will pick duplicated heroes in Captain mode. 5. Slightly adjust the ability usage of Centaur, Slardar, Ursa etc. so that they are less likely to miss their stuns. -6. Rewrite the ability usage of skeleton king. Althogh he still can't use his third ability correctly, he has better ability use now. +6. Rewrite the ability usage of skeleton king. Although he still can't use his third ability correctly, he has better ability use now. 7. Rewrite the ability usage of pugna. Now his ult still has some problems(Similar to SB and ET) but has better ability use now. 8. Rewrite the ability usage of tidehunter. Now he can use gush correctly. -v1.5c(2018.4.19) commited by zmcmcc +v1.5c(2018.4.19) committed by zmcmcc 1. Added new hero weaver and shadow demon. However, he cannot use his shukuchi like human. 2. Added recent created heroes in Captain mode. 3. Fixed a bug that Witch Doctor, Lina and Oracle cannot buy items.(May also be the reason why sometime bots didn't buy courier). @@ -264,7 +264,7 @@ v1.5c(2018.4.19) commited by zmcmcc 8. Fixed a bug that bots buy couriers in 3 minutes and don't release it. Now if bots don't buy courier in the beginning, it means they will never buy it. Buy one by yourself then(lol). v1.5d(2018.4.27) Update item building of Dota2 v7.14 -v1.5e(2018.5.6) commit by zmcmcc +v1.5e(2018.5.6) committed by zmcmcc 1. Added new hero Phantom Lancer, Troll Warlord and Nyx assassin. For now NA cannot use burrow. 2. Kunkka is back with better ability use(not perfect though). 3. Temporarily removed Tiny due to his third skill bugs. @@ -273,7 +273,7 @@ v1.5e(2018.5.6) commit by zmcmcc 6. Further optimized the usage of stomp-like abilities. Now enemies' movement speed and cast delay will be better considered. 7. Added judgement of whether stuck on cliff for broodmother, slark and earth spirit. 8. Fixed some bugs caused by v7.14. -v1.5f(2018.5.16) commit by zmcmcc +v1.5f(2018.5.16) committed by zmcmcc 1. Added new heroes Tusk, Shredder and Furion. 2. Optimized ability usage of TA, QoP, Underlord, Disruptor, Wind Runner, Sniper, NA and Drow Ranger. 3. FIxed some bugs. @@ -288,7 +288,7 @@ V1.5g (2018.6.6) 7. Fixed the issue that the Timber could not use skills 8. Fixed the issue that the Templar Assassins could not use the ultimate ability. 9. Try to fix the problem that Troll warlord will not be able to use abilities properly. -10. Optimize the useage of Weaver's ultimate ability, and now it will use this ability to offset a lot of damage. +10. Optimize the usage of Weaver's ultimate ability, and now it will use this ability to offset a lot of damage. 11. Fixed the problem of bristleback can not purchasing items. 12. Add Invoker's position to the middle to fix the problem. 13. Now AI will buy more TP and dust. @@ -319,7 +319,7 @@ V1.6e(2019.10.13) 5. Optimize the ability using of Doom and Arc Warden. 6. Temporarily closed the team roaming system. 7. Remove Monkey King from the lineup. -8. Warlock will now cancel the channling of 3rd ability at the appropriate time. +8. Warlock will now cancel the channeling of 3rd ability at the appropriate time. v1.6f (2019.12.19) 1. Update the item building of 7.23. 2. Update warding location of 7.23. @@ -338,7 +338,7 @@ v1.7.1 (2021.04.10) Updated by AaronSong321 7. Remove courier purchase; 8. Fix some heroes fail to add some of their abilities according to version 7.28; 9. Fix TA doesn't purchase any boots; -10. Change the ability usage of CM, AM, and Zeus. +10. Change ability usage of CM, AM. v1.7.2 (2021.04.14) Updated by AaronSong321 1. Update to support 7.29. 2. Fixed the ability usage of alchemist, earth spirit, leshrac, broodmother, lich, lycan, medusa, TA. @@ -348,9 +348,9 @@ v1.7.2 (2021.04.14) Updated by AaronSong321 6. Modify furion's sprout not to block friend melee heroes; 7. Add better behaviour to antimage abilities; v1.7.3 (2021.04.26) Updated by AaronSong321 -1. Fix rune mode; +1. Temporarily remove rune mode; 2. Add battle power evaluation of illusion; 3. Change ability building tree of Chen, Dazzle, Kotl; -4. Implement Life_stealer, Dragon_knight, Leshrac, Magnataur, Phantom_assassin; +4. Implement Life_stealer, Dragon_knight, Leshrac, Magnataur, Phantom_assassin shard abilities; 5. Try to improve Kunkka’s x-mark combo; 6. Fix bugs in Alchemist, Bane, Kunkka; \ No newline at end of file diff --git a/changelog/changelog_zh_cn.txt b/changelog/changelog_zh_cn.txt index c4ea4e1f..801743e9 100644 --- a/changelog/changelog_zh_cn.txt +++ b/changelog/changelog_zh_cn.txt @@ -341,17 +341,17 @@ v1.7.1 (2021.04.10) Updated by AaronSong321 7. 移除了信使购买; 8. 修复了一些英雄无法根据7.28版本升级技能的问题; 9. 修复了圣堂刺客不购买鞋子的问题; -10. 改进了冰女,敌法师,宙斯使用技能的时机. +10. 改进了冰女,敌法师使用技能的时机. v1.7.2 (2021.04.14) Updated by AaronSong321 1. 更新以支持7.29版本; 2. 修复炼金术士,土猫,老鹿,育母蜘蛛,巫妖,狼人,美杜莎,圣堂刺客的技能使用; 3. 修复末日和狼人的物品购买; 4. 修改技能升级模式,以便在游戏时重新加载脚本不会破坏技能升级和物品购买; 5. 尝试自动升级27-30级的天赋; -6. 先知的发芽现在不会阻挡友方米波; +6. 先知的发芽现在不会阻挡友方近战英雄; 7. 改进敌法师的技能使用模式; v1.7.3 (2021.04.26) Updated by AaronSong321 -1. 修复神符模式; +1. 暂时移除神符模式; 2. 增加幻象的战斗值检测; 3. 修改了这些英雄的技能构建:陈,戴泽,光之守卫; 4. 实现了这些英雄的技能使用:食尸鬼,龙骑士,老鹿,猛犸,幻影刺客; diff --git a/dev/DEV_ability_item_usage_normal2.lua b/dev/DEV_ability_item_usage_normal2.lua index 06227cf4..50dded59 100644 --- a/dev/DEV_ability_item_usage_normal2.lua +++ b/dev/DEV_ability_item_usage_normal2.lua @@ -264,8 +264,7 @@ function Consider1() --Target Ability Example local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -466,8 +465,7 @@ function Consider2() --Target AOE Ability Example local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) @@ -611,8 +609,7 @@ function Consider3() --Location AOE Example local Damage = ability:GetAbilityDamage(); local Radius = ability:GetAOERadius() - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/dev/DEV_ability_item_usage_skeleton_king.lua b/dev/DEV_ability_item_usage_skeleton_king.lua index 9623a437..a37fb543 100644 --- a/dev/DEV_ability_item_usage_skeleton_king.lua +++ b/dev/DEV_ability_item_usage_skeleton_king.lua @@ -102,8 +102,7 @@ Consider[1]=function() --Target Ability Example local CastRange = ability:GetCastRange(); local Damage = ability:GetAbilityDamage(); - local HeroHealth=10000 - local CreepHealth=10000 + local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ); local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) diff --git a/hero_selection.lua b/hero_selection.lua index 038d3dcc..598e884b 100644 --- a/hero_selection.lua +++ b/hero_selection.lua @@ -311,7 +311,7 @@ local hero_pool_test = { -- "npc_dota_hero_naga_siren", -- "npc_dota_hero_shadow_demon", } ---recording implemented bots, using in CM mode. +--recording implemented bots, used in CM mode. local allBotHeroes = { "npc_dota_hero_abaddon", "npc_dota_hero_alchemist", @@ -349,7 +349,7 @@ local allBotHeroes = { "npc_dota_hero_enchantress", "npc_dota_hero_enigma", "npc_dota_hero_earthshaker", - --"npc_dota_hero_ember_spirit", + "npc_dota_hero_ember_spirit", "npc_dota_hero_faceless_void", "npc_dota_hero_furion", @@ -458,6 +458,7 @@ local hero_pool_position_1 = { } local hero_pool_position_2 = { "npc_dota_hero_leshrac", + "npc_dota_hero_ember_spirit", "npc_dota_hero_dragon_knight", "npc_dota_hero_huskar", "npc_dota_hero_zuus", @@ -914,7 +915,7 @@ function IsHumanPresentInGame() return false; end -local function IsHumanDonePickingFirstSlot() +function IsHumanDonePickingFirstSlot() if GetTeam() == TEAM_RADIANT then for _,id in pairs(GetTeamPlayers(GetTeam())) do if IsPlayerBot(id) == false and GetSelectedHeroName(id) ~= "" then @@ -930,7 +931,7 @@ local function IsHumanDonePickingFirstSlot() end end -local function IsHumanPlayerInRadiant1Slot() +function IsHumanPlayerInRadiant1Slot() if GetTeam() == TEAM_RADIANT then for i,id in pairs(GetTeamPlayers(GetTeam())) do if i == 1 and IsPlayerBot(id) == false then @@ -1010,7 +1011,7 @@ end function GetPositionedHero(team, selectedHeroes) --Fill positions in random order local positionCounts = GetPositionCounts( team ); - local postion + local position repeat position=RandomInt(1,5); until(positionCounts[position] == 0) @@ -1060,7 +1061,7 @@ end -- Returns a hero from the hero_pool_test pool function GetHeroInTest(selectedHeroes) -- Step through the "hero_pool_test" pool allocating them in order. This function will error if the pool is too small, but it's not for general use. - + local hero repeat hero = hero_pool_test[1] table.remove(hero_pool_test,1) @@ -1511,7 +1512,7 @@ function IsUnavailableHero(name) return false; end --Check if a hero hasn't implemented yet -function IsUnImplementedHeroes() +function IsUnImplementedHeroes(name) for _,unh in pairs(UnImplementedHeroes) do if name == unh then diff --git a/item_purchase_abaddon.lua b/item_purchase_abaddon.lua index cc24b2a2..14a45b85 100644 --- a/item_purchase_abaddon.lua +++ b/item_purchase_abaddon.lua @@ -10,22 +10,14 @@ local ItemsToBuy = "item_tango", "item_quelling_blade", "item_enchanted_mango", - "item_branches", - "item_branches", - "item_magic_stick", - "item_recipe_magic_wand", --大魔棒7.14 + "item_magic_wand", "item_boots", "item_bracer", "item_energy_booster", "item_mekansm", --梅肯 "item_vladmir", --祭品7.21 - "item_buckler", - "item_recipe_guardian_greaves", --卫士胫甲 - "item_hood_of_defiance", --挑战 - "item_ring_of_regen", - "item_recipe_headdress", - "item_branches", - "item_recipe_pipe", --笛子 + "item_guardian_greaves", --卫士胫甲 + "item_pipe", --笛子 "item_ultimate_scepter", --蓝杖 "item_lotus_orb" --清莲宝珠 } diff --git a/item_purchase_abyssal_underlord.lua b/item_purchase_abyssal_underlord.lua index 2c666ad2..40548476 100644 --- a/item_purchase_abyssal_underlord.lua +++ b/item_purchase_abyssal_underlord.lua @@ -10,8 +10,7 @@ local ItemsToBuy = "item_tango", "item_quelling_blade", "item_enchanted_mango", - "item_enchanted_mango", - "item_buckler", --玄冥盾牌 + -- "item_buckler", --玄冥盾牌 "item_boots", "item_magic_wand", --大魔棒7.14 "item_bracer", @@ -19,11 +18,8 @@ local ItemsToBuy = "item_mekansm", --梅肯 "item_hood_of_defiance", --挑战 "item_crimson_guard", --赤红甲 - "item_ring_of_regen", - "item_recipe_headdress", - "item_branches", - "item_recipe_pipe", --笛子 - "item_recipe_guardian_greaves", --卫士胫甲 + "item_pipe", --笛子 + "item_guardian_greaves", --卫士胫甲 "item_lotus_orb", --清莲宝珠 --"item_radiance", --辉耀 "item_shivas_guard" --希瓦 diff --git a/item_purchase_alchemist.lua b/item_purchase_alchemist.lua index 0a218536..c9b199db 100644 --- a/item_purchase_alchemist.lua +++ b/item_purchase_alchemist.lua @@ -15,19 +15,10 @@ local ItemsToBuy = "item_armlet", --臂章 "item_blink", "item_black_king_bar", --BKB - "item_mithril_hammer", - "item_belt_of_strength", - "item_recipe_basher", --晕锤7.14 - "item_platemail", - "item_hyperstone", - "item_chainmail", - "item_recipe_assault", --强袭 - "item_javelin", - "item_mithril_hammer", --电锤7.14 - "item_hyperstone", - "item_recipe_mjollnir", --大电锤 - "item_vanguard", - "item_recipe_abyssal_blade", --大晕 + "item_basher", --晕锤7.14 + "item_assault", --强袭 + "item_mjollnir", --大电锤 + "item_abyssal_blade", --大晕 "item_travel_boots", } diff --git a/item_purchase_ancient_apparition.lua b/item_purchase_ancient_apparition.lua index ffefc69c..46ed835c 100644 --- a/item_purchase_ancient_apparition.lua +++ b/item_purchase_ancient_apparition.lua @@ -12,9 +12,9 @@ local ItemsToBuy = "item_branches", "item_boots", "item_flask", - "item_recipe_magic_wand", + "item_magic_wand", "item_null_talisman", - "item_ring_of_basilius", + -- "item_ring_of_basilius", "item_energy_booster", "item_glimmer_cape", --微光 "item_ghost", diff --git a/item_purchase_arc_warden.lua b/item_purchase_arc_warden.lua index 053d17b1..b3691aee 100644 --- a/item_purchase_arc_warden.lua +++ b/item_purchase_arc_warden.lua @@ -15,15 +15,13 @@ local ItemsToBuy = "item_hand_of_midas", --点金 "item_maelstrom", --电锤7.14 "item_invis_sword", --隐刀 - "item_hyperstone", - "item_recipe_mjollnir", --大雷锤 - "item_recipe_travel_boots", --飞鞋 + "item_mjollnir", --大雷锤 + "item_ravel_boots", --飞鞋 "item_ultimate_orb", "item_recipe_silver_edge", --大隐刀 "item_orchid", --紫苑 "item_black_king_bar", --BKB - "item_hyperstone", - "item_recipe_bloodthorn", --血棘 + "item_bloodthorn", --血棘 "item_butterfly" --蝴蝶 } diff --git a/item_purchase_bane.lua b/item_purchase_bane.lua index 8675f621..8a64d498 100644 --- a/item_purchase_bane.lua +++ b/item_purchase_bane.lua @@ -10,7 +10,7 @@ local ItemsToBuy = "item_tango", "item_clarity", "item_boots", - "item_ring_of_basilius", --圣殿 + -- "item_ring_of_basilius", --圣殿 "item_magic_wand", --大魔棒7.14 "item_energy_booster", "item_null_talisman", @@ -20,8 +20,7 @@ local ItemsToBuy = "item_ultimate_scepter", --蓝杖 "item_sheepstick", --羊刀 "item_mekansm", --梅肯 - "item_buckler", - "item_recipe_guardian_greaves" --卫士胫甲 + "item_guardian_greaves" --卫士胫甲 } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_batrider.lua b/item_purchase_batrider.lua index af3bbe2d..988bf72d 100644 --- a/item_purchase_batrider.lua +++ b/item_purchase_batrider.lua @@ -11,18 +11,13 @@ local ItemsToBuy = "item_enchanted_mango", "item_flask", "item_wind_lace", - "item_magic_wand", --大魔棒7.14 - "item_boots", - "item_null_talisman", - "item_buckler", - "item_ring_of_regen", --绿鞋 + "item_tranquil_boots", "item_blink", --跳刀 "item_force_staff", --推推7.14 + "item_ultimate_scepter", --蓝杖 "item_black_king_bar", --bkb "item_cyclone", --风杖 - "item_ultimate_scepter", --蓝杖 "item_lotus_orb", - "item_shivas_guard", } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_beastmaster.lua b/item_purchase_beastmaster.lua index 9863518e..8d0b6983 100644 --- a/item_purchase_beastmaster.lua +++ b/item_purchase_beastmaster.lua @@ -11,10 +11,8 @@ local ItemsToBuy = "item_enchanted_mango", "item_quelling_blade", "item_bracer", - "item_buckler", "item_phase_boots", --相位7.21 "item_magic_wand", - "item_ring_of_basilius", "item_lifesteal", --祭品 "item_necronomicon_3", --死灵书 "item_solar_crest", --大勋章7.20 diff --git a/item_purchase_bloodseeker.lua b/item_purchase_bloodseeker.lua index b1abc3f3..73dbf914 100644 --- a/item_purchase_bloodseeker.lua +++ b/item_purchase_bloodseeker.lua @@ -10,9 +10,7 @@ local ItemsToBuy = "item_flask", "item_quelling_blade", "item_wraith_band", - "item_branches", - "item_branches", - "item_magic_stick", + "item_magic_wand", "item_phase_boots", --相位 "item_recipe_magic_wand", --大魔棒7.14 "item_blade_mail", --刃甲 diff --git a/item_purchase_brewmaster.lua b/item_purchase_brewmaster.lua index 220d8d05..cb215906 100644 --- a/item_purchase_brewmaster.lua +++ b/item_purchase_brewmaster.lua @@ -13,7 +13,6 @@ local ItemsToBuy = "item_bracer", "item_phase_boots", --相位7.21 "item_magic_wand", - "item_vladmir", --祭品7.21 "item_blink", --跳刀 "item_black_king_bar", --BKB "item_ultimate_scepter", --蓝杖 diff --git a/item_purchase_bristleback.lua b/item_purchase_bristleback.lua index 7372ce2f..36c52120 100644 --- a/item_purchase_bristleback.lua +++ b/item_purchase_bristleback.lua @@ -17,10 +17,10 @@ local p = "item_crimson_guard", "item_heart", --龙心7.20 "item_black_king_bar", --BKB - "item_lotus_orb", "item_shivas_guard", "item_ultimate_scepter", "item_recipe_ultimate_scepter", + "item_lotus_orb", } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), p) diff --git a/item_purchase_broodmother.lua b/item_purchase_broodmother.lua index 188a1213..92587256 100644 --- a/item_purchase_broodmother.lua +++ b/item_purchase_broodmother.lua @@ -10,15 +10,14 @@ local ItemsToBuy = "item_quelling_blade", --补刀斧 "item_boots", "item_magic_wand", --大魔棒7.14 - "item_belt_of_strength", - "item_gloves", --假腿7.21 + "item_power_treads", "item_soul_ring", "item_solar_crest", --大勋章7.20 "item_orchid", --紫苑 "item_black_king_bar", --bkb "item_hyperstone", "item_recipe_bloodthorn", --血棘 - "item_assault" --强袭 + "item_assault", --强袭 } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_chen.lua b/item_purchase_chen.lua index 1b933758..ba9b7bf4 100644 --- a/item_purchase_chen.lua +++ b/item_purchase_chen.lua @@ -13,7 +13,7 @@ local ItemsToBuy = "item_boots", "item_flask", "item_magic_wand", --大魔棒7.14 - "item_energy_booster", + "item_arcane_boots", "item_mekansm", --梅肯 "item_ghost", "item_guardian_greaves", --卫士胫甲 diff --git a/item_purchase_crystal_maiden.lua b/item_purchase_crystal_maiden.lua index 47e48d86..2cbe2ee7 100644 --- a/item_purchase_crystal_maiden.lua +++ b/item_purchase_crystal_maiden.lua @@ -9,7 +9,7 @@ local ItemsToBuy = "item_tango", "item_flask", "item_clarity", - "item_ring_of_basilius", + -- "item_ring_of_basilius", "item_tranquil_boots", "item_bracer", "item_glimmer_cape", --微光 diff --git a/item_purchase_dark_seer.lua b/item_purchase_dark_seer.lua index afe8aebe..d12117ac 100644 --- a/item_purchase_dark_seer.lua +++ b/item_purchase_dark_seer.lua @@ -9,15 +9,12 @@ local ItemsToBuy = "item_tango", "item_flask", "item_enchanted_mango", - "item_enchanted_mango", "item_soul_ring", --魂戒 "item_boots", "item_magic_wand", --大魔棒7.14 "item_energy_booster", - "item_pipe", --笛子 "item_mekansm", --梅肯 - "item_buckler", - "item_recipe_guardian_greaves", --卫士胫甲 + "item_guardian_greaves", --卫士胫甲 "item_blink", --跳刀 "item_lotus_orb", --清莲宝珠 "item_shivas_guard", --希瓦 diff --git a/item_purchase_dazzle.lua b/item_purchase_dazzle.lua index 8b4e5f9d..3c78d791 100644 --- a/item_purchase_dazzle.lua +++ b/item_purchase_dazzle.lua @@ -7,20 +7,17 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { "item_tango", - "item_ring_of_basilius", + -- "item_ring_of_basilius", "item_tango", "item_wind_lace", "item_boots", "item_magic_wand", --大魔棒7.14 - "item_energy_booster", - "item_spirit_vessel", --大骨灰 + "item_arcane_boots", "item_mekansm", --梅肯 "item_ghost", "item_spirit_vessel", --大骨灰 - "item_buckler", - "item_recipe_guardian_greaves", --卫士胫甲 + "item_guardian_greaves", --卫士胫甲 "item_solar_crest", --大勋章7.20 - "item_pipe", "item_sheepstick" --羊刀 } diff --git a/item_purchase_death_prophet.lua b/item_purchase_death_prophet.lua index 33ad8988..792508ec 100644 --- a/item_purchase_death_prophet.lua +++ b/item_purchase_death_prophet.lua @@ -12,8 +12,7 @@ local ItemsToBuy = "item_null_talisman", --无用挂件 "item_boots", "item_magic_wand", - "item_blades_of_attack", - "item_chainmail", --相位7.21 + "item_phase_boots", "item_cyclone", --风杖 "item_ultimate_scepter", "item_shivas_guard", --希瓦 diff --git a/item_purchase_disruptor.lua b/item_purchase_disruptor.lua index d9856e42..b4aac1ef 100644 --- a/item_purchase_disruptor.lua +++ b/item_purchase_disruptor.lua @@ -10,9 +10,8 @@ local ItemsToBuy = "item_tango", "item_clarity", "item_wind_lace", - "item_boots", - "item_ring_of_regen", --绿鞋 - "item_flask", + "item_magic_stick", + "item_tranquil_boots", "item_glimmer_cape", "item_ultimate_scepter", --蓝杖 "item_force_staff", --推推7.14 diff --git a/item_purchase_doom_bringer.lua b/item_purchase_doom_bringer.lua index d333b6f9..f4aefa80 100644 --- a/item_purchase_doom_bringer.lua +++ b/item_purchase_doom_bringer.lua @@ -8,22 +8,17 @@ local ItemsToBuy = { "item_tango", "item_flask", - "item_enchanted_mango", + "item_quelling_blade", "item_bracer", "item_boots", - "item_branches", - "item_branches", - "item_recipe_magic_wand", - "item_blades_of_attack", - "item_chainmail", --相位7.21 + "item_magic_wand", + "item_phase_boots", "item_ancient_janggo", --战鼓7.20 "item_invis_sword", --隐刀 "item_ultimate_scepter", "item_blade_mail", --刃甲 "item_shivas_guard", --希瓦 - "item_ultimate_orb", - "item_recipe_silver_edge", --大隐刀 - "item_assault" --强袭 + "item_silver_edge", --大隐刀 } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_dragon_knight.lua b/item_purchase_dragon_knight.lua index 63c9398e..05f8064e 100644 --- a/item_purchase_dragon_knight.lua +++ b/item_purchase_dragon_knight.lua @@ -15,8 +15,7 @@ local ItemsToBuy = "item_maelstrom", --电锤7.14 "item_black_king_bar", --BKB "item_blink", - "item_hyperstone", - "item_recipe_mjollnir", --大雷锤 + "item_mjollnir", --大雷锤 "item_assault", --强袭 "item_greater_crit" --大炮 } diff --git a/item_purchase_drow_ranger.lua b/item_purchase_drow_ranger.lua index e5163de3..8ef7675d 100644 --- a/item_purchase_drow_ranger.lua +++ b/item_purchase_drow_ranger.lua @@ -14,12 +14,13 @@ local ItemsToBuy = "item_dragon_lance", --魔龙枪 "item_yasha", --夜叉 "item_mjollnir", + "item_black_king_bar", "item_manta", "item_hurricane_pike", --大推推7.20 "item_ultimate_scepter", --蓝杖 "item_monkey_king_bar", "item_recipe_ultimate_scepter", - "item_black_king_bar", + "item_butterfly", } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_earth_spirit.lua b/item_purchase_earth_spirit.lua index a274b7f0..05b2d405 100644 --- a/item_purchase_earth_spirit.lua +++ b/item_purchase_earth_spirit.lua @@ -9,7 +9,6 @@ local ItemsToBuy = "item_tango", "item_clarity", "item_orb_of_venom", --毒球 - "item_buckler", "item_boots", "item_bracer", "item_magic_wand", --大魔棒7.14 diff --git a/item_purchase_earthshaker.lua b/item_purchase_earthshaker.lua index a1963488..bc9d533b 100644 --- a/item_purchase_earthshaker.lua +++ b/item_purchase_earthshaker.lua @@ -14,9 +14,8 @@ local ItemsToBuy = "item_magic_wand", --大魔棒7.14 "item_blink", --跳刀 "item_force_staff", --推推7.14 - "item_cyclone", --风杖 "item_ultimate_scepter", --蓝杖 - "item_black_king_bar" + "item_black_king_bar", } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_ember_spirit.lua b/item_purchase_ember_spirit.lua index 0516e2e8..21cccbe1 100644 --- a/item_purchase_ember_spirit.lua +++ b/item_purchase_ember_spirit.lua @@ -6,23 +6,19 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { - "item_tango", - "item_tango", "item_quelling_blade", - "item_wraith_band", + "item_circlet", "item_bottle", + "item_wraith_band", "item_phase_boots", - "item_broadsword", - "item_ring_of_health", - "item_claymore", - "item_void_stone", + "item_bfury", "item_magic_wand", --大魔棒7.14 + "item_lesser_crit", "item_black_king_bar", "item_greater_crit", - "item_maelstrom", --电锤7.14 - "item_octarine_core", --玲珑心 - "item_hyperstone", - "item_recipe_mjollnir", --大雷锤 + "item_ultimate_scepter", + "item_aghanims_shard", + "item_octarine_core", --玲珑心 } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_enchantress.lua b/item_purchase_enchantress.lua index c3bbbe9e..9449e42a 100644 --- a/item_purchase_enchantress.lua +++ b/item_purchase_enchantress.lua @@ -14,10 +14,9 @@ local ItemsToBuy = "item_null_talisman", "item_boots", "item_magic_wand", --大魔棒7.14 - "item_robe", - "item_gloves", - --"item_hood_of_defiance", --挑战 + "item_power_treads", "item_dragon_lance", --魔龙枪 + "item_black_king_bar", "item_ultimate_scepter", --蓝杖 "item_force_staff", --推推7.14 "item_recipe_hurricane_pike", --大推推7.28 diff --git a/item_purchase_enigma.lua b/item_purchase_enigma.lua index 3ace7f34..907e6296 100644 --- a/item_purchase_enigma.lua +++ b/item_purchase_enigma.lua @@ -8,17 +8,14 @@ local ItemsToBuy = { "item_tango", "item_clarity", - "item_ring_of_basilius", + -- "item_ring_of_basilius", "item_magic_wand", --大魔棒7.14 "item_arcane_boots", --秘法鞋 "item_blink", --跳刀 - "item_mekansm", --梅肯 - "item_buckler", - "item_recipe_guardian_greaves", --卫士胫甲 + "item_guardian_greaves", --卫士胫甲 "item_black_king_bar", --bkb "item_vitality_booster", - --"item_energy_booster", - "item_arcane_boots", + "item_energy_booster", "item_recipe_aeon_disk", -- 永恒之盘 "item_ultimate_scepter", --蓝杖 "item_octarine_core", --玲珑心 diff --git a/item_purchase_gyrocopter.lua b/item_purchase_gyrocopter.lua index 6d0082a8..01f3cdae 100644 --- a/item_purchase_gyrocopter.lua +++ b/item_purchase_gyrocopter.lua @@ -13,8 +13,7 @@ local ItemsToBuy = "item_wraith_band", --系带 "item_boots", "item_magic_wand", - "item_blades_of_attack", - "item_chainmail", --相位7.21 + "item_phase_boots", "item_ancient_janggo", --战鼓7.20 "item_monkey_king_bar", --金箍棒7.14 "item_black_king_bar", --bkb diff --git a/item_purchase_hoodwink.lua b/item_purchase_hoodwink.lua index ba62813c..702d6719 100644 --- a/item_purchase_hoodwink.lua +++ b/item_purchase_hoodwink.lua @@ -7,12 +7,11 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { "item_tango", - "item_flask", "item_branches", "item_branches", "item_tranquil_boots", - "item_recipe_magic_wand", + "item_magic_wand", "item_aether_lens", "item_cyclone", diff --git a/item_purchase_invoker.lua b/item_purchase_invoker.lua index 2a659f7c..990a6ebe 100644 --- a/item_purchase_invoker.lua +++ b/item_purchase_invoker.lua @@ -10,10 +10,9 @@ local ItemsToBuy = "item_tango", "item_hand_of_midas", "item_boots", - "item_cyclone", - "item_black_king_bar", - "item_ultimate_scepter", - "item_recipe_travel_boots", + "item_ultimate_scepter", + "item_travel_boots", + "item_cyclone", "item_black_king_bar", "item_sphere", "item_sheepstick" diff --git a/item_purchase_jakiro.lua b/item_purchase_jakiro.lua index eeac7949..08e7c6db 100644 --- a/item_purchase_jakiro.lua +++ b/item_purchase_jakiro.lua @@ -7,8 +7,8 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { "item_tango", - "item_ring_of_basilius", - "item_tango", + -- "item_ring_of_basilius", + -- "item_tango", "item_clarity", "item_magic_stick", "item_arcane_boots", --秘法鞋 @@ -18,10 +18,9 @@ local ItemsToBuy = "item_cyclone", --风杖 "item_ultimate_scepter", --蓝杖 "item_mekansm", - "item_buckler", - "item_recipe_guardian_greaves", + "item_guardian_greaves", "item_dragon_lance", - "item_recipe_hurricane_pike", + "item_hurricane_pike", } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_juggernaut.lua b/item_purchase_juggernaut.lua index 9182916c..e125c4e4 100644 --- a/item_purchase_juggernaut.lua +++ b/item_purchase_juggernaut.lua @@ -15,12 +15,12 @@ local ItemsToBuy = "item_phase_boots", --相位7.21 "item_maelstrom", "item_yasha", --夜叉 - "item_diffusal_blade", --散失刀 "item_ultimate_orb", "item_recipe_manta", --分身 "item_abyssal_blade", --大晕锤 "item_butterfly", --蝴蝶 "item_ultimate_scepter", + "item_swift_blink", "item_recipe_ultimate_scepter", } diff --git a/item_purchase_keeper_of_the_light.lua b/item_purchase_keeper_of_the_light.lua index 188defac..06243330 100644 --- a/item_purchase_keeper_of_the_light.lua +++ b/item_purchase_keeper_of_the_light.lua @@ -11,8 +11,7 @@ local ItemsToBuy = "item_tango", "item_wind_lace", "item_boots", - "item_magic_stick", - "item_ring_of_regen", --绿鞋 + "item_tranquil_boots", "item_glimmer_cape", --微光 "item_ghost", --绿杖 "item_force_staff", --推推7.14 diff --git a/item_purchase_legion_commander.lua b/item_purchase_legion_commander.lua index cb56daba..fdb1b354 100644 --- a/item_purchase_legion_commander.lua +++ b/item_purchase_legion_commander.lua @@ -13,7 +13,6 @@ local ItemsToBuy = "item_bracer", "item_magic_wand", "item_phase_boots", --相位7.21 - "item_desolator", "item_invis_sword", --隐刀 "item_blade_mail", --刃甲 "item_ultimate_orb", diff --git a/item_purchase_leshrac.lua b/item_purchase_leshrac.lua index a45a591f..550b8078 100644 --- a/item_purchase_leshrac.lua +++ b/item_purchase_leshrac.lua @@ -6,9 +6,8 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { - "item_tango", "item_null_talisman", - "item_tango", + "item_branches", "item_bottle", "item_magic_wand", --大魔棒7.14 "item_boots", @@ -17,9 +16,8 @@ local ItemsToBuy = "item_veil_of_discord", --纷争7.20 "item_cyclone", --风杖 "item_octarine_core", --玲珑心 - "item_mekansm", - "item_buckler", - "item_recipe_guardian_greaves", + -- "item_mekansm", + -- "item_uardian_greaves", "item_ultimate_scepter", "item_shivas_guard" --希瓦 } diff --git a/item_purchase_lich.lua b/item_purchase_lich.lua index dba9c20c..ca6f2983 100644 --- a/item_purchase_lich.lua +++ b/item_purchase_lich.lua @@ -9,11 +9,9 @@ local ItemsToBuy = "item_tango", "item_tango", "item_clarity", - "item_ring_of_basilius", "item_wind_lace", "item_boots", - "item_magic_wand", - "item_ring_of_regen", --绿鞋 + "item_tranquil_boots", "item_urn_of_shadows", "item_ghost", "item_glimmer_cape", --微光 diff --git a/item_purchase_life_stealer.lua b/item_purchase_life_stealer.lua index 65e3e26f..e9b90df5 100644 --- a/item_purchase_life_stealer.lua +++ b/item_purchase_life_stealer.lua @@ -12,12 +12,8 @@ local ItemsToBuy = "item_quelling_blade", --补刀斧 "item_orb_of_venom", "item_phase_boots", --相位7.21 - "item_blight_stone", - "item_fluffy_hat", - "item_recipe_orb_of_corrosion", - "item_branches", - "item_branches", - "item_recipe_magic_wand", --大魔棒7.14 + "item_orb_of_corrosion", + "item_magic_wand", --大魔棒7.14 "item_armlet", --臂章 --"item_scepter_shard", "item_sange_and_yasha", diff --git a/item_purchase_lina.lua b/item_purchase_lina.lua index 818e2d5a..253bc523 100644 --- a/item_purchase_lina.lua +++ b/item_purchase_lina.lua @@ -6,9 +6,7 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { - "item_tango", "item_null_talisman", - "item_enchanted_mango", "item_bottle", "item_phase_boots", "item_magic_wand", --大魔棒7.14 @@ -20,7 +18,7 @@ local ItemsToBuy = "item_shivas_guard", "item_sheepstick", "item_mystic_staff", - "item_recipe_wind_waker", + "item_wind_waker", } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_lion.lua b/item_purchase_lion.lua index 6bdaad90..a8621d8a 100644 --- a/item_purchase_lion.lua +++ b/item_purchase_lion.lua @@ -9,18 +9,15 @@ local ItemsToBuy = "item_tango", "item_tango", "item_clarity", - "item_ring_of_basilius", - "item_wind_lace", "item_boots", - "item_magic_stick", - "item_ring_of_regen", --绿鞋 + "item_tranquil_boots", "item_blink", "item_ghost", + "item_aether_lens", "item_glimmer_cape", --微光 "item_force_staff", "item_ultimate_scepter", --蓝杖 "item_lotus_orb", --清莲宝珠 - "item_sheepstick" --羊刀 } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_mirana.lua b/item_purchase_mirana.lua index d82b838e..9d08f5e6 100644 --- a/item_purchase_mirana.lua +++ b/item_purchase_mirana.lua @@ -11,15 +11,12 @@ local ItemsToBuy = "item_flask", "item_magic_wand", "item_phase_boots", --相位7.21 - "item_branches", - "item_branches", "item_maelstrom", - "item_hurricane_pike", --大推推7.20 "item_manta", "item_black_king_bar", "item_butterfly", - "item_hyperstone", - "item_recipe_mjollnir" --大雷锤 + "item_mjollnir", --大雷锤 + "item_greater_crit", } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_naga_siren.lua b/item_purchase_naga_siren.lua index f551999b..18e2f1b3 100644 --- a/item_purchase_naga_siren.lua +++ b/item_purchase_naga_siren.lua @@ -21,8 +21,8 @@ local ItemsToBuy = } local ItemsToBuy1 = { - "item_tango","item_tango", "item_wraith_brand", + "item_tango","item_tango", "item_power_treads", "item_manta", "item_diffusal_blade", diff --git a/item_purchase_necrolyte.lua b/item_purchase_necrolyte.lua index 80579284..25cec309 100644 --- a/item_purchase_necrolyte.lua +++ b/item_purchase_necrolyte.lua @@ -13,14 +13,13 @@ local ItemsToBuy = "item_boots", "item_magic_wand", --大魔棒7.14 "item_veil_of_discord", --纷争7.20 - "item_point_booster", + "item_arcane_boots", "item_holy_locket", "item_mekansm", --梅肯 "item_shivas_guard", --希瓦 "item_bloodthorn", "item_ultimate_scepter", --蓝杖 - "item_buckler", - "item_recipe_guardian_greaves", --卫士胫甲 + "item_guardian_greaves", --卫士胫甲 "item_black_king_bar", --bkb } diff --git a/item_purchase_nevermore.lua b/item_purchase_nevermore.lua index afe5dc47..05c48714 100644 --- a/item_purchase_nevermore.lua +++ b/item_purchase_nevermore.lua @@ -6,7 +6,6 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { - "item_tango", "item_wraith_band", --系带 "item_bottle", "item_flask", diff --git a/item_purchase_night_stalker.lua b/item_purchase_night_stalker.lua index 70b2653a..e9efd7ed 100644 --- a/item_purchase_night_stalker.lua +++ b/item_purchase_night_stalker.lua @@ -7,9 +7,9 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { "item_tango", - "item_flask", "item_quelling_blade", --补刀斧 "item_bracer", + "item_flask", "item_phase_boots", --相位7.21 "item_magic_wand", "item_blink", diff --git a/item_purchase_nyx_assassin.lua b/item_purchase_nyx_assassin.lua index 677507d4..a0070ba5 100644 --- a/item_purchase_nyx_assassin.lua +++ b/item_purchase_nyx_assassin.lua @@ -10,21 +10,15 @@ local ItemsToBuy = "item_tango", "item_enchanted_mango", "item_flask", - "item_magic_wand", --大魔棒7.14 - "item_buckler", + "item_magic_stick", --大魔棒7.14 "item_boots", "item_hand_of_midas", --点金 "item_energy_booster", - "item_urn_of_shadows", "item_blink", + "item_dagon_1", "item_ultimate_scepter", --蓝杖 - "item_crown", - "item_staff_of_wizardry", - "item_recipe_dagon", "item_force_staff", --推推 - "item_mekansm", --梅肯 - "item_buckler", - "item_recipe_guardian_greaves", --卫士胫甲 + "item_guardian_greaves", "item_recipe_dagon", "item_recipe_dagon", "item_sheepstick", diff --git a/item_purchase_obsidian_destroyer.lua b/item_purchase_obsidian_destroyer.lua index 2eb11237..51a0dc85 100644 --- a/item_purchase_obsidian_destroyer.lua +++ b/item_purchase_obsidian_destroyer.lua @@ -10,13 +10,12 @@ local ItemsToBuy = "item_tango", "item_null_talisman", --无用挂件 "item_power_treads", --假腿7.21 + "item_dragon_lance", --魔龙枪 "item_witch_blade", - "item_dragon_lance", --魔龙枪 "item_orchid", "item_black_king_bar", --bkb "item_sheepstick", --羊刀 - "item_force_staff", --推推7.14 - "item_recipe_hurricane_pike", --大推推7.20 + "item_hurricane_pike", --大推推7.20 "item_sphere", --林肯 "item_ultimate_scepter", } diff --git a/item_purchase_ogre_magi.lua b/item_purchase_ogre_magi.lua index dc7f299d..fd54757c 100644 --- a/item_purchase_ogre_magi.lua +++ b/item_purchase_ogre_magi.lua @@ -8,15 +8,13 @@ local ItemsToBuy = { "item_tango", "item_clarity", - "item_clarity", - "item_buckler", "item_boots", "item_flask", "item_hand_of_midas", - "item_energy_booster", - -- heroes buy a lot of energy boosters because energy booster and boots create an arcane boots so they need to buy more energy booster + "item_arcane_boots", "item_aether_lens", --以太之镜7.06 "item_ultimate_scepter", --蓝杖 + "item_aghanims_shard", "item_force_staff", --推推7.14 "item_cyclone", --风杖 "item_lotus_orb", diff --git a/item_purchase_omniknight.lua b/item_purchase_omniknight.lua index 4f363741..ee2b5244 100644 --- a/item_purchase_omniknight.lua +++ b/item_purchase_omniknight.lua @@ -7,18 +7,14 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { "item_tango", - "item_tango", - "item_quelling_blade", --补刀斧 + "item_bracer", "item_enchanted_mango", "item_enchanted_mango", "item_magic_wand", --大魔棒7.14 + "item_soul_ring", "item_arcane_boots", --秘法鞋 - "item_buckler", - "item_bracer", - "item_ancient_janggo", "item_mekansm", --梅肯 - "item_buckler", - "item_recipe_guardian_greaves", --卫士胫甲 + "item_guardian_greaves", "item_ultimate_scepter", --蓝杖 "item_force_staff", "item_lotus_orb", --清莲宝珠 diff --git a/item_purchase_oracle.lua b/item_purchase_oracle.lua index a7fbf823..62f47005 100644 --- a/item_purchase_oracle.lua +++ b/item_purchase_oracle.lua @@ -6,14 +6,11 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { - "item_tango", "item_tango", "item_clarity", "item_flask", - "item_ring_of_basilius", - "item_wind_lace", - "item_boots", - "item_ring_of_regen", --绿鞋 + -- "item_ring_of_basilius", + "item_tranquil_boots", "item_urn_of_shadows", "item_ghost", "item_glimmer_cape", --微光 diff --git a/item_purchase_phantom_assassin.lua b/item_purchase_phantom_assassin.lua index 294cfea4..f9335925 100644 --- a/item_purchase_phantom_assassin.lua +++ b/item_purchase_phantom_assassin.lua @@ -6,16 +6,13 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { - "item_tango", "item_tango", "item_quelling_blade", --补刀斧 "item_wraith_band", --系带 - "item_magic_wand", --大魔棒7.14 + "item_tango", "item_phase_boots", --相位7.21 - "item_broadsword", - "item_ring_of_health", - "item_claymore", - "item_void_stone", + "item_magic_wand", --大魔棒7.14 + "item_bfury", "item_desolator", "item_black_king_bar", --bkb "item_abyssal_blade", --大晕锤 diff --git a/item_purchase_phantom_lancer.lua b/item_purchase_phantom_lancer.lua index 104d3144..c238b7f3 100644 --- a/item_purchase_phantom_lancer.lua +++ b/item_purchase_phantom_lancer.lua @@ -10,7 +10,6 @@ local ItemsToBuy = "item_tango", "item_tango", "item_quelling_blade", --补刀斧 - "item_flask", "item_wraith_band", "item_magic_wand", "item_wraith_band", diff --git a/item_purchase_pudge.lua b/item_purchase_pudge.lua index aafb1511..e1e746f5 100644 --- a/item_purchase_pudge.lua +++ b/item_purchase_pudge.lua @@ -9,22 +9,17 @@ local ItemsToBuy = "item_tango", "item_tango", "item_clarity", - "item_magic_stick", - "item_wind_lace", "item_boots", - "item_buckler", "item_bracer", - "item_branches", - "item_branches", - "item_recipe_magic_wand", - "item_ring_of_regen", --绿鞋 + "item_magic_wand", + "item_tranquil_boots", "item_urn_of_shadows", "item_blade_mail", + "item_ultimate_scepter", "item_blink", "item_glimmer_cape", --微光 "item_force_staff", "item_lotus_orb", --清莲宝珠 - "item_sheepstick" --羊刀 } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_pugna.lua b/item_purchase_pugna.lua index 903ce9b8..2a51b7e4 100644 --- a/item_purchase_pugna.lua +++ b/item_purchase_pugna.lua @@ -9,41 +9,19 @@ local ItemsToBuy = "item_tango", "item_mantle", "item_circlet", - "item_mantle", --无用挂件 + "item_mantle", + "item_null_talisman", "item_magic_wand", "item_boots", - "item_recipe_null_talisman", - "item_circlet", - "item_recipe_null_talisman", - "item_energy_booster", - "item_robe", - "item_staff_of_wizardry", --慧光 - "item_energy_booster", - "item_void_stone", - "item_recipe_aether_lens", --以太之镜7.06 - "item_point_booster", - "item_staff_of_wizardry", - "item_ogre_axe", - "item_blade_of_alacrity", --蓝杖 - "item_ogre_axe", - "item_mithril_hammer", - "item_recipe_black_king_bar", --bkb - "item_mystic_staff", - "item_ultimate_orb", - "item_void_stone" --羊刀 + "item_null_talisman", + "item_arcane_boots", + "item_kaya", + "item_aether_lens", --以太之镜7.06 + "item_ultimate_scepter", + "item_black_king_bar", --bkb + "item_aghanims_shard", } ---[[for k,v in pairs(ItemsToBuy) -do - local item = GetItemComponents(ItemsToBuy[k]) - if item ~= nil and #item > 0 - then - for k,v in pairs(item) - do - table.insert(ItemsToBuy,k,item[k]) - end - end -end]] ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_queenofpain.lua b/item_purchase_queenofpain.lua index d4b40e9b..352eaa35 100644 --- a/item_purchase_queenofpain.lua +++ b/item_purchase_queenofpain.lua @@ -11,16 +11,13 @@ local ItemsToBuy = "item_enchanted_mango", "item_boots", "item_magic_wand", --大魔棒7.14 - "item_belt_of_strength", - "item_gloves", --假腿7.21 - "item_witch_blade", + "item_power_treads", "item_veil_of_discord", --纷争7.20 "item_orchid", --紫苑 "item_black_king_bar", --bkb "item_ultimate_scepter", --蓝杖 "item_shivas_guard", --希瓦 - "item_hyperstone", - "item_recipe_bloodthorn" --血棘 + "item_bloodthorn" --血棘 } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_riki.lua b/item_purchase_riki.lua index ee0e80e9..3f20789a 100644 --- a/item_purchase_riki.lua +++ b/item_purchase_riki.lua @@ -13,7 +13,7 @@ local ItemsToBuy = "item_power_treads", "item_diffusal_blade", --散失刀 "item_sange_and_yasha", --双刀 - "item_mage_slayer", + --"item_mage_slayer", "item_black_king_bar", --bkb "item_abyssal_blade" --大晕锤 } diff --git a/item_purchase_shadow_demon.lua b/item_purchase_shadow_demon.lua index ca1ac679..73be56cb 100644 --- a/item_purchase_shadow_demon.lua +++ b/item_purchase_shadow_demon.lua @@ -11,10 +11,7 @@ local ItemsToBuy = "item_tango", "item_clarity", "item_magic_stick", - "item_ring_of_basilius", - "item_wind_lace", - "item_boots", - "item_ring_of_regen", --绿鞋 + "item_tranquil_boots", "item_glimmer_cape", --微光 "item_force_staff", "item_ultimate_scepter", --蓝杖 diff --git a/item_purchase_shadow_shaman.lua b/item_purchase_shadow_shaman.lua index 8278dfd8..500a3c86 100644 --- a/item_purchase_shadow_shaman.lua +++ b/item_purchase_shadow_shaman.lua @@ -10,10 +10,9 @@ local ItemsToBuy = "item_tango", "item_clarity", "item_magic_stick", - "item_ring_of_basilius", "item_arcane_boots", "item_blink", - "item_glimmer_cape", --微光 + "item_aether_lens", "item_ghost", "item_force_staff", "item_ultimate_scepter", --蓝杖 diff --git a/item_purchase_shredder.lua b/item_purchase_shredder.lua index 4325a6f6..1f892438 100644 --- a/item_purchase_shredder.lua +++ b/item_purchase_shredder.lua @@ -13,7 +13,7 @@ local ItemsToBuy = "item_magic_wand", "item_arcane_boots", --秘法鞋 "item_bloodstone", - "item_pipe", --笛子 + "item_hood_of_defiance", "item_cyclone", "item_ultimate_scepter", --蓝杖 "item_shivas_guard", --希瓦 diff --git a/item_purchase_silencer.lua b/item_purchase_silencer.lua index 9813dc62..ef7a309b 100644 --- a/item_purchase_silencer.lua +++ b/item_purchase_silencer.lua @@ -13,13 +13,10 @@ local ItemsToBuy = "item_power_treads", --假腿7.21 "item_witch_blade", "item_hurricane_pike", --大推推7.20 - "item_rod_of_atos", --阿托斯7.20 "item_orchid", - "item_hyperstone", - "item_recipe_bloodthorn", + "item_bloodthorn", "item_sheepstick", --羊刀 - "item_maelstrom", - "item_recipe_gleipnir", + "item_gleipnir", "item_ultimate_scepter", --蓝杖 } diff --git a/item_purchase_skeleton_king.lua b/item_purchase_skeleton_king.lua index 162fb26c..4e04da01 100644 --- a/item_purchase_skeleton_king.lua +++ b/item_purchase_skeleton_king.lua @@ -3,6 +3,9 @@ -- Author: adamqqq Email:adamqqq@163.com ---------------------------------------------------------------------------- local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSystem") +local AbilityExtensions = require(GetScriptDirectory().."/util/AbilityAbstraction") + +local enemyTeamMemberNames = AbilityExtensions:GetEnemyTeamMemberNames(GetBot()) local ItemsToBuy = { @@ -12,9 +15,8 @@ local ItemsToBuy = "item_magic_wand", --大魔棒7.14 "item_gloves", "item_boots", - "item_recipe_hand_of_midas", - "item_belt_of_strength", - "item_gloves", + "item_hand_of_midas", + "item_power_treads", "item_radiance", "item_black_king_bar", --bkb "item_blink", @@ -22,6 +24,10 @@ local ItemsToBuy = "item_ultimate_scepter", --蓝杖 } +if AbilityExtensions:Contains(enemyTeamMemberNames, "antimage") then + AbilityExtensions:InsertAfter_Modify(ItemsToBuy, "item_radiance", "item_aghanims_shard") +end + ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_skywrath_mage.lua b/item_purchase_skywrath_mage.lua index be769dcd..f88a998b 100644 --- a/item_purchase_skywrath_mage.lua +++ b/item_purchase_skywrath_mage.lua @@ -12,16 +12,15 @@ local ItemsToBuy = "item_enchanted_mango", "item_enchanted_mango", "item_magic_wand", - "item_boots", - "item_energy_booster", - "item_witch_blade", + "item_arcane_boots", + -- "item_witch_blade", "item_kaya", "item_aether_lens", "item_rod_of_atos", --阿托斯7.20 "item_force_staff", "item_ultimate_scepter", --蓝杖 "item_sheepstick", --羊刀 - "item_yasha", + "item_kaya_and_yasha", } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_sniper.lua b/item_purchase_sniper.lua index ca254232..6e0661a8 100644 --- a/item_purchase_sniper.lua +++ b/item_purchase_sniper.lua @@ -17,7 +17,6 @@ local ItemsToBuy = "item_black_king_bar", --bkb "item_hyperstone", "item_recipe_mjollnir", --大雷锤 - -- "item_skadi" "item_greater_crit", } diff --git a/item_purchase_spectre.lua b/item_purchase_spectre.lua index 310d09e6..c15e0852 100644 --- a/item_purchase_spectre.lua +++ b/item_purchase_spectre.lua @@ -19,7 +19,7 @@ local ItemsToBuy = "item_black_king_bar", "item_butterfly", "item_ultimate_scepter", - "item_recipe_ultimate_scepter", + -- "item_recipe_ultimate_scepter", } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_templar_assassin.lua b/item_purchase_templar_assassin.lua index 7ed430d3..5ddf32d5 100644 --- a/item_purchase_templar_assassin.lua +++ b/item_purchase_templar_assassin.lua @@ -14,10 +14,9 @@ local ItemsToBuy = "item_magic_wand", "item_desolator", --黯灭 "item_black_king_bar", --bkb - "item_orchid", + "item_blink", "item_butterfly", --蝴蝶 - "item_hyperstone", - "item_recipe_bloodthorn" --血棘 + "item_bloodthorn", } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_tidehunter.lua b/item_purchase_tidehunter.lua index 36fe73cf..ac1f8123 100644 --- a/item_purchase_tidehunter.lua +++ b/item_purchase_tidehunter.lua @@ -10,17 +10,14 @@ local ItemsToBuy = "item_quelling_blade", "item_flask", "item_enchanted_mango", - "item_enchanted_mango", + "item_bracer", "item_soul_ring", "item_phase_boots", "item_magic_wand", + "item_blink", --跳刀 "item_vladmir", "item_medallion_of_courage", - "item_pipe", - "item_blink", --跳刀 - "item_ultimate_orb", - "item_wind_lace", - "item_recipe_solar_crest", + "item_solar_crest", "item_shivas_guard" --希瓦 } diff --git a/item_purchase_tiny.lua b/item_purchase_tiny.lua index 546eee7f..f25fb64f 100644 --- a/item_purchase_tiny.lua +++ b/item_purchase_tiny.lua @@ -6,11 +6,8 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { - "item_tango", - "item_tango", - "item_enchanted_mango", - "item_enchanted_mango", "item_quelling_blade", + "item_gauntlets", "item_bottle", -- 魔瓶 "item_power_treads", "item_magic_wand", --大魔棒7.14 diff --git a/item_purchase_treant.lua b/item_purchase_treant.lua index bae7376f..da7beb60 100644 --- a/item_purchase_treant.lua +++ b/item_purchase_treant.lua @@ -7,7 +7,6 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { "item_tango", - "item_buckler", "item_tango", "item_enchanted_mango", "item_magic_stick", @@ -15,19 +14,12 @@ local ItemsToBuy = "item_arcane_boots", --秘法鞋 "item_medallion_of_courage", --勋章 "item_mekansm", --梅肯 - "item_recipe_guardian_greaves", --卫士胫甲 - "item_vladmir", + "item_guardian_greaves", --卫士胫甲 "item_force_staff", - "item_ultimate_orb", - "item_wind_lace", - "item_recipe_solar_crest", --大勋章7.20 + "item_solar_crest", --大勋章7.20 "item_lotus_orb", --清莲宝珠 "item_ultimate_scepter", --蓝杖 - "item_ring_of_health", - "item_void_stone", - "item_ring_of_health", - "item_void_stone", - "item_recipe_refresher" --刷新球 + "item_efresher" --刷新球 } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_troll_warlord.lua b/item_purchase_troll_warlord.lua index c24d2c1c..ca053ab6 100644 --- a/item_purchase_troll_warlord.lua +++ b/item_purchase_troll_warlord.lua @@ -14,17 +14,12 @@ local ItemsToBuy = "item_wraith_band", "item_magic_wand", "item_phase_boots", --相位7.21 - "item_broadsword", - "item_ring_of_health", - "item_claymore", - "item_void_stone", + "item_bfury", "item_sange_and_yasha", --双刀 "item_diffusal_blade", --散失刀 "item_black_king_bar", --bkb "item_butterfly", - "item_demon_edge", - "item_quarterstaff", - "item_javelin" --金箍棒7.14 + "item_monkey_king_bar", } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_tusk.lua b/item_purchase_tusk.lua index a00d49b9..d03e8cff 100644 --- a/item_purchase_tusk.lua +++ b/item_purchase_tusk.lua @@ -8,9 +8,7 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { "item_tango", - "item_buckler", "item_tango", - "item_enchanted_mango", "item_bracer", "item_phase_boots", "item_magic_stick", @@ -18,8 +16,8 @@ local ItemsToBuy = "item_solar_crest", "item_black_king_bar", --bkb "item_ultimate_scepter", --蓝杖 - "item_ultimate_orb", - "item_recipe_silver_edge" --大隐刀 + "item_aghanims_shard", + "item_silver_edge" --大隐刀 } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_undying.lua b/item_purchase_undying.lua index 487ea566..4d812693 100644 --- a/item_purchase_undying.lua +++ b/item_purchase_undying.lua @@ -11,11 +11,10 @@ local ItemsToBuy = "item_enchanted_mango", "item_magic_wand", --大魔棒7.14 "item_boots", - "item_buckler", "item_energy_booster", "item_blade_mail", --刃甲 "item_mekansm", --梅肯 - "item_recipe_guardian_greaves", --卫士胫甲 + "item_guardian_greaves", --卫士胫甲 "item_force_staff", "item_pipe", --笛子 "item_lotus_orb", diff --git a/item_purchase_ursa.lua b/item_purchase_ursa.lua index 97cf5bdd..bd8a3229 100644 --- a/item_purchase_ursa.lua +++ b/item_purchase_ursa.lua @@ -12,18 +12,14 @@ local ItemsToBuy = "item_orb_of_venom", "item_boots", "item_magic_wand", --大魔棒7.14 - "item_blades_of_attack", - "item_chainmail", --相位7.21 - "item_blight_stone", - "item_fluffy_hat", - "item_recipe_orb_of_corrosion", + "item_phase_boots", + "item_orb_of_corrosion", "item_vladmir", --祭品7.21 "item_blink", --跳刀 "item_basher", --晕锤7.14 "item_black_king_bar", --bkb "item_ultimate_scepter", - "item_vanguard", --先锋 - "item_recipe_abyssal_blade" --大晕锤 + "item_abyssal_blade" --大晕锤 } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_vengefulspirit.lua b/item_purchase_vengefulspirit.lua index e926e636..2548e963 100644 --- a/item_purchase_vengefulspirit.lua +++ b/item_purchase_vengefulspirit.lua @@ -8,19 +8,17 @@ local ItemsToBuy = { "item_tango", "item_clarity", - "item_ring_of_basilius", + -- "item_ring_of_basilius", "item_magic_stick", "item_power_treads", --假腿7.21 "item_medallion_of_courage", --勋章 "item_force_staff", --推推7.14 - "item_ultimate_orb", - "item_wind_lace", - "item_recipe_solar_crest", --大勋章7.20 + "item_solar_crest", --大勋章7.20 "item_dragon_lance", --魔龙枪 - "item_recipe_hurricane_pike", --大推推7.20 + "item_hurricane_pike", --大推推7.20 "item_glimmer_cape", "item_black_king_bar", - "item_sange_and_yasha" + "item_ultimate_scepter", } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_venomancer.lua b/item_purchase_venomancer.lua index 0a6e88b0..34e6623d 100644 --- a/item_purchase_venomancer.lua +++ b/item_purchase_venomancer.lua @@ -12,15 +12,12 @@ local ItemsToBuy = "item_magic_stick", "item_wraith_band", --系带 "item_boots", - "item_branches", - "item_branches", - "item_recipe_magic_wand", - "item_energy_booster", + "item_magic_wand", + "item_arcane_boots", "item_veil_of_discord", --纷争7.20 "item_hurricane_pike", --大推推7.20 "item_mekansm", --梅肯 - "item_buckler", - "item_recipe_guardian_greaves", --卫士胫甲 + "item_guardian_greaves", --卫士胫甲 "item_ultimate_scepter", --蓝杖 "item_black_king_bar", "item_lotus_orb" --清莲宝珠 diff --git a/item_purchase_warlock.lua b/item_purchase_warlock.lua index 20581c3c..6c696f59 100644 --- a/item_purchase_warlock.lua +++ b/item_purchase_warlock.lua @@ -11,30 +11,14 @@ local ItemsToBuy = "item_branches", "item_branches", "item_boots", - "item_magic_stick", - "item_recipe_magic_wand", --大魔棒7.14 - "item_energy_booster", - "item_cloak", - "item_shadow_amulet", --微光 - "item_ring_of_regen", - "item_staff_of_wizardry", - "item_recipe_force_staff", --推推7.14 + "item_magic_wand", --大魔棒7.14 + "item_arcane_boots", + "item_glimmer_cape", + "item_force_staff", "item_ghost", "item_ultimate_scepter", "item_refresher", "item_sheepstick", - --"item_point_booster", - --"item_staff_of_wizardry", - --"item_ogre_axe", - --"item_blade_of_alacrity", --蓝杖 - --"item_ring_of_health", - --"item_void_stone", - --"item_ring_of_health", - --"item_void_stone", - --"item_recipe_refresher", --刷新球 - --"item_mystic_staff", - --"item_ultimate_orb", - --"item_void_stone" --羊刀 } ItemPurchaseSystem.checkItemBuild(ItemsToBuy) diff --git a/item_purchase_weaver.lua b/item_purchase_weaver.lua index 9f72594e..c326d2c1 100644 --- a/item_purchase_weaver.lua +++ b/item_purchase_weaver.lua @@ -15,8 +15,8 @@ local ItemsToBuy = "item_magic_wand", "item_power_treads", --假腿7.21 "item_desolator", + "item_black_king_bar", --bkb "item_greater_crit", - "item_black_king_bar", --bkb "item_butterfly", } diff --git a/item_purchase_windrunner.lua b/item_purchase_windrunner.lua index 79c5922f..edbb5eab 100644 --- a/item_purchase_windrunner.lua +++ b/item_purchase_windrunner.lua @@ -12,16 +12,14 @@ local ItemsToBuy = "item_magic_wand", "item_boots", "item_javelin", - "item_blades_of_attack", - "item_chainmail", --相位7.21 - "item_mithril_hammer", --电锤7.14 + "item_phase_boots", + "item_maelstrom", "item_blink", "item_black_king_bar", "item_monkey_king_bar", "item_ultimate_scepter", "item_sphere", --林肯 - "item_hyperstone", - "item_recipe_mjollnir" --大雷锤 + "item_mjollnir" --大雷锤 } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_winter_wyvern.lua b/item_purchase_winter_wyvern.lua index 876077ba..f7f16648 100644 --- a/item_purchase_winter_wyvern.lua +++ b/item_purchase_winter_wyvern.lua @@ -10,11 +10,7 @@ local ItemsToBuy = "item_tango", "item_clarity", "item_magic_stick", - "item_buckler", - "item_wind_lace", - "item_boots", - "item_ring_of_regen", --绿鞋 - "item_soul_ring", + "item_tranquil_boots", "item_urn_of_shadows", "item_glimmer_cape", --微光 "item_force_staff", diff --git a/item_purchase_witch_doctor.lua b/item_purchase_witch_doctor.lua index 38c0bfab..05d7d672 100644 --- a/item_purchase_witch_doctor.lua +++ b/item_purchase_witch_doctor.lua @@ -12,15 +12,13 @@ local ItemsToBuy = "item_magic_stick", "item_bracer", "item_boots", - "item_energy_booster", + "item_arcane_boots", "item_urn_of_shadows", - "item_buckler", "item_ghost", "item_glimmer_cape", --微光 "item_force_staff", "item_ultimate_scepter", --蓝杖 "item_lotus_orb", --清莲宝珠 - "item_sheepstick" --羊刀 } ItemPurchaseSystem:CreateItemInformationTable(GetBot(), ItemsToBuy) diff --git a/item_purchase_zuus.lua b/item_purchase_zuus.lua index f5b3f1c7..0840578a 100644 --- a/item_purchase_zuus.lua +++ b/item_purchase_zuus.lua @@ -6,14 +6,12 @@ local ItemPurchaseSystem = dofile(GetScriptDirectory() .. "/util/ItemPurchaseSys local ItemsToBuy = { - "item_tango", "item_null_talisman", "item_clarity", "item_bottle", "item_boots", "item_magic_wand", --大魔棒7.14 - "item_null_talisman", - "item_energy_booster", + "item_arcane_boots", "item_veil_of_discord", --纷争 "item_aether_lens", --以太之镜7.06 "item_cyclone", --风杖 diff --git a/mode_farm_generic.lua b/mode_farm_generic.lua index 8d66fe8c..5a389707 100644 --- a/mode_farm_generic.lua +++ b/mode_farm_generic.lua @@ -12,7 +12,7 @@ local lanes = {LANE_TOP, LANE_MID, LANE_BOT}; local cause = ""; local cogsTarget = nil; local t3Destroyed = false; -local shrineTarget = nil; +--local shrineTarget = nil; local cLoc = nil; local farmLane = false; @@ -121,15 +121,15 @@ function GetDesire() if t3Destroyed == false then t3Destroyed = IsThereT3Detroyed(); - else - if bot:DistanceFromFountain() > 10000 then - shrineTarget = GetTargetShrine(); - local barracks = bot:GetNearbyBarracks(700, true); - if shrineTarget ~= nil and ( barracks == nil or #barracks == 0 ) and IsSuitableToDestroyShrine() then - cause = "shrine"; - return BOT_MODE_DESIRE_VERYHIGH; - end - end + --else + -- if bot:DistanceFromFountain() > 10000 then + -- shrineTarget = GetTargetShrine(); + -- local barracks = bot:GetNearbyBarracks(700, true); + -- if shrineTarget ~= nil and ( barracks == nil or #barracks == 0 ) and IsSuitableToDestroyShrine() then + -- cause = "shrine"; + -- return BOT_MODE_DESIRE_VERYHIGH; + -- end + -- end end if campUtils.IsStrongJungler(bot) and bot:GetLevel() >= 6 and bot:GetLevel() < 30 and not IsHumanPlayerInTeam() and GetGameMode() ~= GAMEMODE_MO @@ -165,7 +165,7 @@ function OnEnd() cogsTarget = nil; cogs = ""; cause = ""; - shrineTarget = nil; + --shrineTarget = nil; end function Think() @@ -199,15 +199,7 @@ function Think() print("Attack Cogs") bot:Action_AttackUnit( cogsTarget, true ); cause = ""; - return; - elseif cause == "shrine" then - if GetUnitToUnitDistance(bot, shrineTarget) > 500 then - bot:Action_MoveToLocation(shrineTarget:GetLocation()) - return - else - bot:Action_AttackUnit(shrineTarget, true) - return - end + return end if LaneCreeps ~= nil and #LaneCreeps > 0 then @@ -275,33 +267,33 @@ function IsThereT3Detroyed() return false; end -function GetTargetShrine() - local shrines = { - SHRINE_JUNGLE_1, - SHRINE_JUNGLE_2 - } - for _,s in pairs(shrines) do - local shrine = GetShrine(GetOpposingTeam(), s); - if shrine ~= nil and shrine:IsAlive() then - return shrine; - end - end - return nil; -end - -function IsSuitableToDestroyShrine() - local mode = bot:GetActiveMode(); - if bot:WasRecentlyDamagedByTower(2.0) or bot:WasRecentlyDamagedByAnyHero(3.0) - or mode == BOT_MODE_DEFEND_TOWER_TOP - or mode == BOT_MODE_DEFEND_TOWER_MID - or mode == BOT_MODE_DEFEND_TOWER_BOT - or mode == BOT_MODE_ATTACK - or mode == BOT_MODE_RETREAT and bot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH - then - return false; - end - return true; -end +--function GetTargetShrine() +-- local shrines = { +-- SHRINE_JUNGLE_1, +-- SHRINE_JUNGLE_2 +-- } +-- for _,s in pairs(shrines) do +-- local shrine = GetShrine(GetOpposingTeam(), s); +-- if shrine ~= nil and shrine:IsAlive() then +-- return shrine; +-- end +-- end +-- return nil; +--end +-- +--function IsSuitableToDestroyShrine() +-- local mode = bot:GetActiveMode(); +-- if bot:WasRecentlyDamagedByTower(2.0) or bot:WasRecentlyDamagedByAnyHero(3.0) +-- or mode == BOT_MODE_DEFEND_TOWER_TOP +-- or mode == BOT_MODE_DEFEND_TOWER_MID +-- or mode == BOT_MODE_DEFEND_TOWER_BOT +-- or mode == BOT_MODE_ATTACK +-- or mode == BOT_MODE_RETREAT and bot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH +-- then +-- return false; +-- end +-- return true; +--end function GetDistance(s, t) return math.sqrt((s[1]-t[1])*(s[1]-t[1]) + (s[2]-t[2])*(s[2]-t[2])); diff --git a/mode_push_tower_bot_generic.lua b/mode_push_tower_bot_generic.lua index dd64d4d1..d33d78cc 100644 --- a/mode_push_tower_bot_generic.lua +++ b/mode_push_tower_bot_generic.lua @@ -1,7 +1,7 @@ require( GetScriptDirectory().."/util/PushUtility"); -npcBot = GetBot(); -lane = LANE_BOT +local npcBot = GetBot() +local lane = LANE_BOT function GetDesire() return PushUtility.GetUnitPushLaneDesire(npcBot,lane) diff --git a/mode_push_tower_mid_generic.lua b/mode_push_tower_mid_generic.lua index 74e2697f..d33d78cc 100644 --- a/mode_push_tower_mid_generic.lua +++ b/mode_push_tower_mid_generic.lua @@ -1,7 +1,7 @@ require( GetScriptDirectory().."/util/PushUtility"); -npcBot = GetBot(); -lane = LANE_MID +local npcBot = GetBot() +local lane = LANE_BOT function GetDesire() return PushUtility.GetUnitPushLaneDesire(npcBot,lane) diff --git a/mode_push_tower_top_generic.lua b/mode_push_tower_top_generic.lua index 2e61cdd5..d33d78cc 100644 --- a/mode_push_tower_top_generic.lua +++ b/mode_push_tower_top_generic.lua @@ -1,7 +1,7 @@ require( GetScriptDirectory().."/util/PushUtility"); -npcBot = GetBot(); -lane = LANE_TOP +local npcBot = GetBot() +local lane = LANE_BOT function GetDesire() return PushUtility.GetUnitPushLaneDesire(npcBot,lane) diff --git a/mode_retreat_antimage.lua b/mode_retreat_antimage.lua new file mode 100644 index 00000000..2cb5fb33 --- /dev/null +++ b/mode_retreat_antimage.lua @@ -0,0 +1,21 @@ +local AbilityExtensions = require(GetScriptDirectory().."/util/AbilityAbstraction") + +function GetDesire() + local npc = GetBot() + local activeMode = npc:GetActiveMode() + local healthPercent = AbilityExtensions:GetHealthPercent(npc) + local manaPercent = AbilityExtensions:GetManaPercent(npc) + local desire = RemapValClamped(healthPercent, 0, 0.3, 0.85, 0.35) + if activeMode == BOT_MODE_LANING then + if healthPercent <= 0.25 and not (npc:GetUnitName() == "npc_dota_hero_huskar" and npc:GetAbility(3):GetLevel() >= 2) then + desire = RemapValClamped(healthPercent, 0.1, 0.3, 1, 0.4) + end + end + if activeMode == BOT_MODE_RETREAT and npc:DistanceFromFountain() <= 1000 and healthPercent >= 0.75 and manaPercent >= 0.85 then + desire = 0.1 + end + if npc:IsIllusion() or npc:HasModifier("modifier_skeleton_king_reincarnation_active") then + desire = 0.05 + end + return desire +end diff --git a/mode_retreat_furion.lua b/mode_retreat_furion.lua new file mode 100644 index 00000000..2cb5fb33 --- /dev/null +++ b/mode_retreat_furion.lua @@ -0,0 +1,21 @@ +local AbilityExtensions = require(GetScriptDirectory().."/util/AbilityAbstraction") + +function GetDesire() + local npc = GetBot() + local activeMode = npc:GetActiveMode() + local healthPercent = AbilityExtensions:GetHealthPercent(npc) + local manaPercent = AbilityExtensions:GetManaPercent(npc) + local desire = RemapValClamped(healthPercent, 0, 0.3, 0.85, 0.35) + if activeMode == BOT_MODE_LANING then + if healthPercent <= 0.25 and not (npc:GetUnitName() == "npc_dota_hero_huskar" and npc:GetAbility(3):GetLevel() >= 2) then + desire = RemapValClamped(healthPercent, 0.1, 0.3, 1, 0.4) + end + end + if activeMode == BOT_MODE_RETREAT and npc:DistanceFromFountain() <= 1000 and healthPercent >= 0.75 and manaPercent >= 0.85 then + desire = 0.1 + end + if npc:IsIllusion() or npc:HasModifier("modifier_skeleton_king_reincarnation_active") then + desire = 0.05 + end + return desire +end diff --git a/mode_rune_generic.lua b/mode_rune_generic.lua index 626a6bc4..dcbe09ef 100644 --- a/mode_rune_generic.lua +++ b/mode_rune_generic.lua @@ -124,26 +124,26 @@ function Think() end end - if runeStatus == RUNE_STATUS_AVAILABLE then - if bottle ~= nil and closestDist < 1200 then - local bottle_charge = bottle:GetCurrentCharges() - if bottle:IsFullyCastable() and bottle_charge > 0 and ( bot:GetHealth() < bot:GetMaxHealth() or bot:GetMana() < bot:GetMaxMana() ) then - bot:Action_UseAbility( bottle ); - return; - end - end + -- if runeStatus == RUNE_STATUS_AVAILABLE then + -- if bottle ~= nil and closestDist < 1200 then + -- local bottle_charge = bottle:GetCurrentCharges() + -- if bottle:IsFullyCastable() and bottle_charge > 0 and ( bot:GetHealth() < bot:GetMaxHealth() or bot:GetMana() < bot:GetMaxMana() ) then + -- bot:Action_UseAbility( bottle ); + -- return; + -- end + -- end - if closestDist > 200 then - bot:Action_MoveToLocation(GetRuneSpawnLocation(closestRune)); - return - else - bot:Action_PickUpRune(closestRune); - return - end - else - bot:Action_MoveToLocation(GetRuneSpawnLocation(closestRune)); - return - end + -- if closestDist > 200 then + -- bot:Action_MoveToLocation(GetRuneSpawnLocation(closestRune)); + -- return + -- else + -- bot:Action_PickUpRune(closestRune); + -- return + -- end + -- else + -- bot:Action_MoveToLocation(GetRuneSpawnLocation(closestRune)); + -- return + -- end end diff --git a/mode_side_shop_generic.lua b/mode_side_shop_generic.lua index 755f8300..6f4508eb 100644 --- a/mode_side_shop_generic.lua +++ b/mode_side_shop_generic.lua @@ -5,40 +5,40 @@ ---------------------------------------------------------------------------------------------------- local utility = require( GetScriptDirectory().."/utility" ) function GetDesire() - - local npcBot = GetBot(); - - local desire = 0.0; - - local enemys = npcBot:GetNearbyHeroes(600,true,BOT_MODE_NONE) - if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:WasRecentlyDamagedByAnyHero(5.0) or #enemys>=1) --不应打断持续施法 - then - return 0 - end - - if ( npcBot.sideShopMode == true and npcBot:GetGold() >= npcBot:GetNextItemPurchaseValue()) then - local d=npcBot:DistanceFromSideShop() - if d<2500 - then - desire = (2500-d)/2500*0.3+0.3; --根据离边路商店的距离返回欲望值 - end - end - - return desire + return 0 + --local npcBot = GetBot(); + -- + --local desire = 0.0; + -- + --local enemys = npcBot:GetNearbyHeroes(600,true,BOT_MODE_NONE) + --if ( npcBot:IsUsingAbility() or npcBot:IsChanneling() or npcBot:WasRecentlyDamagedByAnyHero(5.0) or #enemys>=1) --不应打断持续施法 + --then + -- return 0 + --end + -- + --if ( npcBot.sideShopMode == true and npcBot:GetGold() >= npcBot:GetNextItemPurchaseValue()) then + -- local d=npcBot:DistanceFromSideShop() + -- if d<2500 + -- then + -- desire = (2500-d)/2500*0.3+0.3; --根据离边路商店的距离返回欲望值 + -- end + --end + -- + --return desire end function Think() - local npcBot = GetBot(); - - local shopLoc1 = GetShopLocation( GetTeam(), SHOP_SIDE ); - local shopLoc2 = GetShopLocation( GetTeam(), SHOP_SIDE2 ); - - if ( GetUnitToLocationDistance(npcBot, shopLoc1) <= GetUnitToLocationDistance(npcBot, shopLoc2) ) then --选择前往距离自己更近的商店 - npcBot:Action_MoveToLocation( shopLoc1 ); - else - npcBot:Action_MoveToLocation( shopLoc2 ); - end + --local npcBot = GetBot(); + -- + --local shopLoc1 = GetShopLocation( GetTeam(), SHOP_SIDE ); + --local shopLoc2 = GetShopLocation( GetTeam(), SHOP_SIDE2 ); + -- + --if ( GetUnitToLocationDistance(npcBot, shopLoc1) <= GetUnitToLocationDistance(npcBot, shopLoc2) ) then --选择前往距离自己更近的商店 + -- npcBot:Action_MoveToLocation( shopLoc1 ); + --else + -- npcBot:Action_MoveToLocation( shopLoc2 ); + --end end ---------------------------------------------------------------------------------------------------- \ No newline at end of file diff --git a/mode_team_roam_generic.lua b/mode_team_roam_generic.lua index f9f4b66c..ea3ecbcf 100644 --- a/mode_team_roam_generic.lua +++ b/mode_team_roam_generic.lua @@ -4,6 +4,7 @@ ---------------------------------------------------------------------------- local utility = require( GetScriptDirectory().."/utility" ) local role = require(GetScriptDirectory() .. "/util/RoleUtility") +local AbilityExtensions = require(GetScriptDirectory().."/util/AbilityAbstraction") local HeroMode function OnStart() @@ -17,236 +18,240 @@ function GetDesire() then return 0 end + if npcBot:IsChanneling() or npcBot:IsUsingAbility() then + return npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM and 1 or 0 + end --local ShrineDesire=GetShrineDesire() - --local TeamRoamDesire=GetTeamRoamDesire() - local ShrineDesire=0 - local TeamRoamDesire=0 - - if(ShrineDesire>TeamRoamDesire) - then - HeroMode="Shrine" - return ShrineDesire - else - HeroMode="TeamRoam" - return TeamRoamDesire - end + local TeamRoamDesire=GetTeamRoamDesire() + --local ShrineDesire=0 + --local TeamRoamDesire=0 + + --if(ShrineDesire>TeamRoamDesire) + --then + -- HeroMode="Shrine" + -- return ShrineDesire + --else + -- HeroMode="TeamRoam" + return TeamRoamDesire + --end end function Think() - if(HeroMode=="Shrine") - then - ShrineThink() - elseif(HeroMode=="TeamRoam") + --if(HeroMode=="Shrine") + --then + -- ShrineThink() + --else + if(HeroMode=="TeamRoam") then TeamRoamThink() end end -function GetShrineDesire() - local npcBot=GetBot() - - if ( npcBot:IsUsingAbility() or npcBot:IsChanneling()) - then - return 0 - end - - local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) - - if(npcBot.ShrineTime==nil) - then - npcBot.ShrineTime=0 - end - - if( npcBot:IsAlive()==false or - (npcBot:DistanceFromFountain()<=6000 and (npcBot:GetStashValue()>400 or npcBot:GetMaxMana()-npcBot:GetMana()>=400) and #enemys==0) or - (npcBot.GoingToShrine==true and GetShrineCooldown(npcBot.Shrine)>10 and IsShrineHealing(npcBot.Shrine)==false) or - npcBot:GetFactor()>1.8 or - (GetUnitToUnitDistance(npcBot,npcBot.Shrine)>7500) or - (npcBot.Shrine==nil or npcBot.GoingToShrine==false) - ) - then - npcBot.GoingToShrine=false - npcBot.Shrine=nil - end - - if(npcBot.GoingToShrine==false) - then - ConsiderShrine() - end - - if(npcBot.GoingToShrine==true and (GetUnitToUnitDistance(npcBot,npcBot.Shrine)>=300 or IsShrineHealing(npcBot.Shrine)==false) - and DotaTime()+GetUnitToUnitDistance(npcBot,npcBot.Shrine)/npcBot:GetCurrentMovementSpeed() >= npcBot.ShrineTime) - then - local HealthFactor=npcBot:GetHealth()/npcBot:GetMaxHealth() - return 0.7+(1-HealthFactor)*0.3 - end - return 0.0; -end - -function ConsiderShrine() - local Shrines={ SHRINE_JUNGLE_1, - SHRINE_JUNGLE_2 } - - local npcBot=GetBot() - local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) - - if(npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot.GoingToShrine~=true and - (npcBot:GetFactor()<1.2 or npcBot:GetMaxHealth()-npcBot:GetHealth()>=400) and - (npcBot:GetMaxMana()-npcBot:GetMana()<=400 and npcBot:GetMaxHealth()-npcBot:GetHealth()<=1000 or #enemys>0 )) - then - local TargetShrine - local min_distance=10000 - for _,s in pairs(Shrines) - do - local shrine=GetShrine(GetTeam(),s) - if(shrine~=nil and shrine:IsAlive()) - then - if(GetShrineCooldown(shrine)<10 or IsShrineHealing(shrine)==true) - then - d=GetUnitToUnitDistance(npcBot,shrine) - if(d=300) and GetUnitToUnitDistance(ally,TargetShrine)<=7500-allyfactor*1500) and ally:IsAlive() - then - ally.Shrine=TargetShrine - ally.GoingToShrine=true - - local distance = GetUnitToUnitDistance(ally,TargetShrine)/ally:GetCurrentMovementSpeed() - if distance>max_distance - then - max_distance=distance - end - end - end - - - for _,ally in pairs (allys) - do - if(TargetShrine==ally.Shrine) - then - ally.ShrineTime=DotaTime()+max_distance - --npcBot:ActionImmediate_Chat("Enjoy together"..ally:GetUnitName()..ally.ShrineTime,false) - end - end - - npcBot.Shrine=TargetShrine - npcBot.GoingToShrine=true - - npcBot.ShrineTime=DotaTime()+max_distance - npcBot:ActionImmediate_Chat("I want to use Shrine,let's enjoy together! 我想要使用神泉,快来一起享用",false) - --npcBot:ActionImmediate_Ping(shrineLocation.x,shrineLocation.y,true) - - end - end - -end - -function ShrineThink() - local npcBot=GetBot() - - if ( npcBot:IsUsingAbility() or npcBot:IsChanneling()) - then - return - end - - if(npcBot.GoingToShrine==true and npcBot.Shrine~=nil) - then - if(GetUnitToUnitDistance(npcBot,npcBot.Shrine)<300 and GetShrineCooldown(npcBot.Shrine)<5) - then - local allys = npcBot:GetNearbyHeroes( 1600, false, BOT_MODE_NONE ); - local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) - local ready=true - - if(#enemys>0) - then - ready=true - else - for _,ally in pairs(GetUnitList(UNIT_LIST_ALLIED_HEROES)) - do - local allyfactor=ally:GetHealth()/ally:GetMaxHealth()+ally:GetMana()/ally:GetMaxMana() - local distance=GetUnitToUnitDistance(ally,npcBot.Shrine) - if(IsPlayerBot(ally:GetPlayerID())==false and distance>500 and allyfactor<1.6 and distance<6000) - then - if(ally.ShrineHuman==nil) - then - ally.ShrineHuman={} - ally.ShrineHuman.timer=DotaTime() - ally.ShrineHuman.distance=distance - ready=false - else - if(DotaTime()-ally.ShrineHuman.timer>5) - then - if(distance500 and ally.Shrine==npcBot.Shrine) - then - ready=false - end - end - end - end - - if(ready==true) - then - npcBot:Action_UseShrine(npcBot.Shrine) - else - npcBot:Action_MoveToUnit(npcBot.Shrine) - end - else - npcBot:Action_MoveToUnit(npcBot.Shrine) - end - end - - -- if(IsShrineHealing(npcBot.Shrine)==true) - -- then - -- npcBot:Action_MoveToUnit(npcBot.Shrine) - -- end - - -- local shrines2=npcBot:GetNearbyShrines(1600,false) - -- if(npcBot:GetHealth()/npcBot:GetMaxHealth()+npcBot:GetMana()/npcBot:GetMaxMana()<1.8) - -- then - -- for _,s in pairs(shrines2) - -- do - -- if(IsShrineHealing(s)==true and GetUnitToUnitDistance(npcBot,s)>=450) - -- then - -- npcBot:Action_MoveToLocation(s:GetLocation()) - -- return - -- end - -- end - -- end - -end +--function GetShrineDesire() +-- local npcBot=GetBot() +-- +-- if ( npcBot:IsUsingAbility() or npcBot:IsChanneling()) +-- then +-- return 0 +-- end +-- +-- local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) +-- +-- if(npcBot.ShrineTime==nil) +-- then +-- npcBot.ShrineTime=0 +-- end +-- +-- if( npcBot:IsAlive()==false or +-- (npcBot:DistanceFromFountain()<=6000 and (npcBot:GetStashValue()>400 or npcBot:GetMaxMana()-npcBot:GetMana()>=400) and #enemys==0) or +-- (npcBot.GoingToShrine==true and GetShrineCooldown(npcBot.Shrine)>10 and IsShrineHealing(npcBot.Shrine)==false) or +-- npcBot:GetFactor()>1.8 or +-- (GetUnitToUnitDistance(npcBot,npcBot.Shrine)>7500) or +-- (npcBot.Shrine==nil or npcBot.GoingToShrine==false) +-- ) +-- then +-- npcBot.GoingToShrine=false +-- npcBot.Shrine=nil +-- end +-- +-- if(npcBot.GoingToShrine==false) +-- then +-- ConsiderShrine() +-- end +-- +-- if(npcBot.GoingToShrine==true and (GetUnitToUnitDistance(npcBot,npcBot.Shrine)>=300 or IsShrineHealing(npcBot.Shrine)==false) +-- and DotaTime()+GetUnitToUnitDistance(npcBot,npcBot.Shrine)/npcBot:GetCurrentMovementSpeed() >= npcBot.ShrineTime) +-- then +-- local HealthFactor=npcBot:GetHealth()/npcBot:GetMaxHealth() +-- return 0.7+(1-HealthFactor)*0.3 +-- end +-- return 0.0; +--end +-- +--function ConsiderShrine() +-- local Shrines={ SHRINE_JUNGLE_1, +-- SHRINE_JUNGLE_2 } +-- +-- local npcBot=GetBot() +-- local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) +-- +-- if(npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot.GoingToShrine~=true and +-- (npcBot:GetFactor()<1.2 or npcBot:GetMaxHealth()-npcBot:GetHealth()>=400) and +-- (npcBot:GetMaxMana()-npcBot:GetMana()<=400 and npcBot:GetMaxHealth()-npcBot:GetHealth()<=1000 or #enemys>0 )) +-- then +-- local TargetShrine +-- local min_distance=10000 +-- for _,s in pairs(Shrines) +-- do +-- local shrine=GetShrine(GetTeam(),s) +-- if(shrine~=nil and shrine:IsAlive()) +-- then +-- if(GetShrineCooldown(shrine)<10 or IsShrineHealing(shrine)==true) +-- then +-- d=GetUnitToUnitDistance(npcBot,shrine) +-- if(d=300) and GetUnitToUnitDistance(ally,TargetShrine)<=7500-allyfactor*1500) and ally:IsAlive() +-- then +-- ally.Shrine=TargetShrine +-- ally.GoingToShrine=true +-- +-- local distance = GetUnitToUnitDistance(ally,TargetShrine)/ally:GetCurrentMovementSpeed() +-- if distance>max_distance +-- then +-- max_distance=distance +-- end +-- end +-- end +-- +-- +-- for _,ally in pairs (allys) +-- do +-- if(TargetShrine==ally.Shrine) +-- then +-- ally.ShrineTime=DotaTime()+max_distance +-- --npcBot:ActionImmediate_Chat("Enjoy together"..ally:GetUnitName()..ally.ShrineTime,false) +-- end +-- end +-- +-- npcBot.Shrine=TargetShrine +-- npcBot.GoingToShrine=true +-- +-- npcBot.ShrineTime=DotaTime()+max_distance +-- npcBot:ActionImmediate_Chat("I want to use Shrine,let's enjoy together! 我想要使用神泉,快来一起享用",false) +-- --npcBot:ActionImmediate_Ping(shrineLocation.x,shrineLocation.y,true) +-- +-- end +-- end +-- +--end +-- +--function ShrineThink() +-- local npcBot=GetBot() +-- +-- if ( npcBot:IsUsingAbility() or npcBot:IsChanneling()) +-- then +-- return +-- end +-- +-- if(npcBot.GoingToShrine==true and npcBot.Shrine~=nil) +-- then +-- if(GetUnitToUnitDistance(npcBot,npcBot.Shrine)<300 and GetShrineCooldown(npcBot.Shrine)<5) +-- then +-- local allys = npcBot:GetNearbyHeroes( 1600, false, BOT_MODE_NONE ); +-- local enemys = npcBot:GetNearbyHeroes(1600,true,BOT_MODE_NONE) +-- local ready=true +-- +-- if(#enemys>0) +-- then +-- ready=true +-- else +-- for _,ally in pairs(GetUnitList(UNIT_LIST_ALLIED_HEROES)) +-- do +-- local allyfactor=ally:GetHealth()/ally:GetMaxHealth()+ally:GetMana()/ally:GetMaxMana() +-- local distance=GetUnitToUnitDistance(ally,npcBot.Shrine) +-- if(IsPlayerBot(ally:GetPlayerID())==false and distance>500 and allyfactor<1.6 and distance<6000) +-- then +-- if(ally.ShrineHuman==nil) +-- then +-- ally.ShrineHuman={} +-- ally.ShrineHuman.timer=DotaTime() +-- ally.ShrineHuman.distance=distance +-- ready=false +-- else +-- if(DotaTime()-ally.ShrineHuman.timer>5) +-- then +-- if(distance500 and ally.Shrine==npcBot.Shrine) +-- then +-- ready=false +-- end +-- end +-- end +-- end +-- +-- if(ready==true) +-- then +-- npcBot:Action_UseShrine(npcBot.Shrine) +-- else +-- npcBot:Action_MoveToUnit(npcBot.Shrine) +-- end +-- else +-- npcBot:Action_MoveToUnit(npcBot.Shrine) +-- end +-- end +-- +-- -- if(IsShrineHealing(npcBot.Shrine)==true) +-- -- then +-- -- npcBot:Action_MoveToUnit(npcBot.Shrine) +-- -- end +-- +-- -- local shrines2=npcBot:GetNearbyShrines(1600,false) +-- -- if(npcBot:GetHealth()/npcBot:GetMaxHealth()+npcBot:GetMana()/npcBot:GetMaxMana()<1.8) +-- -- then +-- -- for _,s in pairs(shrines2) +-- -- do +-- -- if(IsShrineHealing(s)==true and GetUnitToUnitDistance(npcBot,s)>=450) +-- -- then +-- -- npcBot:Action_MoveToLocation(s:GetLocation()) +-- -- return +-- -- end +-- -- end +-- -- end +-- +--end function GetTeamRoamDesire() local npcBot=GetBot() @@ -282,9 +287,9 @@ function ConsiderTeamRoam() local nearBuilding = utility.GetNearestBuilding(GetTeam(), npcBot:GetLocation()) local location = utility.GetUnitsTowardsLocation(nearBuilding,GetAncient(GetTeam()),600) npcBot.TeamRoamAssemblyPoint=location - npcBot:ActionImmediate_Chat("Let's Gank "..string.gsub(target:GetUnitName(),"npc_dota_hero_","").." together! ",false) - print(npcBot:GetPlayerID().." @TeamRoam@ Let's Gank together! Factor:"..factor.." target:"..target:GetUnitName()) - npcBot:ActionImmediate_Ping(location.x,location.y,true) + --npcBot:ActionImmediate_Chat("Let's Gank "..string.gsub(target:GetUnitName(),"npc_dota_hero_","").." together! ",false) + --print(npcBot:GetPlayerID().." @TeamRoam@ Let's Gank together! Factor:"..factor.." target:"..target:GetUnitName()) + --npcBot:ActionImmediate_Ping(location.x,location.y,true) for _,npcAlly in pairs(allys) do @@ -297,8 +302,8 @@ function ConsiderTeamRoam() npcAlly.TeamRoamLeader=npcBot npcAlly.TeamRoamTimer=DotaTime() npcAlly:SetTarget(target) - npcBot:ActionImmediate_Chat(string.gsub(npcAlly:GetUnitName(),"npc_dota_hero_","").." come to Gank! Factor:"..factor2,false) - print(npcBot:GetPlayerID().." @TeamRoam@"..npcAlly:GetUnitName().." want to Gank together!Factor:"..factor2) + --npcBot:ActionImmediate_Chat(string.gsub(npcAlly:GetUnitName(),"npc_dota_hero_","").." come to Gank! Factor:"..factor2,false) + --print(npcBot:GetPlayerID().." @TeamRoam@"..npcAlly:GetUnitName().." want to Gank together!Factor:"..factor2) end end @@ -432,7 +437,7 @@ function GetEnemyFactor(npcEnemy,allys) then factor=factor*1.2 end - print(npcBot:GetPlayerID().." =[TeamRoam] Enemy/"..npcEnemy:GetUnitName().."/ sumdamage:"..sumdamage.."/ Factor:"..factor) +--[[ print(npcBot:GetPlayerID().." =[TeamRoam] Enemy/"..npcEnemy:GetUnitName().."/ sumdamage:"..sumdamage.."/ Factor:"..factor)]] return math.min(1.0,factor),suitableallys end return 0,0 @@ -484,6 +489,35 @@ function GetLocationTowardsLocation(vMyLocation,vTargetLocation, nUnits) return vMyLocation+nUnits*tempvector end +local wardTargets = { + "npc_dota_techies_remote_mine", + "npc_dota_techies_stasis_trap", + "npc_dota_techies_land_mine", + "npc_dota_techies_minefield_sign", + "npc_dota_juggernaut_healing_ward", + "npc_dota_phoenix_sun", + "npc_dota_visage_familiar3", + "npc_dota_unit_tombstone4", + "npc_dota_pugna_nether_ward_4", + "npc_dota_unit_tombstone3", + "npc_dota_visage_familiar2", + "npc_dota_pugna_nether_ward_43", + "npc_dota_unit_tombstone2", + "npc_dota_visage_familiar1", + "npc_dota_pugna_nether_ward_2", + "npc_dota_shadow_shaman_ward_3", + "npc_dota_venomancer_plague_ward_4", + "npc_dota_venomancer_plague_ward_3", + "npc_dota_unit_tombstone1", + "npc_dota_pugna_nether_ward_1", + "npc_dota_shadow_shaman_ward_2", + "npc_dota_shadow_shaman_ward_1", + "npc_dota_venomancer_plague_ward_2", + "npc_dota_venomancer_plague_ward_1", +} + +local FindEnemyWardTargets + function TeamRoamThink() local npcBot=GetBot() @@ -497,6 +531,9 @@ function TeamRoamThink() return end end + if npcBot:GetTarget() ~= nil and not npcBot:GetTarget():IsAlive() then + npcBot:SetTarget() + end if(npcBot.TeamRoamState=="Assemble") then @@ -558,8 +595,25 @@ function TeamRoamThink() end end + local enemyStaticTargets = {} + local myTeam = npcBot:GetTeam() + if FindEnemyWardTargets == nil then + FindEnemyWardTargets = AbilityExtensions:EveryManySeconds(1, function() + enemyStaticTargets = GetUnitList(UNIT_LIST_ALL) + enemyStaticTargets = AbilityExtensions:Filter(enemyStaticTargets, function(t) + return t:GetTeam() ~= myTeam and GetUnitToUnitDistance(npcBot, t) <= npcBot:GetAttackRange() + 150 + end) + enemyStaticTargets = AbilityExtensions:Map(enemyStaticTargets, function(t) + return { t, AbilityExtensions:IndexOf(wardTargets, t:GetUnitName()) } + end) + enemyStaticTargets = AbilityExtensions:Filter(enemyStaticTargets, function(t) return t[2] ~= -1 end) + enemyStaticTargets = AbilityExtensions:SortByMinFirst(enemyStaticTargets, function(t) return t[2] end) + end) + end + FindEnemyWardTargets() + local seeninfo=GetHeroLastSeenInfo(npcBot.TeamRoamTargetID) - if(seeinfo~=nil) + if(seeninfo~=nil) then local seenpoint=seeninfo[1].location seenpoint=GetLocationTowardsLocation(seenpoint,GetAncient(utility.GetOtherTeam()):GetLocation(),1000) @@ -575,19 +629,38 @@ function TeamRoamThink() do npcAlly.TeamRoamTargetID=target2:GetPlayerID() end - npcBot:ActionImmediate_Chat("Target Change to "..string.gsub(target2:GetUnitName(),"npc_dota_hero_",""),false) - print(npcBot:GetPlayerID().." Target Change!factor:"..factor.." target:"..target2:GetUnitName()) + --npcBot:ActionImmediate_Chat("Target Change to "..string.gsub(target2:GetUnitName(),"npc_dota_hero_",""),false) + --print(npcBot:GetPlayerID().." Target Change!factor:"..factor.." target:"..target2:GetUnitName()) else npcBot.TeamRoam=false for i,npcAlly in pairs(GetUnitList(UNIT_LIST_ALLIED_HEROES)) do npcAlly.TeamRoam=false end - npcBot:ActionImmediate_Chat("Target disappear, Ganking stop",false) - print(npcBot:GetPlayerID().." Target disappear!Roaming stop") + --npcBot:ActionImmediate_Chat("Target disappear, Ganking stop",false) + --print(npcBot:GetPlayerID().." Target disappear!Roaming stop") end end + local dps = npcBot:GetAttackDamage() * 1 / npcBot:GetSecondsPerAttack() + if AbilityExtensions:GetHealthPercent(target) >= 0.5 and AbilityExtensions:Any(enemyStaticTargets) then + local selectedWardTarget = enemyStaticTargets[1] + if string.match("npc_dota_techies_") then + if npcBot:GetAttackRange() > 500 then + npcBot:SetTarget(selectedWardTarget) + npcBot:Action_AttackUnit(selectedWardTarget, false) + end + elseif string.match("npc_dota_venomancer_plague_ward") then + if selectedWardTarget:GetHealth() < selectedWardTarget:GetActualIncomingDamage(dps*2, DAMAGE_TYPE_PHYSICAL) then + npcBot:SetTarget(selectedWardTarget) + npcBot:Action_AttackUnit(selectedWardTarget, false) + end + else + npcBot:SetTarget(selectedWardTarget) + npcBot:Action_AttackUnit(selectedWardTarget, false) + end + return + end if(GetUnitToLocationDistance(npcBot,seenpoint)<=1200) then if(target~=nil) diff --git a/mode_ward_generic.lua b/mode_ward_generic.lua index 7ad54387..d6a08026 100644 --- a/mode_ward_generic.lua +++ b/mode_ward_generic.lua @@ -128,14 +128,14 @@ function OnEnd() bot.steal = false; itemWard = nil; wt = nil; - local wardSlot = bot:FindItemSlot('item_ward_observer'); - if wardSlot >=0 and wardSlot <= 5 then - local mostCostItem = FindMostItemSlot(); - if mostCostItem ~= -1 then - bot:ActionImmediate_SwapItems( wardSlot, mostCostItem ); - return - end - end + -- local wardSlot = bot:FindItemSlot('item_ward_observer'); + -- if wardSlot >=0 and wardSlot <= 5 then + -- local mostCostItem = FindMostItemSlot(); + -- if mostCostItem ~= -1 then + -- bot:ActionImmediate_SwapItems( wardSlot, mostCostItem ); + -- return + -- end + -- end end function Think() @@ -145,7 +145,7 @@ function Think() end if wt ~= nil then - bot:Action_UseAbilityOnEntity(itemWard, wt); + -- bot:Action_UseAbilityOnEntity(itemWard, wt); return end @@ -298,7 +298,6 @@ function IsSuitableToWard() local mode = bot:GetActiveMode(); if ( ( mode == BOT_MODE_RETREAT and bot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) or mode == BOT_MODE_ATTACK - or mode == BOT_MODE_RUNE or mode == BOT_MODE_DEFEND_ALLY or mode == BOT_MODE_DEFEND_TOWER_TOP or mode == BOT_MODE_DEFEND_TOWER_MID diff --git a/team_desires.lua b/team_desires.lua index b37fc0a1..fba6091a 100644 --- a/team_desires.lua +++ b/team_desires.lua @@ -369,7 +369,7 @@ function GetRealHero(Candidates) for i,unit in pairs(Candidates) do local int = unit:GetAttributeValue(2); local baseRegen=0.01; - if unit:GetUnitName()==npc_dota_hero_techies then + if unit:GetUnitName()=="npc_dota_hero_techies" then baseRegen=0.02; end diff --git a/util/AbilityAbstraction.lua b/util/AbilityAbstraction.lua index 8b9a38e6..3ebe6d24 100644 --- a/util/AbilityAbstraction.lua +++ b/util/AbilityAbstraction.lua @@ -4,27 +4,53 @@ local binlib = require(GetScriptDirectory().."/util/BinDecHex") -- LINQ functions +local magicTable = {} +local function NewTable() + local a = {} + setmetatable(a, magicTable) + return a +end +magicTable.__index = magicTable + M.Range = function(self, min, max, step) if step == nil then step = 1 end - local g = {} + local g = NewTable() for i = min, max, step do table.insert(g, i) end return g end -M.Contains = function(self, tb, value, compare) - compare = compare or function(a, b) return a == b end +M.Contains = function(self, tb, value, equals) + equals = equals or function(a, b) return a == b end for _, v in ipairs(tb) do - if compare(v, value) then + if equals(v, value) then + return true + end + end + return false +end + +M.ContainsKey = function(self, tb, key, equals) + equals = equals or function(a, b) return a == b end + for k, _ in pairs(tb) do + if equals(key, k) then return true end end return false end +function M:Keys(tb) + local g = NewTable() + for k, _ in pairs(tb) do + table.insert(g, k) + end + return g +end + M.Filter = function(self, tb, filter) - local g = {} + local g = NewTable() for k, v in ipairs(tb) do if filter(v, k) then table.insert(g, v) @@ -33,7 +59,7 @@ M.Filter = function(self, tb, filter) return g end M.FilterNot = function(self, tb, filter) - local g = {} + local g = NewTable() for k, v in ipairs(tb) do if not filter(v, k) then table.insert(g, v) @@ -52,14 +78,28 @@ M.Count = function(self, tb, filter) return g end +function M:NonEmpty(self, tb) + return self:Filter(tb, function(t) + return t ~= nil and #t ~= 0 + end) +end + M.Map = function(self, tb, transform) - local g = {} + local g = NewTable() for k, v in ipairs(tb) do g[k] = transform(v) end return g end +function M:MapDic(tb, transform) + local g = NewTable() + for k, v in pairs(tb) do + g[k] = transform(k, v) + end + return g +end + M.ForEach = function(self, tb, action) for k, v in ipairs(tb) do action(v, k) @@ -92,7 +132,7 @@ M.Aggregate = function(self, seed, tb, aggregate) end M.ShallowCopy = function(self, tb) - local g = {} + local g = NewTable() for k, v in pairs(tb) do g[k] = v end @@ -108,7 +148,7 @@ M.First = function(self, tb, filter) end M.Skip = function(self, tb, number) - local g = {} + local g = NewTable() local i = 0 for _, v in ipairs(tb) do i = i + 1 @@ -120,7 +160,7 @@ M.Skip = function(self, tb, number) end M.Take = function(self, tb, number) - local g = {} + local g = NewTable() local i = 0 for _, v in ipairs(tb) do i = i + 1 @@ -134,8 +174,8 @@ M.Take = function(self, tb, number) end local function deepCopy(self, tb) - local copiedTables = {} - local g = {} + local copiedTables = NewTable() + local g = NewTable() table.insert(copiedTables, tb) for k, v in pairs(tb) do if type(v) ~= "table" then @@ -152,14 +192,19 @@ local function deepCopy(self, tb) end M.DeepCopy = deepCopy -M.Concat = function(self, a, b) - if type(a) ~= "table" or type(b) ~= "table" then - return a..b - end - local g = self:ShallowCopy(a) - for _, v in ipairs(b) do - table.insert(g, v) +M.Concat = function(self, a, ...) + local g = NewTable() + local rec + rec = function(b, ...) + if b == nil then + return + end + for _, v in ipairs(b) do + table.insert(g, v) + end + rec(...) end + rec(a, ...) return g end @@ -173,7 +218,7 @@ M.Remove = function(self, a, b) return g end M.RemoveAll = function(self, a, b) - local g = {} + local g = NewTable() for _,v in pairs(a) do if not self:Contains(b, v) then table.insert(g, v) @@ -186,11 +231,47 @@ M.Prepend = function(self, a, b) return self:Concat(b, a) end -M.Distinct = function(self, tb, compare) - compare = compare or function(a, b) return a == b end - local g = {} +M.GroupBy = function(self, collection, keySelector, elementSelector, resultSelector, comparer) + comparer = comparer or function(a,b) return a==b end + resultSelector = resultSelector or function(key, value) return value end + elementSelector = elementSelector or self.IdentityFunction + local keys = NewTable() + local values = NewTable() + for _, k in ipairs(collection) do + local keyFound = false + for readKeyIndex, readKey in ipairs(keys) do + if comparer(readKey, keySelector(k)) then + keyFound = true + table.insert(values[readKeyIndex], elementSelector(k)) + break + end + end + if not keyFound then + table.insert(keys, keySelector(k)) + table.insert(values, { elementSelector(k) }) + end + end + return self:Map2(keys, values, resultSelector) +end + +M.Partition = function(self, tb, filter) + local a = NewTable() + local b = NewTable() + for k, v in pairs(tb) do + if filter(v, k) then + table.insert(a, v) + else + table.insert(b, v) + end + end + return a, b +end + +M.Distinct = function(self, tb, equals) + equals = equals or function(a, b) return a == b end + local g = NewTable() for _, v in pairs(tb) do - if not self:Contains(tb, v, compare) then + if not self:Contains(g, v, equals) then table.insert(g, v) end end @@ -198,7 +279,7 @@ M.Distinct = function(self, tb, compare) end M.Reverse = function(self, tb) - local g = {} + local g = NewTable() for i = #tb, 1, -1 do table.insert(g, tb[i]) end @@ -209,8 +290,43 @@ M.Last = function(self, tb, filter) return self:First(self:Reverse(tb), filter) end +function M:Identity(t) return t end +M.IdentityFunction = function(t) return t end + +function M:Max(tb, map) + if #tb == 0 then + return nil + end + map = map or self.IdentityFunction + local maxv, maxm = tb[1], map(tb[1]) + for i = 2, #tb do + local m = map(tb[i]) + if m > maxm then + maxm = m + maxv = tb[i] + end + end + return maxv +end + +function M:Min(tb, map) + if #tb == 0 then + return nil + end + map = map or self.IdentityFunction + local maxv, maxm = tb[1], map(tb[1]) + for i = 2, #tb do + local m = map(tb[i]) + if m < maxm then + maxm = m + maxv = tb[i] + end + end + return maxv +end + M.Repeat = function(self, element, count) - local g = {} + local g = NewTable() for i = 1, count do table.insert(g, element) end @@ -219,7 +335,7 @@ end M.Select = M.Map M.SelectMany = function(self, tb, map, filter) - local g = {} + local g = NewTable() for _, source in ipairs(tb) do local collection = map(source) for index, value in ipairs(collection) do @@ -231,12 +347,14 @@ M.SelectMany = function(self, tb, map, filter) return g end +M.Where = M.Filter + M.SkipLast = function(self, tb, number) return self:Skip(self:Reverse(tb), number) end M.Replace = function(self, tb, filter, map) - local g = {} + local g = NewTable() for k, v in ipairs(tb) do if filter(v, k) then table.insert(g, map(v, k)) @@ -248,7 +366,7 @@ M.Replace = function(self, tb, filter, map) end M.IndexOf = function(self, tb, filter) - local g = {} + local g = NewTable() for k, v in ipairs(tb) do if type(filter) == "function" then if filter(v, k) then @@ -269,7 +387,7 @@ M.Zip2 = function(self, tb1, tb2, map) return {a, b} end end - local g = {} + local g = NewTable() for i = 1, #tb1 do table.insert(g, map(tb1[i], tb2[i])) end @@ -283,7 +401,7 @@ M.ForEach2 = function(self, tb1, tb2, func) end M.Map2 = function(self, tb1, tb2, map) - local g = {} + local g = NewTable() for i = 1, #tb1 do table.insert(g, map(tb1[i], tb2[i], i)) end @@ -294,7 +412,7 @@ M.Filter2 = function(self, tb1, tb2, filter, map) if map == nil then map = function(a,b,c) return {a,b,c} end end - local g = {} + local g = NewTable() for i = 1, #tb1 do if filter(tb1[i], tb2[i], i) then table.insert(map(tb1[i], tb2[i], i)) @@ -331,7 +449,7 @@ M.MergeSort = function(self, tb, sort) sort = function(a, b) return a-b end end local function Merge(a, b) - local g = {} + local g = NewTable() local aLen = #a local bLen = #b local i = 1 @@ -372,48 +490,101 @@ end M.Sort = M.SlowSort M.SortByMaxFirst = function(self, tb, map) + map = map or function(a, b) return b-a end return self:Sort(tb, function(a, b) return map(b) - map(a) end) end M.SortByMinFirst = function(self, tb, map) + map = map or function(a, b) return a-b end return self:Sort(tb, function(a, b) return map(a) - map(b) end) end --- bot mode behaviour +function M:Remove_Modify(tb, item) + local filter = item + if type(item) ~= "function" then + filter = function(t) return t == item end + end + local i = 1 + local d = #tb + while i <= d do + if filter(tb[i]) then + table.remove(tb, i) + d = d - 1 + else + i = i + 1 + end + end +end + +function M:InsertAfter_Modify(tb, item, after) + if after == nil then + table.insert(tb, item) + else + for index, value in ipairs(tb) do + if item == value then + table.insert(tb, index) + return + end + end + table.insert(tb, item) + end +end + +function M:Unpack(tb) + local index = #tb + local function rec(...) + if index >= 1 then + index = index - 1 + return rec(tb[index + 1], ...) + else + return ... + end + end + return rec() +end + +function M:UnpackIfTable(p) + if type(p) == "table" then + return self:Unpack(p) + else + return p + end +end + +function M:Also(tb, block) + block(tb) + return tb +end + +function M:Let(tb, block) + return block(tb) +end + + +-- function M:ClampGroup(tb, min, max) +-- local vmin = math.min(tb) +-- local vmax = math.max(tb) +-- return self:Map(tb, function(t) return RemapVal(t, vmin, vmax, min, max) end) +-- end -M.SeriouslyRetreatingStunSomeone = function(self, npcBot, abilityIndex, ability, targetType) - if not ability:IsFullyCastable() then - return BOT_ACTION_DESIRE_NONE, 0 - end - - local CastRange = ability:GetCastRange() - local Damage = ability:GetAbilityDamage() - local Radius = ability:GetAOERadius() - local CastPoint = ability:GetCastPoint() - - local allys = npcBot:GetNearbyHeroes( 1200, false, BOT_MODE_NONE ) - local enemys = npcBot:GetNearbyHeroes(CastRange+300,true,BOT_MODE_NONE) - local WeakestEnemy,HeroHealth=utility.GetWeakestUnit(enemys) - local creeps = npcBot:GetNearbyCreeps(CastRange+300,true) - local WeakestCreep,CreepHealth=utility.GetWeakestUnit(creeps) - - if ( npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH ) then - for _,npcEnemy in pairs( enemys ) - do - if ( npcBot:WasRecentlyDamagedByHero( npcEnemy, 2.0 ) ) - then - if ( CanCast[abilityNumber]( npcEnemy ) ) - then - return BOT_ACTION_DESIRE_LOW, npcEnemy:GetExtrapolatedLocation(CastPoint) - end - end - end - end +local function AddLinqFunctionsToMetatable(mt) + for k, v in pairs(M) do + mt[k] = function(...) + return v(M, ...) + end + end + for functionName, func in pairs(table) do + mt[functionName] = func + end end +AddLinqFunctionsToMetatable(magicTable) + +-- bot mode behaviour + local Trim = function(v, left, right) if right >= left then if v > right then @@ -444,7 +615,12 @@ end M.IsFarmingOrPushing = function(self, npcBot) local mode = npcBot:GetActiveMode() - return mode==BOT_MODE_FARM or mode==BOT_MODE_PUSH_TOWER_BOT or mode==BOT_MODE_PUSH_TOWER_MID or mode==BOT_MODE_PUSH_TOWER_TOP + return mode==BOT_MODE_FARM or mode==BOT_MODE_PUSH_TOWER_BOT or mode==BOT_MODE_PUSH_TOWER_MID or mode==BOT_MODE_PUSH_TOWER_TOP or mode == BOT_MODE_DEFEND_TOWER_BOT or mode==BOT_MODE_DEFEND_TOWER_MID or mode==BOT_MODE_DEFEND_TOWER_TOP +end + +M.IsLaning = function(self, npcBot) + local mode = npcBot:GetActiveMode() + return mode == BOT_MODE_LANING end M.IsAttackingEnemies = function(self, npcBot) @@ -515,9 +691,6 @@ M.PreventEnemyTargetAbilityUsageAtAbilityBlock = function(self, npcBot, oldConsi -- TODO: do we consider the base cooldown or the modified cooldown (arcane rune, octarine orb)? Will you crack a sphere's spell block with an ultimate ability when you're on arcane rune? local desire, target, targetTypeString = oldConsiderFunction() if desire == 0 or target == nil or target == 0 or self:IsVector(target) or targetTypeString == "Location" then - --if self:IsVector(target) then - -- print("npcBot "..npcBot:GetUnitName().." lands target ability "..ability:GetName().." at location "..self:ToStringVector(target)) - --end return desire, target, targetTypeString end local oldDesire = desire @@ -560,9 +733,6 @@ M.PreventEnemyTargetAbilityUsageAtAbilityBlock = function(self, npcBot, oldConsi desire = self:TrimDesire(desire) end - if desire ~= oldDesire then - print("desire modified from "..oldDesire.." to "..desire) - end return desire, target, targetTypeString end return newConsider @@ -590,8 +760,6 @@ M.AddCooldownToChargeAbility = function(self, oldConsider, ability, abilityInfoT end end - - M.AutoModifyConsiderFunction = function(self, npcBot, considers, abilitiesReal) for index, ability in pairs(abilitiesReal) do if not binlib.Test(ability:GetBehavior(), ABILITY_BEHAVIOR_PASSIVE) and considers[index] == nil then @@ -603,19 +771,559 @@ M.AutoModifyConsiderFunction = function(self, npcBot, considers, abilitiesReal) end end end + npcBot.abilityRecords = {} +end + +function M:InitAbility(npcBot) + local abilities = NewTable() + local abilityNames = NewTable() + local talents = NewTable() + for i = 0, 23 do + local ability = npcBot:GetAbilityInSlot(i) + if (ability ~= nil) then + if (ability:GetName() ~= "generic_hidden") then + if (ability:IsTalent() == true) then + table.insert(talents, ability:GetName()) + else + table.insert(abilityNames, ability:GetName()) + table.insert(abilities, ability) + end + end + end + end + npcBot.abilityInited = true + return abilityNames, abilities, talents +end + +-- ability information + +local keysBeforeAbilityInformation = M:Keys(M) + +M.UndisjointableProjectiles = { + "alchemist_berser_potion", + "alchemist_unstable_concoction_throw", + "arc_warden_spark_wraith", + "grimstroke_phantoms_embrace", + "earthshaker_echoslam", + "gyrocopter_homing_missile", + "beastmaster_hawk_dive", + "huskar_life_break", + "lich_chain_frost", + "medusa_cold_blooded", + "medusa_mystic_snake", + "mirana_starstorm", + "necrolyte_death_pulse", + "necrolyte_death_seeker", + "oracle_fortunes_end", + "queenofpain_scream_of_pain", + "skywrath_mage_arcane_bolt", + "snapfire_firesnap_cookie", + "spectre_spectral_dagger", + "tiny_toss", + "tusk_snowball", + "witch_doctor_paralyzing_cask", +} + +M.targetTrackingStunAbilities = { + "alchemist_berser_potion", + "alchemist_unstable_concoction_throw", + "chaos_knight_chaos_bolt", + "dragon_knight_dragon_tail", + "gyrocopter_homing_missile", + "morphling_adaptive_strike_str", + "mud_golem_hurl_boulder", + "skeleton_king_hellfire_blast", + "sven_storm_hammer", + "vengefulspirit_magic_missile", + "windrunner_shackleshot", +} + +M.targetNonTrackingStunAbilities = { + "bane_fiends_grip", + "beastmaster_primal_roar", + "dark_willow_cursed_crown", + "enigma_malefice", + "invoker_cold_snap", + "item_abyssal_blade", + "lich_sinister_gaze", + "luna_lucent_beam", + "necrolyte_reapers_scythe", + "ogre_magi_fireblast", + "ogre_magi_unrefined_fireblast", + "pudge_dismember", + "rubick_telekinesis", + "shadow_shaman_shackles", + "storm_spirit_electric_vortex", +} + +M.targetStunAbilities = M:Concat(M.targetTrackingStunAbilities, M.targetNonTrackingStunAbilities) + +M.locationStunAbilities = { + "axe_berserkers_call", + "centaur_hoof_stomp", + "dark_seer_vacuum", + "dark_willow_cursed_crown", + "dawnbreaker_fire_wreath", + "dawnbreaker_solar_guardian", + "earthshaker_fissure", + "earthshaker_enchant_totem", + "earthshaker_echoslam", + "enigma_black_hole", + "faceless_void_chronosphere", + "jakiro_ice_path", + "keeper_of_the_light_will_o_wisp", + "kunkka_ghostship", + "kunkka_torrent", + "kunkka_torrent_storm", + "lina_light_strike_array", + "magnataur_skewer", + "magnataur_horn_toss", + "magnataur_reverse_polarity", + "monkey_king_boundless_strike", + "phoenix_supernova", + "puck_dream_coil", + "sand_king_burrowstrike", + "slardar_slithereen_crush", + "tidehunter_ravage", +} + +M.targetTrackingDisableAbilities = { + "gleipnir_eternal_chains", + "naga_siren_ensnare", + "riki_sleeping_dart", + "viper_viper_strike", +} + +M.targetNonTrackingDisableAbilities = { + "bloodseeker_rupture", + "doom_bringer_doom", + "ember_spirit_searing_chains", + "grimstroke_ink_creature", + "grimstroke_soul_chain", + "item_sheepstick", + "lion_vex", + "shadow_demon_purge", + "shadow_shaman_voodoo", +} + +M.targetDisableAbilities = M:Concat(M.targetNonTrackingStunAbilities, M.targetTrackingDisableAbilities) + +M.locationDisableAbilities = { + "dark_willow_bramble_maze", + "death_prophet_silence", + "disruptor_kinetic_field", + "disruptor_static_storm", + "drow_ranger_wave_of_silence", + "elder_titan_echo_stomp", + "invoker_deafening_wave", + "treant_overgrowth", +} + +M.targetTrackingHeavyDamageAbilities = { + "item_ethereal_blade", + "lich_chain_frost", + "lion_finger_of_death", + "morphling_adaptive_strike_agi", + "sniper_assassinate", +} + +M.targetNonTrackingHeavyDamageAbilities = { + "antimage_mana_void", + "item_dagon", + "lina_laguna_blade", + "pugna_life_drain", + "tinker_laser", + "zuus_lightning_bolt", +} + +M.targetHeavyDamageAbilities = M:Concat(M.targetTrackingHeavyDamageAbilities, M.targetNonTrackingHeavyDamageAbilities) + +M.locationHeavyDamageAbilities = { + "ancient_apparition_ice_blast", + "antimage_mana_void", + "disruptor_static_storm", + "invoker_chaos_meteor", + "invoker_sun_strike", + "jakiro_macropyre", + "kunkka_ghostship", + "nevermore_requiem_of_souls", + "obsidian_destroyer_sanitys_eclipse", + "phoenix_sun_ray", + "puck_dream_coil", + "pugna_nether_blast", + "queenofpain_sonic_wave", + "sand_king_epicenter", + "skywrath_mage_mystic_flare", + "venomancer_poison_nova", +} + +M.heavyDamageAbilities = M:Concat(M.targetTrackingHeavyDamageAbilities, M.locationHeavyDamageAbilities) + +M.dodgeWorthAbilities = M:Concat(M.targetStunAbilities, M.locationStunAbilities, M.heavyDamageAbilities) + +M.invisibleModifiers = { + "modifier_bounty_hunter_wind_walk", + "modifier_clinkz_wind_walk", + "modifier_dark_willow_shadow_realm_buff", + "modifier_item_glimmer_cape_glimmer", + "modifier_invoker_ghost_walk_self", + "modifier_nyx_assassin_vendetta", + "modifier_item_phase_boots_active", + "modifier_item_shadow_amulet_fade", + "modifier_item_invisibility_edge_windwalk", + "modifier_shadow_fiend_requiem_thinker", + "modifier_item_silver_edge_windwalk", + "modifier_windrunner_wind_walk", + "modifier_storm_wind_walk", + "modifier_templar_assassin_meld", + "modifier_visage_silent_as_the_grave", + "modifier_weaver_shukuchi", +} + +M.phaseModifiers = { + "modifier_bounty_hunter_wind_walk", + "modifier_clinkz_wind_walk", + "modifier_dark_willow_shadow_realm_buff", + "modifier_faceless_void_chronosphere_selfbuff", + "modifier_item_glimmer_cape_glimmer", + "modifier_invoker_ghost_walk_self", + "modifier_nyx_assassin_vendetta", + "modifier_item_phase_boots_active", + "modifier_item_shadow_amulet_fade", + "modifier_item_invisibility_edge_windwalk", + "modifier_shadow_fiend_requiem_thinker", + "modifier_item_silver_edge_windwalk", + "modifier_slardar_sprint", + "modifier_storm_wind_walk", + "modifier_templar_assassin_meld", + "modifier_weaver_shukuchi", +} + +M.phaseUnits = { + "npc_dota_brewmaster_fire_1", + "npc_dota_brewmaster_fire_2", + "npc_dota_brewmaster_fire_3", + "npc_dota_broodmother_web", + "npc_dota_courier", + "npc_dota_phoenix_sun", + "npc_dota_juggernaut_healing_ward", + "npc_dota_techies_land_mine", + "npc_dota_techies_stasis_trap", + "npc_dota_techies_remote_mine", + "npc_dota_weaver_swarm", +} + +M.unobstructedMovementModifiers = { + "modifier_batrider_firefly", + "modifier_broodmother_spin_web", + "modifier_centaur_stampede", + "modifier_dragon_knight_dragon_form", + "modifier_item_giants_ring_giants_foot", + "modifier_lich_sinister_gaze", + "modifier_legion_commander_duel", + "modifier_nyx_assassin_vendetta", + "modifier_spectre_spectral_dagger_path_phased", + "modifier_item_spider_legs_active", + "modifier_visage_silent_as_the_grave", +} + +M.flyingModifiers = { + "modifier_rattletrap_jetpack", + "modifier_night_stalker_darkness", + "modifier_winter_wyvern_arctic_burn_flight", +} + +M.flyingUnits = { + "npc_dota_visage_familiar1", + "npc_dota_visage_familiar2", + "npc_dota_visage_familiar3", + "npc_dota_flying_courier", + "npc_dota_beastmaster_hawk", +} + +M.positiveForceMovementModifiers = { + "modifier_faceless_void_time_walk", + "modifier_huskar_life_break_charge", + "modifier_magnataur_skewer_movement", + "modifier_monkey_king_bounce", + "modifier_monkey_king_bounce_leap", + "modifier_monkey_king_tree_dance_activity", + "modifier_monkey_king_bounce_perch", + "modifier_monkey_king_right_click_jump_activity", + "modifier_pangolier_swashbuckle", + "modiifer_pangolier_shield_crash_jump", + "modifier_pangolier_rollup", + "modifier_snapfire_firesnap_cookie", + "modifier_snapfire_gobble_up", + "modifier_sand_king_burrowstrike", + "modifier_techies_suicide_leap", +} + +M.timeSensitivePositiveModifiers = { + "modifier_item_black_king_bar", + "modifier_faceless_void_chronosphere_selfbuff", + "modifier_medusa_stone_gaze", + "modifier_monkey_king_fur_army_soldier_in_position", +} +-- sorted by importance, used by dispell abilities + +M.basicDispellablePositiveModifiers = { + "modifier_omniknight_guardian_angle", + "modifier_ember_spirit_flame_guard", + "modifier_legion_commander_press_the_attack", + "modifier_windrunner_windrun", + "modifier_lich_frost_shield", + "modifier_oracle_purifying_flames", + "modifier_ogre_magi_bloodlust", + "modifier_treant_living_armor", + "modifier_mirana_leap_buff", + "modifier_necrolyte_death_seeker", + "modifier_necrolyte_sadist_active", + "modifier_pugna_decrepify", + "modifier_item_ethereal_blade_ethereal", + "modifier_ghost_state", + "modifier_abaddon_frostmourne_buff", + "modifier_item_mjollnir_static", + "modifier_visage_silent_as_the_grave", + "modifier_spirit_breaker_bulldoze", + "modifier_item_spider_legs_active", + "modifier_item_bullwhip_buff", +} + +M.basicDispellWorthPositiveModifiers = { + "modifier_omniknight_guardian_angle", + "modifier_ember_spirit_flame_guard", + "modifier_legion_commander_press_the_attack", + "modifier_windrunner_windrun", + "modifier_lich_frost_shield", + "modifier_oracle_purifying_flames", + "modifier_ogre_magi_bloodlust", + "modifier_treant_living_armor", + "modifier_mirana_leap_buff", + "modifier_necrolyte_death_seeker", + "modifier_necrolyte_sadist_active", + "modifier_pugna_decrepify", + "modifier_item_ethereal_blade_ethereal", + "modifier_ghost_state", +} + +M.basicDispellWorthNegativeModifiers = { + "modifier_abaddon_frostmourne_debuff_bonus", +} + +M.basicDispellableNegativeModifiers = { + "modifier_abaddon_frostmourne_debuff", + "modifier_abaddon_frostmourne_debuff_bonus", + +} + +M.unbreakableChannelAbilities = { + "puck_phase_shift", + "pangolier_gyroshell", + "lone_druid_true_form", + "phoenix_supernova", + "lycan_shapeshift", +} + +M.nonIllusionModifiers = {} + +M.valubleNeutrals = { + "npc_dota_neutral_alpha_wolf", + "npc_dota_neutral_centaur_khan", + "npc_dota_neutral_polar_furbolg_ursa_warrior", + "npc_dota_neutral_dark_troll_warlord", + "npc_dota_neutral_mud_golem", + "npc_dota_neutral_satyr_hellcaller", +} + +M.valubleAncientNeutrals = { + "npc_dota_neutral_black_dragon", + "npc_dota_neutral_rock_golem", + "npc_dota_neutral_big_thunder_lizard", +} + +M.hypnosisModifiers = { + "modifier_lich_sinister_gaze", + "modifier_void_spirit_aether_remnant_pull", + "modifier_keeper_of_the_light_will_o_wisp", +} + +M.fearModifiers = { + "modifier_dark_willow_debuff_fear", + "modifier_lone_druid_savage_roar", + "modifier_shadow_fiend_requiem_fear", + "modifier_terrorblade_fear", +} + +M.hexModifiers = { + "modifier_lion_voodoo", + "modifier_shadow_shaman_voodoo", + "modifier_sheepstick_debuff", + "modifier_item_princes_knife_hex", + "modifier_hexxed", -- dazzle_poison_touch lv 25 +} + +M.silenceModifiers = { + "modifier_abaddon_frostmourne_debuff_bonus", + "modifier_silence", + "modifier_bloodthorn_debuff", + "modifier_disruptor_static_storm", + "modifier_doom_bringer_doom", + "modifier_drow_ranger_wave_of_silence", + "modifier_earth_spirit_geomagnetic_grip_debuff", + "modifier_enigma_black_hole_pull", + "modifier_grimstroke_ink_creature_debuff", + "modifier_legion_commander_duel", + "modifier_item_mask_of_madness_berserk", + "modifier_night_stalker_crippling_fear", + "modifier_orchid_malevolence_debuff", + "modifier_riki_smoke_screen", + "modifier_silencer_global_silence", + "modifier_silencer_last_word", + "modifier_skywrath_mage_ancient_seal", +} + +M.timedSilenceModifiers = { + "modifier_abaddon_frostmourne_debuff_bonus", + "modifier_silence", + "modifier_bloodthorn_debuff", + "modifier_doom_bringer_doom", + "modifier_drow_ranger_wave_of_silence", + "modifier_earth_spirit_geomagnetic_grip_debuff", + "modifier_grimstroke_ink_creature_debuff", + "modifier_legion_commander_duel", + "modifier_item_mask_of_madness_berserk", + "modifier_orchid_malevolence_debuff", + "modifier_silencer_global_silence", + "modifier_silencer_last_word", + "modifier_skywrath_mage_ancient_seal", +} + +M.magicImmuneModifiers = { + "modifier_item_black_king_bar", + "modifier_life_stealer_rage", + "modifier_juggernaut_blade_fury", + "modifier_minotaur_horn_immune", + "modifier_elder_titan_echo_stomp_magic_immune", + "modifier_huskar_life_break_charge", + "modifier_legion_commander_press_the_attack_immunity", + "modifier_lion_mana_drain_immunity", +} + +M.muteModifiers = { + "modifier_tusk_snowball", + "modifier_doom_bringer_doom", + "modifier_disruptor_static_storm_mute", +} + +M.breakModifiers = { + -- "modifier_doom_bringer_doom",--only breaks with scepter + "modifier_hoodwink_sharpshooter", + "modifier_phantom_assassin_fan_of_knives", + -- "modifier_shadow_demon_purge_slow",--only break with scepter + "modifier_silver_edge_debuff", + -- "modifier_spirit_breaker_greaterbash_break",--only break with shard + "modifier_viper_nethertoxin", +} +-- TODO: how to record he caster of these abilities + +M.noTrueSightRootAbilityAssociation = { + dark_willow_branble_maze = "modifier_dark_willow_bramble_maze", + item_diffusal_blade = "modifier_rooted", -- most people don't know diffusal blade apply root on non-hero units +} + +M.conditionalTrueSightRootAbilityAssociation = { + dark_troll_warlord_ensnare = "modifier_dark_troll_warlord_ensnare", + ember_spirit_searing_chains = "modifier_ember_spirit_searing_chains", + oracle_fortunes_end = "modifier_oracle_fortunes_end_purge", + item_rod_of_atos = "modifier_rod_of_atos_debuff", +} + +M.permanentTrueSightRootAbilityAssociation = { + broodmother_silken_bola = "modifier_broodmother_silken_bola", + crystal_maiden_frostbite = "modfifier_crystal_maiden_frostbite", + meepo_earthbind = "modifier_meepo_earthbind", + naga_siren_ensnare = "modifier_naga_siren_ensnare", + spirit_bear_entangling_claws = "modifier_lone_druid_spirit_bear_entangle_effect", + techies_stasis_trap = "modifier_techies_stasis_trap_stunned", + treant_overgrowth = "modifier_treant_overgrowth", + troll_warlord_berserkers_rage = "modifier_troll_warlord_berserkers_rage_ensnare", + abyssal_underlord_pit_of_malice = "modifier_abyssal_underlord_pit_of_malice_ensare", +} + +M.rootAbilityAssociation = M:Concat(M.noTrueSightRootAbilityAssociation, M.conditionalTrueSightRootAbilityAssociation, M.permanentTrueSightRootAbilityAssociation) + +local keysAfterAbilityInformation = M:Keys(M) +local abilityInformationKeys = keysAfterAbilityInformation:RemoveAll(keysBeforeAbilityInformation) +abilityInformationKeys:ForEach(function(t) setmetatable(M[t], magicTable) end) +abilityInformationKeys = abilityInformationKeys:Filter(function(t) return t:match("AbilityAssociation") end) + +local function ExtendAssociation(association) + return association:MapDic(function(key, value) return key end), association:Map(function(key, value) return value end):Distinct() end +abilityInformationKeys:ForEach(function(t) + local a, b = ExtendAssociation(M[t]) + local k = t:sub(1, #t-#"AbilityAssociation") + M[k.."Abilities"] = a + M[k.."Modifiers"] = b +end) + -- unit function +function M:IsRoshan(npcTarget) + return npcTarget ~= nil and npcTarget:IsAlive() and string.find(npcTarget:GetUnitName(), "roshan") +end + +function M:IsHero(t) + return t:IsHero() +end + +function M:IsTempestDouble(npc) + return npc:HasModifier("modifier_arc_warden_tempest_double") +end + +function M:IsLoneDruidBear(npc) + return string.match(npc:GetUnitName(), "npc_dota_lone_druid_bear") +end + +function M:IsVisageFamiliar(npc) + return string.match(npc:GetUnitName(), "npc_dota_visage_familiar") +end + +function M:IsBrewmasterPrimalSplit(npc) + local unitName = npc:GetUnitName() + return string.match(unitName, "npc_dota_brewmaster_") +end + +M.GetIncomingDodgeWorthProjectiles = function(self, npc) + local health = npc:GetHealth() + local projectiles = npc:GetIncomingTrackingProjectiles() + projectiles = self:Filter(projectiles, function(t) + if t.is_attack or npc:GetTeam() == t.caster:GetTeam() then + return false + end + local ability = t.ability + if ability then + local abilityName = ability:GetName() + if self:Contains(self.UndisjointableProjectiles, abilityName) then + return false + end + if self:Contains(self.targetTrackingStunAbilities, abilityName) or self:Contains(self.targetTrackingDisableAbilities, abilityName) or self:Contains(self.targetTrackingHeavyDamageAbilities, abilityName) or npc:GetHealth() <= npc:GetActualIncomingDamage(ability:GetAbilityDamage(), ability:GetDamageType()) then + return true + end + return false + end + return true + end) + return projectiles +end + M.GetTargetHealAmplifyPercent = function(self, npc) local modifiers = npc:FindAllModifiers() local amplify = 1 - for i, modifier in pairs(modifiers) do - local a = (modifier:GetModifierHealAmplify_PercentageSource()) - if a ~= 0 then - print("modifier: "..modifier:GetName()..", heal amplify source:"..a..", target:"..modifier:GetModifierHealAmplify_PercentageTarget()) - end - local modifierName = modifier:GetName() + for i = 1, npc:NumModifiers() do + local modifierName = npc:GetModifierName(i) if modifierName == "modifier_ice_blast" then return 0 end @@ -646,13 +1354,23 @@ M.IsChannelingAbility = function(self, npc) return npc:IsChanneling() and not self:IsChannelingItem(npc) end -local GetOtherTeam = function(team) - if team == TEAM_RADIANT then - return TEAM_DIRE +function M:IsChannelingBreakWorthAbility(npc) + if not npc:IsChanneling() then + return false + end + local ability = npc:GetCurrentActiveAbility() + if ability == nil then + if npc:HasModifier("modifier_teleporting") then + return true + end + local item = self:GetAvailableItem(npc, "item_fallen_sky") + return item ~= nil end - if team == TEAM_DIRE then - return TEAM_RADIANT + local name = ability:GetName() + if self:Contains(self.unbreakableChannelAbilities, name) then + return false end + return true end M.RadiantPlayerId = GetTeamPlayers(TEAM_RADIANT) @@ -666,24 +1384,110 @@ M.GetTeamPlayers = function(self, team) end end +M.GetEnemyTeamMemberNames = function(self, npcBot) + local enemies = self:GetEnemyHeroUnique(npcBot, GetUnitList(UNIT_LIST_ENEMY_HEROES)) + return self:Map(enemies, function(t) return t:GetUnitName() end) +end + +M.enemyVisibleIllusionModifiers = { + "modifier_illusion", + -- "modifier_phantom_lancer_doppelwalk_illusion", + -- "modifier_phantom_lancer_juxtapose_illusion", + "modifier_terrorblade_conjureimage", + "modifier_grimstroke_scepter_buff", + "modifier_arc_warden_tempest_double", + "modifier_skeleton_king_reincarnation_active", + "modifier_vengefulspirit_hybrid_special", +} + M.MustBeIllusion = function(self, npcBot, target) if npcBot:GetTeam() == target:GetTeam() then - return target:IsIllusion() and not target:HasModifier("modifier_skeleton_king_reincarnation_active") + return target:IsIllusion() or self:HasAnyModifier(target, self.enemyVisibleIllusionModifiers) end - if self:Contains(self:GetTeamPlayers(npcBot:GetTeam()), target:GetPlayerID()) then + if self:Contains(self:GetTeamPlayers(npcBot:GetTeam()), target:GetPlayerID()) or target.markedAsIllusion then + return true + end + if target.markedAsRealHero then + return false + end + if not IsHeroAlive(target:GetPlayerID()) then return true end return false end M.MayNotBeIllusion = function(self, npcBot, target) return not self:MustBeIllusion(npcBot, target) end -M.GetNearbyNonIllusionHeroes = function(self, npcBot, range, getEnemy, botModeMask) - botModeMask = botModeMask or BOT_MODE_NONE - local heroes = npcBot:GetNearbyHeroes(range, getEnemy, botModeMask) - return self:Filter(heroes, function(t) return self:MayNotBeIllusion(npcBot, t) end) +function M:IsOnSameTeam(a, b) + return a:GetTeam() == b:GetTeam() end -function M:GetNearbyAttackableCreeps(npcBot, range, getEnemy) +function M:IsNonIllusionHero(npcBot, target) + return self:MayNotBeIllusion(npcBot, target) and self:IsHero(target) +end + +function M:HasNonIllusionModifier(npc) + return self:HasAnyModifier(npc, self.nonIllusionModifiers) +end + +function M:CanIllusionUseAbility(npc) + local name = npc:GetUnitName() + local ability = npc:GetCurrentActiveAbility() + if ability == nil then + return false + end + if name == "npc_dota_hero_bane" and self:HasScepter(npc) and ability:GetName() == "bane_fiends_grip" then + return true + end +end + +M.DetectIllusion = function(self, npcBot) + local nearbyEnemies = self:GetNearbyNonIllusionHeroes(npcBot, 1599) + nearbyEnemies = self:Filter(nearbyEnemies, function(t) return string.match(t:GetUnitName(), "npc_dota_hero") end) + local nearbyEnemyGroups = self:GroupBy(nearbyEnemies, function(t) return t:GetUnitName() end) + nearbyEnemyGroups = self:Filter(nearbyEnemyGroups, function(t) return #t > 1 end) + self:ForEach(nearbyEnemyGroups, function(nearbyEnemyGroup) + local castingEnemies = self:Filter(nearbyEnemyGroup, function(t) + return (t:IsUsingAbility() or t:IsChanneling() or self:HasNonIllusionModifier(t) or t.markedAsRealHero) and not t.markedAsIllusion + end) + local castingEnemy = castingEnemies[1] + if castingEnemy and not self:CanIllusionUseAbility(castingEnemy) then + castingEnemy.markedAsRealHero = true + castingEnemies = self:Remove(nearbyEnemyGroup, castingEnemy) + self:ForEach(castingEnemies, function(t) + t.markedAsIllusion = true + end) + end + end) +end + +M.GetNearbyHeroes = function(self, npcBot, range, getEnemy, botModeMask) + range = range or 1200 + if getEnemy == nil then + getEnemy = true + end + botModeMask = botModeMask or BOT_MODE_NONE + local heroes = npcBot:GetNearbyHeroes(range, getEnemy, botModeMask) + return heroes +end + +M.GetNearbyNonIllusionHeroes = function(self, npcBot, range, getEnemy, botModeMask) + range = range or 1200 + if getEnemy == nil then + getEnemy = true + end + botModeMask = botModeMask or BOT_MODE_NONE + local heroes = npcBot:GetNearbyHeroes(range, getEnemy, botModeMask) + return self:Filter(heroes, function(t) return self:MayNotBeIllusion(npcBot, t) end) +end + +function M:AttackOnceDamage(npcBot, target) + return target:GetActualIncomingDamage(npcBot:GetAttackDamage() - npcBot:GetBaseDamageVariance()/2, DAMAGE_TYPE_PHYSICAL) +end + +function M:GetNearbyAttackableCreeps(npcBot, range, getEnemy) + if getEnemy == nil then + getEnemy = true + end local creeps = npcBot:GetNearbyCreeps(range, getEnemy) if getEnemy then creeps = self:Filter(creeps, function(t) return t:HasModifier("modifier_fountain_glyph") end) @@ -699,10 +1503,17 @@ M.GetNearbyAllUnits = function(self, npcBot, range) return self:Concat(h1, h2, h3, h4) end +function M:GetNearbyEnemyUnits(npc, range) + local h1 = npc:GetNearbyHeroes(range, true, BOT_MODE_NONE) + local h3 = npc:GetNearbyCreeps(range, true) + return self:Concat(h1, h3) +end + + M.GetEnemyHeroUnique = function(self, npcBot, enemies) local p = self:Filter(enemies, function(t) self:MayNotBeIllusion(npcBot, t) end) - local g = {} - local readNames = {} + local g = NewTable() + local readNames = NewTable() for _, enemy in pairs(p) do local name = enemy:GetUnitName() if not self:Contains(readNames, name) then @@ -725,9 +1536,10 @@ M.GetModifierRemainingDuration = function(self, npc, modifierName) if mod ~= -1 then return npc:GetModifierRemainingDuration(mod) end - return nil + return 0 end -M.ImprisonmentModifier = { + +M.imprisonmentModifier = { "modifier_item_cyclone", "modifier_item_wind_waker", "modifier_shadow_demon_disruption", @@ -737,15 +1549,73 @@ M.ImprisonmentModifier = { --"modifier_x_marks_the_target", } M.GetImprisonmentRemainingDuration = function(self, npc) - return self:First(self:Map(self.ImprisonmentModifier, function(t) return self:GetModifierRemainingDuration(npc, t) end), function(t) return t ~= nil end) + return self:First(self:Map(self.imprisonmentModifier, function(t) return self:GetModifierRemainingDuration(npc, t) end), function(t) return t ~= 0 end) or 0 +end + +function M:GetMagicImmuneRemainingDuration(npc) + local remainingTime = self:Map(self.magicImmuneModifiers, function(t) return { t, self:GetModifierRemainingDuration(npc, t)} end) + remainingTime = self:SortByMaxFirst(remainingTime, function(t) return t[2] end) + remainingTime = remainingTime[1] + return remainingTime and remainingTime[2] or 0 +end + +function M:GetSilenceRemainingDuration(npc) + local silenceModifierRemainings = self:Map(self.timedSilenceModifiers, function(t) + return self:GetModifierRemainingDuration(npc, t) + end) + if npc:HasModifier("modifier_disruptor_static_storm") then + table.insert(silenceModifierRemainings, 1, 6) + end + if npc:HasModifier("modifier_enigma_black_hole_pull") or npc:HasModifier("modifier_riki_smoke_screen") then + table.insert(silenceModifierRemainings, 1, 4) + end + silenceModifierRemainings = #silenceModifierRemainings ~= 0 and math.max(self:Unpack(silenceModifierRemainings)) or 0 + return silenceModifierRemainings +end + +function M:GetStunRemainingDuration(npc) + return self:IsStunned(npc) and 1 or 0 end M.GetEnemyHeroNumber = function(self, npcBot, enemies) return #self:GetEnemyHeroUnique(npcBot, enemies) end +function M:HasPhasedMovement(npc) + return self:HasAnyModifier(npc, self.phaseModifiers) or self:Contains(self.phaseUnits, npc:GetUnitName()) +end + +function M:HasUnobstructedMovement(npc) + if self:HasAnyModifier(npc, self.flyingModifiers) or self:Contains(self.flyingUnits, npc:GetUnitName()) then + if string.match(npc:GetUnitName(), "npc_dota_visage_familiar") then + return npc:HasModifier("modifier_rooted") + end + return true + end + local activeFlyingModifiers = self:Filter(self.unobstructedMovementModifiers, function(t) return npc:HasModifier(t) end) + if #activeFlyingModifiers ~= 0 then + local dragonKnightDragonForm = self:IndexOf(activeFlyingModifiers, "modifier_dragon_knight_dragon_form") + if dragonKnightDragonForm ~= -1 then + local ability = npc:GetAbilityByName("dragon_knight_elder_dragon_form") + if ability == nil or not (ability:GetLevel() == 4) then + table.remove(activeFlyingModifiers, dragonKnightDragonForm) + end + end + local stampede = self:IndexOf(activeFlyingModifiers, "modifier_centaur_stampede") + if stampede ~= -1 then + local ability = npc:GetAbilityByName("centaur_stampede") + if ability == nil or not self:hasScepter(npc) then + table.remove(activeFlyingModifiers, stampede) + end + end + end + return #activeFlyingModifiers ~= 0 +end + +-- item function + M.GetAvailableItem = function(self, npc, itemName) - for i = 0,6 do + for i = 0, 5 do local item = npc:GetItemInSlot(i) if item ~= nil and item:GetName() == itemName then return item @@ -753,6 +1623,36 @@ M.GetAvailableItem = function(self, npc, itemName) end end +local radianceAncientLocation = Vector(-7200,-6666) +local direAncientLocation = Vector(7137,6548) + +M.GetAncientLocation = function(self, npc) + if npc:GetTeam() == TEAM_RADIANT then + return radianceAncientLocation + else + return direAncientLocation + end +end + +M.GetDistanceFromAncient = function(self, npc) + local fountain = self:GetAncientLocation(npc) + return GetUnitToLocationDistance(npc, fountain) +end + +M.TryUseTp = function(self, npc) + local item = npc:GetItemInSlot(15) + if item ~= nil and item:IsFullyCastable() and self:CanMove(npc) then + local distanceFromFountain + if npc:GetTeam() == TEAM_RADIANT then + distanceFromFountain = radianceAncientLocation + Vector(400, 400) + else + distanceFromFountain = direAncientLocation + Vector(-400, -400) + end + npc:ActionImmediate_UseAbilityOnLocation(item, distanceFromFountain) + return true + end +end + M.GetAvailableBlink = function(self, npc) local blinks = { "item_blink", @@ -761,10 +1661,30 @@ M.GetAvailableBlink = function(self, npc) "item_arcane_blink", } return self:Aggregate(nil, blinks, function(a, blinkName) - return a or self:GetAvailableItem(blinkName) + return a or self:GetAvailableItem(npc, blinkName) + end) +end + +function M:GetAvailableTravelBoots(npc) + local travelBoots = { + "item_travel_boots", + "item_travel_boots_2", + } + return self:Aggregate(nil, travelBoots, function(seed, t) + return seed or self:GetAvailableItem(npc, t) end) end +M.GetEmptyInventorySlots = function(self, npc) + local g = 0 + for i = 0, 5 do + if npc:GetItemInSlot(i) == nil then + g = g+1 + end + end + return g +end + M.GetEmptyItemSlots = function(self, npc) local g = 0 for i = 0, 8 do @@ -777,7 +1697,7 @@ end M.GetEmptyBackpackSlots = function(self, npc) local g = 0 - for i = 6, 8 do + for i = 7, 9 do if npc:GetItemInSlot(i) == nil then g = g+1 end @@ -796,7 +1716,7 @@ M.SwapItemToBackpack = function(self, npc, itemIndex) end M.GetCarriedItems = function(self, npc) - local g = {} + local g = NewTable() for i = 0, 8 do local item = npc:GetItemInSlot(i) if item ~= nil then @@ -808,8 +1728,32 @@ M.GetCarriedItems = function(self, npc) end M.GetInventoryItems = function(self, npc) - local g = {} - for i = 0, 6 do + local g = NewTable() + for i = 0, 5 do + local item = npc:GetItemInSlot(i) + if item ~= nil then + item.slotIndex = i + table.insert(g, item) + end + end + return g +end + +M.GetInventoryItemNames = function(self, npc) + local g = NewTable() + for i = 0, 5 do + local item = npc:GetItemInSlot(i) + if item ~= nil then + item.slotIndex = i + table.insert(g, item:GetName()) + end + end + return g +end + +M.GetStashItems = function(self, npc) + local g = NewTable() + for i = 9, 14 do local item = npc:GetItemInSlot(i) if item ~= nil then item.slotIndex = i @@ -820,27 +1764,45 @@ M.GetInventoryItems = function(self, npc) end function M:GetCourierItems(courier) - if courier ~= nil then - for i = 0, 8 do - local item = courier:GetItemInSlot(i) - if item then - table.insert(g, item) - end + local g = NewTable() + for i = 0, 8 do + local item = courier:GetItemInSlot(i) + if item then + table.insert(g, item) end end return g end -M.GetAllBoughtItems = function(self) - local g = {} - local npcBot = GetBot() +function M:GetMyCourier(npcBot) + if npcBot.courierIDNew == nil then + self:FindCourier(npcBot) + end + return GetCourier(npcBot.courierIDNew) +end + +function M:FindCourier(npcBot) + for i = 0,4 do + local courier = GetCourier(i) + if courier ~= nil then + if courier:GetPlayerID() == npcBot:GetPlayerID() then + npcBot.courierIDNew = i + end + end + end +end + +M.GetAllBoughtItems = function(self, npcBot) + local g = NewTable() for i = 0, 15 do local item = npcBot:GetItemInSlot(i) if item then table.insert(g, item) end end - g = self:Concat(g, self:GetCourierItems(GetCourier(0))) + if DotaTime() >= -70 then + g = self:Concat(g, self:GetCourierItems(self:GetMyCourier(npcBot))) + end return g end @@ -848,26 +1810,23 @@ M.IsBoots = function(self, item) if type(item) ~= "string" then item = item:GetName() end - return string.match(item, "boots") or item == "item_guardian_greaves" + return string.match(item, "boots") or item == "item_guardian_greaves" or #item >= 17 and string.sub(item, 17) == "item_power_treads" end M.SwapCheapestItemToBackpack = function(self, npc) - local cheapestItem = self:First(self:Sort(self:Filter(self:GetInventoryItems(npc), function(t) return not self:IsBoots(t) end), function(a, b) return GetItemCost(a:GetName()) - GetItemCost(b:GetName()) end)) + local cheapestItem = self:First(self:Sort(self:Filter(self:GetInventoryItems(npc), function(t) + return not self:IsBoots(t) and not string.match(t:GetName(), "item_ward") + end), function(a, b) return GetItemCost(a:GetName()) - GetItemCost(b:GetName()) end)) if cheapestItem == nil then - print(npc:GetUnitName()..": only have shoes in inventory") return false end return self:SwapItemToBackpack(npc, cheapestItem.slotIndex) end M.SuitableForSilence = function(self, npc, target) - return self:MayNotBeIllusion(npc, target) and not target:IsMagicImmune() and not target:IsInvulnerable() + return self:MayNotBeIllusion(npc, target) and not target:IsMagicImmune() and not self:IsInvulnerable(target) end -local heroNameTable = {} -setmetatable(heroNameTable, { - __index = function(tb, s) return "npc_dota_hero_"..s end -}) M.GetHeroFullName = function(self, s) return "npc_dota_hero_"..s end @@ -881,6 +1840,10 @@ M.IsMeleeHero = function(self, npc) return range <= 210 or name == self:GetHeroFullName("tiny") or name == self:GetHeroFullName("doom_bringer") or name == self:GetHeroFullName("pudge") end +function M:HasAnyModifier(npc, modifierGroup) + return self:First(modifierGroup, function(t) return npc:HasModifier(t) end) +end + M.AttackPassiveAbilities = { "doom_bringer_infernal_blade", "drow_ranger_frost_arrows", @@ -890,7 +1853,8 @@ M.AttackPassiveAbilities = { } M.OtherIgnoreAbilityBlockAbilities = { "batrider_flaming_lasso", - "gyrocopter_homing_missle", + "gyrocopter_homing_missile", + "axe_culling_blade", } M.IgnoreAbilityBlockAbilities = { "dark_seer_ion_shell", @@ -913,68 +1877,201 @@ M.AbilityRetargetModifiers = { "modifier_antimage_counterspell", "modifier_item_lotus_orb_active", "modifier_nyx_assassin_spiked_carapace", - "modifier_item_blade_mail", + -- "modifier_item_blade_mail", } M.HasAbilityRetargetModifier = function(self, npc) - return self:Any(self.AbilityRetargetModifiers, function(t) return npc:HasModifier(t) end) + return self:HasAnyModifier(npc, self.AbilityRetargetModifiers) end M.CanMove = function(self, npc) - return not npc:IsStunned() and not npc:IsRooted() + return not npc:IsStunned() and not npc:IsRooted() and not self:IsNightmared(npc) and not self:IsTaunted(npc) +end + +function M:CannotMove(npc) + return -- npc:IsStunned() or self:IsNightmared(npc) or --actually still able to cast abilities or move while stunned or nightmared, but provides no dfference + npc:IsRooted() or self:IsTaunted(npc)or self:IsHypnosed(npc) or self:IsFeared(npc) end -M.IsSeverlyDisabled = function(self, npc) - return npc:IsStunned() or npc:IsHexed() or npc:IsRooted() or self:GetMovementSpeedPercent(npc) <= 0.4 or npc:IsNightmared() +function M:CannotTeleport(npc) + return npc:IsRooted() or self:IsTaunted(npc)or self:IsHypnosed(npc) or self:IsFeared(npc) +end + +function M:IsNightmared(npc) + return npc:HasModifier("modifier_bane_nightmare") or npc:HasModifier("modifier_riki_poison_dart_debuff") +end + +function M:IsTaunted(npc) + return npc:HasModifier("modifier_axe_berserkers_call") or npc:HasModifier("modifier_legion_commander_duel") +end + +function M:IsDuelCaster(npc) + local function IsTaunting(_npc) + local ability = _npc:GetAbilityByName("legion_commander_duel") + return ability and ability:GetCooldownTimeRemaining() + self:GetModifierRemainingDuration(_npc, "modifier_legion_commander_duel") + 1 >= ability:GetCooldown() + end + local npcBot = GetBot() + if npcBot:GetTeam() == npc:GetTeam() then + return IsTaunting(npc) + else + local players = self:Map(self:Range(0, 4), GetTeamMember) + local tauntingPlayer = self:First(players, function(t) + return IsTaunting(t) and t:GetAttackTarget() == npc + end) + return not IsTaunting(tauntingPlayer) + end +end + +function M:IsMuted(npc) + return npc:IsHexed() or self:HasAnyModifier(npc, self.muteModifiers) +end + +function M:IsHypnosed(npc) + return self:HasAnyModifier(npc, self.hypnosisModifiers) +end + +function M:IsFeared(npc) + return self:HasAnyModifier(npc, self.fearModifiers) +end + +M.IsSeverelyDisabled = function(self, npc) + return npc:IsStunned() or npc:IsHexed() or npc:IsRooted() or self:IsFeared(npc) or self:IsHypnosed(npc) + or self:IsNightmared(npc) + or npc:HasModifier("modifier_legion_commander_duel") and not self:IsDuelCaster(npc) or npc:HasModifier("modifier_axe_berserkers_call") + or npc:HasModifier("modifier_shadow_demon_purge_slow") + or npc:HasModifier("modifier_doom_bringer_doom") +end + +M.IsSeverelyDisabledOrSlowed = function(self, npc) + return self:IsSeverelyDisabled(npc) or self:GetMovementSpeedPercent(npc) <= 0.35 +end + +M.HasSeverelyDisableProjectiles = function(self, npc) + local projectiles = self:GetIncomingDodgeableProjectiles(npc) + return self:Any(projectiles, function(t) + return self:Contains(self.targetTrackingStunAbilities, t.ability:GetName()) + end) +end + +M.IsOrGoingToBeSeverelyDisabled = function(self, npc) + return self:IsSeverelyDisabled(npc) or self:HasSeverelyDisableProjectiles(npc) end M.EtherealModifiers = { "modifier_ghost_state", - "modifier_item_ethereal_blade_slow", + "modifier_item_ethereal_blade_ethereal", "modifier_necrolyte_death_seeker", - "modifier_necrylte_sadist_active", + "modifier_necrolyte_sadist_active", "modifier_pugna_decrepify", } M.IsEthereal = function(self, npc) - return self:Any(self.EtherealModifiers, function(t) return npc:HasModifier(t) end) + return self:HasAnyModifier(npc, self.EtherealModifiers) +end + +function M:NotBlasted(self, npc) + return not npc:HasModifier("modifier_ice_blast") +end + +M.CannotBeTargetted = function(self, npc) + return self:HasAnyModifier(npc, self.CannotBeTargettedModifiers) end +M.CanBeTargettedFunction = function(npc) return not M:CanBeTargetted(npc) end + M.CannotBeAttacked = function(self, npc) - return self:IsEthereal() or self:IsInvulnerable() + return self:IsEthereal(npc) or self:IsInvulnerable(npc) or self:CannotBeTargetted(npc) +end + +M.CanBeAttackedFunction = function(npc) return not M:CanBeAttacked(npc) end + +M.IsInvulnerable = function(self, npc) + return npc:IsInvulnerable() or self:Any(self.IgnoreDamageModifiers, function(t) return npc:HasModifier(t) end) +end + +M.MayNotBeSeen = function(self, npc) + if not npc:IsInvisible() or npc:HasModifier("modifier_item_dust") or npc:HasModifier("modifier_bounty_hunter_track") or npc:HasModifier("modifier_slardar_amplify_damage") or npc:HasModifier("modifier_truesight") then + return false + end + if self:HasAnyModifier(npc, self.permanentTrueSightRootModifiers) then + return false + end + local enemies = self:GetNearbyHeroes(npc) + return self:All(enemies, function(t) + if t:HasItem("item_gem") then + return false + end + if t:GetAttackTarget() == npc then + return false + end + if t:IsUsingAbility() then + local ability = t:GetCurrentActiveAbility() + if binlib.Test(ability:GetBehavior(), ABILITY_BEHAVIOR_UNIT_TARGET) and t:IsFacingLocation(npc:GetLocation(), 10) then + return false + end + end + return true + end) and not self:Any(npc:GetNearbyCreeps(1000, true), function(t) + return t:GetUnitName() == "npc_dota_necronomicon_warrior_3" + end) end M.ShouldNotBeAttacked = function(self, npc) return self:CannotBeAttacked(npc) or self:Any(self.IgnoreDamageModifiers, function(t) return npc:HasModifier(t) end) or self:Any(self.IgnorePhysicalDamageModifiers, function(t) return npc:HasModifier(t) end) end +M.PhysicalCanCastFunction = function(npc) + return not M:IsInvulnerable(npc) and not M:ShouldNotBeAttacked(npc) and not npc:IsMagicImmune() +end + M.IsPhysicalOutputDisabled = function(self, npc) - return npc:IsDisarmed() or npc:IsBlind() or self:IsEthereal(npc) + return npc:IsDisarmed() or npc:IsBlind() and not npc:GetAvailableItem("item_monkey_king_bar") or self:IsEthereal(npc) end M.GetHealthPercent = function(self, npc) return npc:GetHealth() / npc:GetMaxHealth() end +function M:GetPhysicalHealth(t) + return t:GetHealth() * (1+0.06*t:GetArmor()) / (1 - t:GetEvasion()) +end + +function M:GetBuildingPhysicalHealth(t) + local h = self:GetPhysicalHealth(t) + if t:HasModifier("modifier_fountain_glyph") then + h = h + self:GetModifierRemainingDuration("modifier_fountain_glyph") * 200 + end + return h +end + M.GetManaPercent = function(self, npc) return npc:GetMana() / npc:GetMaxMana() end -M.BasicDispellablePositiveModifiers = { - "modifier_ember_spirit_flame_guard", - "modifier_legion_commander_press_the_attack", - "modifier_windrunner_windrun", - "modifier_lich_frost_shield", - "modifier_oracle_purifying_flames", - "modifier_treant_living_armor", - "modifier_mirana_leap_buff", - "modifier_necrolyte_death_seeker", - "modifier_necrylte_sadist_active", - "modifier_pugna_decrepify", - "modifier_ghost_state", - "modifier_spirit_breaker_bulldoze", -} +M.GetHealthDeficit = function(self, npc) + return npc:GetMaxHealth() - npc:GetHealth() +end + +function M:GetManaDeficit(npc) + return npc:GetMaxMana() - npc:GetMana() +end + +function M:GetTargetIfGood(npc) + local target = npc:GetTarget() + if target~=nil and target:IsHero() and self:MayNotBeIllusion(npc, target) then + return target + end +end + +-- function M:GetAcrossAbilityStatusPerFrame(npc) +-- local g = {} +-- g.health = npc:GetHealth() +-- g.mana = npc:GetMana() +-- g.healthPercent = self:GetHealthPercent(npc) +-- g.manaPercent = self:GetManaPercent(npc) +-- g.attackRange = npc:GetAttackRange() +-- end function M:IndexOfBasicDispellablePositiveModifier(npc) - return self:Aggregate(nil, self.BasicDispellablePositiveModifiers, function(seed, modifier, index) + return self:Aggregate(nil, self.basicDispellWorthPositiveModifiers, function(seed, modifier, index) if seed then return seed end @@ -988,7 +2085,30 @@ function M:IndexOfBasicDispellablePositiveModifier(npc) end function M:HasBasicDispellablePositiveModifier(npc) - return self:Any(self.BasicDispellablePositiveModifiers, function(t) return t:HasModifier(t) end) + return self:Any(self.basicDispellWorthPositiveModifiers, function(t) return t:HasModifier(t) end) +end + +function M:DontInterruptAlly(npc) + return self:HasAnyModifier(npc, self.positiveForceMovementModifiers) or self:HasAnyModifier(npc, self.timeSensitivePositiveModifiers) or self:IsDuelCaster(npc) +end + +M.MidLaneTowers = { TOWER_MID_1, TOWER_MID_2, TOWER_MID_3 } +M.BotLaneTowers = { TOWER_BOT_1, TOWER_BOT_2, TOWER_BOT_3 } +M.TopLaneTowers = { TOWER_TOP_1, TOWER_TOP_2, TOWER_TOP_3 } + +function M:GetLaningTower(npc) + local team = npc:GetTeam() + local lane = npc:GetAssignedLane() + local function ToTower(t) return GetTower(team, t) end + local function TowerExists(t) return t:GetHealth() > 0 end + if lane == LANE_BOT then + local a = self:Map(self.BotLaneTowers, ToTower) + return self:First(a, TowerExists) + elseif lane == LANE_MID then + return self:First(self:Map(self.MidLaneTowers, ToTower), TowerExists) + elseif lane == LANE_TOP then + return self:First(self:Map(self.TopLaneTowers, ToTower), TowerExists) + end end -- debug functions @@ -1037,10 +2157,10 @@ end M.PrintAbilities = function(self, npcBot) local abilityNames = "{\n" - for i = 0,30 do - local abi = npcBot:GetAbilityInSlot(i) - if abi ~= nil and abi:GetName() ~= "generic_hidden" then - abilityNames = abilityNames.."\t\""..abi:GetName().."\",\n" + for i = 0,23 do + local ability = npcBot:GetAbilityInSlot(i) + if ability ~= nil and ability:GetName() ~= "generic_hidden" then + abilityNames = abilityNames.."\t\""..ability:GetName().."\",\n" end end abilityNames = abilityNames.."}" @@ -1050,6 +2170,83 @@ end -- ability function +function M:NormalCanCast(target, isPureDamageWithoutDisable, damageType, pierceMagicImmune, targetMustBeSeen, mustBeTargettable) + damageType = damageType or DAMAGE_TYPE_MAGICAL + if pierceMagicImmune == nil then + if damageType == DAMAGE_TYPE_MAGICAL then + pierceMagicImmune = false + else + pierceMagicImmune = true + end + end + if isPureDamageWithoutDisable == nil then + isPureDamageWithoutDisable = true + end + if self:IsInvulnerable(target) then + return false + end + if mustBeTargettable == nil then + mustBeTargettable = true + end + if mustBeTargettable and not self:CannotBeTargetted(target) then + return false + end + if not pierceMagicImmune and target:IsMagicImmune() then + return false + end + if targetMustBeSeen and not target:CanBeSeen() then + return false + end + if isPureDamageWithoutDisable and (damageType == DAMAGE_TYPE_PHYSICAL and self:ShouldNotBeAttacked(target) or damageType == DAMAGE_TYPE_MAGICAL and (target:IsMagicImmune() or self:Contains(self.IgnoreMagicalDamageModifiers, function(t) target:HasModifier(t) end))) then + return false + end + return true +end + +M.NormalCanCastFunction = function(target) return M:NormalCanCast(target) end + +function M:SpellCanCast(target, pierceMagicImmune, targetMustBeSeen, mustBeTargettable) + if targetMustBeSeen == nil then + targetMustBeSeen = true + end + if mustBeTargettable == nil then + mustBeTargettable = true + end + if target:IsInvulnerable() then + return false + end + if mustBeTargettable and self:CannotBeTargetted(target) then + return false + end + if not pierceMagicImmune and target:IsMagicImmune() then + return false + end + return true +end + +M.SpellCanCastFunction = function(target) return M:SpellCanCast(target) end + +function M:AllyCanCast(target, pierceMagicImmune) + if pierceMagicImmune == nil then + pierceMagicImmune = true + end + return not target:IsInvulnerable() and not self:CannotBeTargetted(target) +end + +M.AllyCanCastFunction = function(target) return M:AllyCanCast(target) end + +function M:NeutralCanCast(target) + +end + +function M:EnemyAllyCanCast(target, isPureDamageWithoutDisable, damageType, pierceMagicImmune, targetMustBeSeen) + if self:IsOnSameTeam(target, GetBot()) then + return self:NormalCanCast(target, isPureDamageWithoutDisable, damageType, pierceMagicImmune, targetMustBeSeen) + else + return self:AllyCanCast(target, pierceMagicImmune, targetMustBeSeen) + end +end + M.SpecialBonusAttributes = "special_bonus_attributes" M.TalentNamePrefix = "special_bonus_" M.IncorrectAbilityName = "incorrect_name" @@ -1065,11 +2262,11 @@ M.IsTalent = function(self, ability) end M.GetAbilities = function(self, npcBot) - local g = {} + local g = NewTable() for i = 0,25 do - local abi = npcBot:GetAbilityInSlot(i) - if abi ~= nil and abi:GetName() ~= "generic_hidden" then - table.insert(g, abi) + local ability = npcBot:GetAbilityInSlot(i) + if ability ~= nil and ability:GetName() ~= "generic_hidden" then + table.insert(g, ability) end end return g @@ -1096,6 +2293,8 @@ M.FillInAbilities = function(self, npcBot, abilityTable) table.insert(abilityTable, 22, self.SpecialBonusAttributes) table.insert(abilityTable, 23, self.SpecialBonusAttributes) table.insert(abilityTable, 24, self.SpecialBonusAttributes) + end + if #abilityTable == 25 then table.insert(abilityTable, 26, self.SpecialBonusAttributes) end for i = 1, 26 do @@ -1108,6 +2307,10 @@ M.FillInAbilities = function(self, npcBot, abilityTable) end end if #abilityTable == 30 then + npcBot.abilityTable = abilityTable + abilityTable.incorrectAbilityLevelUpNumber = self:Count(abilityTable, function(ability, index) + return index < npcBot:GetLevel() - npcBot:GetAbilityPoints() + 1 and (ability == nil or not ability:CanAbilityBeUpgraded() or ability:GetName() == self.IncorrectAbilityName) + end) return end @@ -1143,7 +2346,7 @@ end -- geometry M.IsVector = function(self, object) - return type(object)=="userdata" and type(object.x)=="number" and type(object.y)=="number" and type(object.z)=="number" and type(object.Length) == "function" + return type(object)=="userdata" and type(object.x)=="number" and type(object.y)=="number" and type(object.z)=="number" end M.ToStringVector = function(self, object) return string.format("(%d,%d,%d)",object.x,object.y,object.z) @@ -1164,13 +2367,75 @@ M.GetPointToLineDistance = function(self, point, line) return up/down end +M.GetPointToPointDistance = function(self, a, b) + return ((a.x-b.x)^2+(a.y-b.y)^2)^0.5 +end + -- Get the location on the line determined by startPoint and endPoint, with distance from startPoint to the target location M.GetPointFromLineByDistance = function(self, startPoint, endPoint, distance) - local line = self:GetLine(startPoint, endPoint) - local distanceTo = math.sqrt(math.pow(startPoint.x-endPoint.x, 2)+math.pow(startPoint.y-endPoint.y, 2)) - local divide = distanceTo / distance - local point = { x = startPoint.x + divide*(endPoint.x-startPoint.x), y = startPoint.y + divide*(endPoint.y-endPoint.x), z = 0 } - return point + local distanceTo = self:GetPointToPointDistance(startPoint, endPoint) + local divide = (endPoint - startPoint) / distanceTo * distance + return startPoint + divide +end + +M.GetCos = function(self, b, c, a) + return (b^2+c*2-a*2)/2/b/c +end +M.GetLocationToLocationDistance = function(self, a, b) + return ((a.x-b.x)^2+(a.y-b.y)^2)^0.5 +end + +function M:GetDegree(loc1, loc2) + local y = loc2.y-loc1.y + local x = loc2.x-loc1.x + return math.atan2(y, x) * 180 / math.pi +end +-- Find the location to use a aoe at a single target with the least distance the hero needs to walk before casting +--M.FindAOELocationAtSingleTarget = function(self, npcBot, target, radius, castRange, castPoint) +-- if self:CanMove(target) then +-- radius = radius * 0.8 +-- end +-- local g +-- GeneratePath(npcBot:GetLocation(), target:GetLocation(), {}, function(distance, waypoints) +-- if waypoints == 0 then +-- waypoints = { npcBot:GetLocation(), target:GetLocation() } +-- end +-- for i = 1, #waypoints-1 do +-- local waypoint1 = waypoints[i] +-- local waypoint2 = waypoints[i+1] +-- local dis1 = GetUnitToLocationDistance(target, waypoint1) +-- local dis2 = GetUnitToLocationDistance(target, waypoint2) +-- if dis1 > dis2 then +-- if radius >= dis1 then +-- g = waypoint1 +-- return +-- elseif radius >= dis2 then +-- local waypointDis = self:GetLocationToLocationDistance(waypoint1, waypoint2) +-- local cosine = self:GetCos(dis2, waypointDis, dis1) +-- local walkDis = dis1*cosine - (dis1^2-radius*2)^0.5 +-- local targetLocation = self:GetPointFromLineByDistance(waypoint1, waypoint2, walkDis) +-- g = targetLocation +-- return +-- end +-- else +-- if radius >= dis1 then +-- g = waypoint1 +-- return +-- end +-- end +-- end +-- g = waypoints[#waypoints] +-- end) +-- return g +--end +M.FindAOELocationAtSingleTarget = function(self, npcBot, target, radius, castRange, castPoint) + radius = radius - 80 + local distance = GetUnitToUnitDistance(npcBot, target) + if distance < radius + castRange then + return self:GetPointFromLineByDistance(npcBot:GetLocation(), target:GetLocation(), castRange) + else + return self:GetPointFromLineByDistance(target:GetLocation(), npcBot:GetLocation(), radius) + end end M.MinValue = function(self, coefficients, min, max) @@ -1258,18 +2523,49 @@ M.PURCHASE_ITEM_INSUFFICIENT_GOLD=63 M.PURCHASE_ITEM_NOT_AT_SECRET_SHOP=62 M.PURCHASE_ITEM_NOT_AT_HOME_SHOP=67 M.PURCHASE_ITEM_SUCCESS=-1 + +-- specified ability is not actually an ability (2) -- invalid order(3) unrecognised order name -- invalid order(40) order not allowed for illusions --- attempt to purchase "item_energy_booster" failed code 68 +-- unit is dead (20) +-- target tree is not active (43) +-- ability is still in cooldown (15) +-- ability is hidden +-- cannot cast ability on tree +-- cannot cast ability on target +-- target is unselectable +-- order requires a physical item target, but specified target is not a physical item (9) +-- item cannot be used from stash (37) +-- does not have enough mana to cast ability (14) +-- item is still in cooldown +-- can't cast attack ability on target, target is attack immune (32) +-- order invalid for units with attack ability DOTA_UNIT_CAP_NO_ATTACK (41) +-- can't cast on target, ability cannot target enemies (30) +-- can't cast on target, ability cannot target creeps (56) +-- unit can't perform command, unit has commands restricted (74) +-- hero does not have enough ability points to upgrade ability (13) +-- ability is hidden (60) + M.IgnoreDamageModifiers = { "modifier_abaddon_borrowed_time", - "modifier_aeon_disk", + "modifier_item_aeon_disk_buff", "modifier_winter_wyvern_winters_curse", "modifier_winter_wyvern_winters_curse_aura", "modifier_skeleton_king_reincarnation_scepter_active", } +M.CannotKillModifiers = { + "modifier_dazzle_shadow_grave", + "modifier_troll_warlord_battle_trance", +} + +M.CannotBeTargettedModifiers = { + "modifier_slark_shadow_dance", + "modifier_item_book_of_shadows", + "modifier_dark_willow_shadow_realm_buff", +} + M.IgnorePhysicalDamageModifiers = { "modifier_winter_wyvern_cold_embrace", } @@ -1304,6 +2600,9 @@ M.GetIllusionBattlePower = function(self, npc) if npc:HasModifier("modifier_arc_warden_tempest_double") or npc:HasModifier("modifier_skeleton_king_reincarnation_active") then return 0.8 end + if npc:HasModifier("modifier_vengefulspirit_hybrid_special") then + return 1.05 + end local t = 0.1 if self:Contains(self.GoodIllusionHero, name) then t = 0.25 @@ -1340,33 +2639,74 @@ M.GetNetWorth = function(self, npc, isEnemy) end end -M.GetHeroGroupNetWorth = function(self, heroes, isEnemy) +function M:GetBattlePower(npc) + local power = 0 + local name = npc:GetUnitName() + if string.match(name, "npc_dota_hero") then + power = npc:GetNetWorth() + npc:GetLevel() * 1000 + if npc:GetLevel() >= 25 then + power = power + 1000 + end + if npc:GetLevel() >= 30 then + power = power + 1000 + end + elseif string.match(name, "npc_dota_lone_druid_bear") then + local heroLevel = GetHeroLevel(npc:GetPlayerID()) + power = name[#"npc_dota_lone_druid_bear"+1]*2000-1000 + power = power + heroLevel * 250 + power = power + npc:GetNetWorth() + end + if npc:HasModifier("modifier_item_assault_positive") and not npc:HasModifier("modifier_item_assault_positive_aura") then + power = power + 1500 + end + local items = self:GetInventoryItemsNames(npc) + if npc:HasModifier("modifier_item_pipe_aura") and not self:Contains(items, "item_pipe") then + power = power + 400 + end + if npc:HasModifier("modifier_item_vladmir_aura") and not self:Contains(items, "item_vladmir") then + power = power + 300 + end + if npc:HasModifier("modifier_item_guardian_greaves_aura") and not self:Contains(items, "item_guardian_greaves") then + power = power + 1000 + elseif npc:HasModifier("modifier_item_mekansm_aura") and not self:Contains(items, "item_mekansm") then + power = power + 500 + end + return power +end + +M.GetHeroGroupBattlePower = function(self, npcBot, heroes, isEnemy) local function A(tb) - tb = self:SortByMaxFirst(tb, function(t) return t:GetNetWorth() end) - local f = self:Map(tb, function(t, index) return t:GetNetWorth() * 1.15-0.15*index end) - local g = {} - for _,v in ipairs(f) do - g[v:GetUnitName()] = v + local battlePowerMap = self:Map(tb, function(t) return { t:GetUnitName(), self:GetBattlePower(t) } end) + battlePowerMap = self:SortByMaxFirst(battlePowerMap, function(t) return t[2] end) + battlePowerMap = self:Map(battlePowerMap, function(t, index) return t[2] * (1.15-0.15*index) end) + local g = NewTable() + for _, v in ipairs(battlePowerMap) do + g[v[1]] = v[2] end return g end - local enemyNetWorthMap = A(self:GetEnemyHeroUnique(heroes)) + local enemyNetWorthMap = A(self:GetEnemyHeroUnique(npcBot, heroes)) local netWorth = 0 - local readNames = {} + local readNames = NewTable() for _, enemy in pairs(heroes) do local name = enemy:GetUnitName() if not self:Contains(readNames, name) then table.insert(readNames, name) - netWorth = netWorth + enemyNetWorthMap[name] + -- TODO: enemyNetWorthMap[name] should not be null + if enemyNetWorthMap[name] then + netWorth = netWorth + enemyNetWorthMap[name] + end else - netWorth = netWorth + enemyNetWorthMap[name] * self:GetIllusionBattlePower(enemy) + if enemyNetWorthMap[name] then + netWorth = netWorth + enemyNetWorthMap[name] * self:GetIllusionBattlePower(enemy) + end end end return netWorth end -M.Outnumber = function(self, friends, enemies) - return self:GetHeroGroupNetWorth(friends, false) >= self:GetHeroGroupNetWorth(enemies, true) * 1.8 +M.Outnumber = function(self, npcBot, friends, enemies) + return self:GetHeroGroupBattlePower(npcBot, friends, false) >= self:GetHeroGroupBattlePower(npcBot, enemies, true) * 1.8 end @@ -1375,17 +2715,290 @@ M.CannotBeKilledNormally = function(self, target) end M.HasScepter = function(self, npc) - return npc:HasScepter() or npc:HasModifier("modifier_wisp_tether_scepter") + return npc:HasScepter() or npc:HasModifier("modifier_wisp_tether_scepter") or npc:HasModifier("modifier_item_ultimate_scepter") or npc:HasModifier("modifier_item_ultimate_scepter_consumed_alchemist") end +-- ability record --- Courier system +local locationAOEAbilities = { + cone = { + "lina_dragon_slave", + }, + circle = { + "lina_light_strike_array", + }, + isoscelesTrapezoid = { + "kunkka_tidebringer", + }, +} -M.CourierUsageThink = function(self) - local npcBot = GetBot() - local courier = GetCourier(0) - local items = self:GetCourierItems() - +function M:RecordAbility(npc, index, target, castType, abilities) + local abilityRecords = npc.abilityRecords + if index ~= nil then + abilityRecords[index] = {} + if castType == "Location" then + abilityRecords[index].location = target + elseif castType == "Target" then + abilityRecords[index].target = target + elseif castType == "Tree" then + abilityRecords[index].targetTree = target + elseif self:IsVector(target) then + abilityRecords[index].location = target + elseif target ~= nil then + abilityRecords[index].target = target + end + abilityRecords.usingAbilityIndex = index + abilityRecords[index].beginCastTime = DotaTime() + return + end + if not npc:IsUsingAbility() and not npc:IsChanneling() then + if abilityRecords.usingAbilityIndex ~= nil and not abilities[abilityRecords.usingAbilityIndex]:IsCooldownReady() then + abilityRecords.lastUsedAbilityIndex = abilityRecords.usingAbilityIndex + abilityRecords.usingAbilityIndex = nil + abilityRecords.lastUsedAbilityTime = DotaTime() + end + end +end + +local frameNumber = 0 +local dotaTimer +local function FloatEqual(a, b) + return math.abs(a-b)<0.000001 +end + +-- tick + +function M:GetFrameNumber() + return frameNumber +end + +function M:EveryManyFrames(count, times) + times = times or 1 + return frameNumber % count < times +end + +local defaultReturn = NewTable() +local everySecondsCallRegistry = NewTable() + +function M:EveryManySeconds(second, oldFunction) + local functionName = tostring(oldFunction) + everySecondsCallRegistry[functionName.."lastCallTime"] = RandomFloat(0, second) + return function(...) + if everySecondsCallRegistry[functionName.."lastCallTime"] <= DotaTime() - second then + everySecondsCallRegistry[functionName.."lastCallTime"] = DotaTime() + return oldFunction(...) + else + return defaultReturn + end + end +end + +local singleForTeamRegistry = NewTable() + +function M:SingleForTeam(oldFunction) + local functionName = tostring(oldFunction)..GetTeam() + return function(...) + if singleForTeamRegistry[functionName] ~= frameNumber then + singleForTeamRegistry[functionName] = frameNumber + return oldFunction(...) + else + return defaultReturn + end + end +end + +local singleForAllBots = NewTable() + +function M:SingleForAllBots(oldFunction) + local functionName = tostring(oldFunction) + return function(...) + if singleForAllBots[functionName] ~= frameNumber then + singleForAllBots[functionName] = frameNumber + return oldFunction(...) + else + return defaultReturn + end + end +end + +local groupAnnounceTimes1 = 0 +function M:AnnounceGroups1(npcBot) + if groupAnnounceTimes1 == 0 then + npcBot:ActionImmediate_Chat("Thanks for choosing RMMAI. Join our new discord group at ... to put suggestions or devloping issues!", true) + groupAnnounceTimes1 = 1 + end +end +local groupAnnounceTimes2 = 0 +function M:AnnounceGroups2(npcBot) + if groupAnnounceTimes2 == 0 then + npcBot:ActionImmediate_Chat("Or join QQ group at 946823144!", true) + groupAnnounceTimes2 = 1 + end +end + +function M:CalledOnThisFrame(functionInvocationResult) + return functionInvocationResult ~= defaultReturn +end + +local slowFunctionRegistries = NewTable() +local coroutineRegistry = NewTable() +local coroutineExempt = NewTable() + +function M:TickFromDota() + local time = DotaTime() + local function ResumeCoroutine(thread) + local coroutineResult = { coroutine.resume(thread[1], time - dotaTimer) } + if not coroutineResult[1] then + error(coroutineResult[2]) + end + end + if dotaTimer == nil then + dotaTimer = time + return + end + if not FloatEqual(time, dotaTimer) then + frameNumber = frameNumber + 1 + self:ForEach(slowFunctionRegistries, function(t) t(time - dotaTimer) end) + local threadIndex = 1 + while threadIndex <= #coroutineRegistry do + local t = coroutineRegistry[threadIndex] + local exemptIndex + local exempt + self:ForEach(coroutineExempt, function(exemptPair, index) + if exemptPair[1] == t then + if exemptPair[2] == frameNumber then + exempt = true + end + exemptIndex = index + end + end) + if exemptIndex then + table.remove(coroutineExempt, exemptIndex) + end + if not exempt then + if coroutine.status(t) == "suspended" then + ResumeCoroutine(t) + threadIndex = threadIndex + 1 + elseif coroutine.status(t) == "dead" then + table.remove(coroutineRegistry, threadIndex) + else + threadIndex = threadIndex + 1 + end + end + end + dotaTimer = time + end +end + +function M:RegisterSlowFunction(oldFunction, calledWhenHowManyFrames, frameOffset, defaultReturn) + return function(...) + if frameNumber % calledWhenHowManyFrames == frameOffset then + return oldFunction(...) + else + return self:UnpackIfTable(defaultReturn) + end + end +end + +-- coroutine + +function M:ResumeUntilReturn(func) + local g = NewTable() + local thread = coroutine.create(func) + while true do + local values = { coroutine.resume(thread) } + if values[1] then + table.remove(values, 1) + table.insert(g, values) + else + error(values[2]) + break + end + end + return g +end + +function M:StartCoroutine(func) + local newCoroutine = coroutine.create(func) + table.insert(coroutineRegistry, newCoroutine) + table.insert(coroutineExempt, {newCoroutine, frameNumber}) + return newCoroutine +end + +function M:WaitForSeconds(seconds) + local function WaitFor(firstFrameTime) + local t = seconds - firstFrameTime + while t > 0 do + t = t - coroutine.yield() + end + end + return self:StartCoroutine(WaitFor) +end + +function M:StopCoroutine(thread) + self:Remove_Modify(coroutineExempt, function(t) return t[1] == thread end) + self:Remove_Modify(coroutineRegistry, thread) +end + +-- get data from ability +-- for example, to get value aoe_radius, use ability.aoe_radius rather than ability:GetSpecialValueInt("aoe_radius") + +local function GetDataFromAbility(ability, valueName) + local a = ability:GetSpecialValueInt(valueName) + return a==0 and ability:GetSpecialValueFloat(valueName) or a +end + +local function Append__Index(tb, __index) + local m = getmetatable(tb) + if m == nil then + m = {} + setmetatable(tb, m) + end + local oldIndex = m.__index + if oldIndex == nil then + m.__index = __index + elseif type(oldIndex) == "function" then + m.__index = function(ability, i) + local oldResult = { oldIndex(ability, i) } + if oldResult[1] == nil then + return __index(ability, i) + else + return M.Unpack(oldResult) + end + end + elseif type(oldIndex) == "table" then + if oldIndex == m then + m.__index = function(g, h) + local newResult = { __index(g, h) } + if newResult[1] == nil then + return oldIndex[h] + else + return M.Unpack(newResult) + end + end + else + Append__Index(oldIndex, __index) + end + end +end +Append__Index(CDOTABaseAbility_BotScript, GetDataFromAbility) + +function M:pcall(func, ...) + local result = { func(...) } + if result[1] then + table.remove(result, 1) + return self:Unpack(result) + else + error(result[2]) + DebugPause() + end +end + +-- M.debug = true +function M:DebugPause() + if self.debug then + DebugPause() + end end return M diff --git a/util/AbilityInformation.lua b/util/AbilityInformation.lua new file mode 100644 index 00000000..e69de29b diff --git a/util/CourierSystem.lua b/util/CourierSystem.lua index 35a0f984..53b26737 100644 --- a/util/CourierSystem.lua +++ b/util/CourierSystem.lua @@ -241,14 +241,14 @@ function M.CourierUsageThink() -- print(npcBot:GetUnitName()); if cst == COURIER_STATE_MOVING then courierUtils.pIDInc = courierUtils.pIDInc + 1; - print(npcBot:GetUnitName().." : Courier Successfully Assigned ."..tostring(npcBot.courierID)); + -- print(npcBot:GetUnitName().." : Courier Successfully Assigned ."..tostring(npcBot.courierID)) checkCourier = false; npcBot.courierAssigned = true; courierUtils.calibrateTime = DotaTime(); npcBot:ActionImmediate_Courier( cr, COURIER_ACTION_RETURN_STASH_ITEMS ); return; elseif npcBot.courierID ~= nil then - print(npcBot:GetUnitName().. ": Failed to Assign Courier."); + -- print(npcBot:GetUnitName().. ": Failed to Assign Courier.") npcBot.courierID = npcBot.courierID + 1; checkCourier = false; courierUtils.calibrateTime = DotaTime(); @@ -318,20 +318,20 @@ function M.CourierUsageThink() local courierPHP = npcCourier:GetHealth() / npcCourier:GetMaxHealth(); if IsFlyingCourier(npcCourier) then - local burst = npcCourier:GetAbilityByName('courier_shield'); - if IsTargetedByUnit(npcCourier) then - if burst:IsFullyCastable() and apiAvailable == true - then - npcBot:ActionImmediate_Courier( npcCourier, COURIER_ACTION_BURST ); - return - elseif DotaTime() > returnTime + 7.0 - --and not burst:IsFullyCastable() and not npcCourier:HasModifier('modifier_courier_shield') - then - npcBot:ActionImmediate_Courier( npcCourier, COURIER_ACTION_RETURN ); - returnTime = DotaTime(); - return - end - end + -- local burst = npcCourier:GetAbilityByName('courier_shield'); + -- if IsTargetedByUnit(npcCourier) then + -- if burst:IsFullyCastable() and apiAvailable == true + -- then + -- npcBot:ActionImmediate_Courier( npcCourier, COURIER_ACTION_BURST ); + -- return + -- elseif DotaTime() > returnTime + 7.0 + -- --and not burst:IsFullyCastable() and not npcCourier:HasModifier('modifier_courier_shield') + -- then + -- npcBot:ActionImmediate_Courier( npcCourier, COURIER_ACTION_RETURN ); + -- returnTime = DotaTime(); + -- return + -- end + -- end else if IsTargetedByUnit(npcCourier) then if DotaTime() - returnTime > 7.0 then @@ -346,7 +346,7 @@ function M.CourierUsageThink() npcCourier.latestUser = "temp"; end - if npcBot.SShopUser and ( not npcBot:IsAlive() or npcBot:GetActiveMode() == npcBot_MODE_SECRET_SHOP or not npcBot.SecretShop ) then + if npcBot.SShopUser and ( not npcBot:IsAlive() or npcBot:GetActiveMode() == BOT_MODE_SECRET_SHOP or not npcBot.SecretShop ) then --npcBot:ActionImmediate_Chat( "Releasing the courier to anticipate secret shop stuck", true ); npcCourier.latestUser = "temp"; npcBot.SShopUser = false; diff --git a/util/ItemPurchaseSystem.lua b/util/ItemPurchaseSystem.lua index 728a9623..a896ed9a 100644 --- a/util/ItemPurchaseSystem.lua +++ b/util/ItemPurchaseSystem.lua @@ -21,13 +21,11 @@ function M.SellExtraItem(ItemsToBuy) end if(GameTime()>25*60 or level>=10) then - --M.SellSpecifiedItem("item_stout_shield") M.SellSpecifiedItem("item_orb_of_venom") M.SellSpecifiedItem("item_enchanted_mango") M.SellSpecifiedItem("item_bracer") M.SellSpecifiedItem("item_null_talisman") M.SellSpecifiedItem("item_wraith_band") - --M.SellSpecifiedItem("item_poor_mans_shield") end if(GameTime()>35*60 or level>=15) then @@ -40,7 +38,6 @@ function M.SellExtraItem(ItemsToBuy) M.SellSpecifiedItem("item_quelling_blade") M.SellSpecifiedItem("item_soul_ring") M.SellSpecifiedItem("item_buckler") - M.SellSpecifiedItem("item_ring_of_basilius") M.SellSpecifiedItem("item_headdress") @@ -53,15 +50,15 @@ function M.SellExtraItem(ItemsToBuy) M.SellSpecifiedItem("item_hand_of_midas") M.SellSpecifiedItem("item_dust") end - if(GameTime()>40*60 and npcBot:GetGold()>2500 and (item_travel_boots[1]==nil and item_travel_boots[2]==nil) and npcBot.HaveTravelBoots~=true ) - then - table.insert(ItemsToBuy,"item_boots") - table.insert(ItemsToBuy,"item_recipe_travel_boots") - npcBot.HaveTravelBoots=true - if npcBot:GetGold() >= 4500 then - table.insert(ItemsToBuy, "item_recipe_travel_boots") - end - end + --if(GameTime()>40*60 and npcBot:GetGold()>2500 and (item_travel_boots[1]==nil and item_travel_boots[2]==nil) and npcBot.HaveTravelBoots~=true ) + --then + -- table.insert(ItemsToBuy,"item_boots") + -- table.insert(ItemsToBuy,"item_recipe_travel_boots") + -- npcBot.HaveTravelBoots=true + -- if npcBot:GetGold() >= 4500 then + -- table.insert(ItemsToBuy, "item_recipe_travel_boots") + -- end + --end end if(item_travel_boots[1]~=nil or item_travel_boots[2]~=nil) @@ -328,17 +325,19 @@ function M.WeNeedTpscroll() -- Count current number of TP scrolls local iScrollCount = 0; - for i = 0, 16 do + for i = 9, 16 do local sCurItem = npcBot:GetItemInSlot(i); if ( sCurItem ~= nil and sCurItem:GetName() == "item_tpscroll" ) then iScrollCount = iScrollCount+sCurItem:GetCurrentCharges() end end + if DotaTime() <= 3*60 then + return + end -- If we are at the sideshop or fountain with no TPs, then buy one or two - if ( iScrollCount <=2 and item_travel_boots_1 == nil and item_travel_boots_2 == nil ) then - - if ( npcBot:DistanceFromSideShop() <= 200 or npcBot:DistanceFromFountain() <= 200 ) then + if ((iScrollCount <= 2 and DotaTime() >= 5*60) or iScrollCount == 0) and item_travel_boots_1 == nil and item_travel_boots_2 == nil then + if npcBot:DistanceFromFountain() <= 200 then if ( DotaTime() > 2*60 and DotaTime() < 20 * 60 ) then npcBot:ActionImmediate_PurchaseItem( "item_tpscroll" ); @@ -346,16 +345,6 @@ function M.WeNeedTpscroll() npcBot:ActionImmediate_PurchaseItem( "item_tpscroll" ); npcBot:ActionImmediate_PurchaseItem( "item_tpscroll" ); end - --[[else - if(npcBot.WeNeedTpscrollTimer==nil) - then - npcBot.WeNeedTpscrollTimer=DotaTime() - end - if(DotaTime()-npcBot.WeNeedTpscrollTimer>120) - then - npcBot:ActionImmediate_PurchaseItem( "item_tpscroll" ); - npcBot.WeNeedTpscrollTimer=DotaTime() - end]] else npcBot:ActionImmediate_PurchaseItem( "item_tpscroll" ); end @@ -364,9 +353,7 @@ function M.WeNeedTpscroll() end function M.SellSpecifiedItem( item_name ) - local npcBot = GetBot(); - local itemCount = 0; local item = nil; @@ -390,9 +377,7 @@ function M.SellSpecifiedItem( item_name ) end function M.GetItemSlotsCount2(npcBot) - local itemCount = 0; - for i = 0, 8 do local sCurItem = npcBot:GetItemInSlot(i); @@ -407,7 +392,6 @@ end function M.GetItemSlotsCount() local npcBot = GetBot(); - local itemCount = 0; for i = 0, 8 @@ -423,13 +407,7 @@ function M.GetItemSlotsCount() end function M.IsItemSlotsFull() - local itemCount = M.GetItemSlotsCount(); - if(itemCount>=8) - then - return true - else - return false - end + return M.GetItemSlotsCount() >= 8 end function M.checkItemBuild(ItemsToBuy) @@ -572,15 +550,6 @@ function M.BuySupportItem() end - -- if(wardState== nil) - -- then - - -- else - - -- end - - - local item_ward_observer = M.GetItemIncludeBackpack( "item_ward_observer" ); local item_ward_sentry = M.GetItemIncludeBackpack( "item_ward_dispenser" ); local item_gem = M.GetItemIncludeBackpack( "item_gem" ) @@ -662,7 +631,7 @@ function M.PrintTable(table , level) for k,v in pairs(table) do if type(v) == "table" then key = k - PrintTable(v, level + 1) + M.PrintTable(v, level + 1) else local content = string.format("%s%s = %s", indent .. " ",tostring(k), tostring(v)) print(content) @@ -678,7 +647,7 @@ setmetatable(M.ItemName, { }) M.Consumables = { "clarity", - "mango", + "enchanted_mango", "faerie_fire", "tome_of_knowledge", "tango", @@ -690,25 +659,9 @@ M.IsConsumableItem = function(self, item) return AbilityExtensions:Contains(self.Consumables, string.sub(item, 6)) end -M.GetAllBoughtItems = function(self) - local g = {} - local npcBot = GetBot() - for i = 0, 15 do - local item = npcBot:GetItemInSlot(i) - if item then - table.insert(g, item) - end - end - local courier = GetCourier(0) - if courier ~= nil then - for i = 0, 8 do - local item = courier:GetItemInSlot(i) - if item then - table.insert(g, item) - end - end - end - return g + +local function HasScepter(npc) + return npc:HasScepter() or npc:HasModifier("modifier_item_ultimate_scepter") end @@ -747,10 +700,10 @@ M.CreateItemInformationTable = function(self, npcBot, itemTable) return tb end local function RemoveBoughtItems() -- used only when reloading scripts in game - local boughtItems = AbilityExtensions:Map(self:GetAllBoughtItems(), function(t) return t:GetName() end) + local boughtItems = AbilityExtensions:Map(AbilityExtensions:GetAllBoughtItems(npcBot), function(t) return t:GetName() end) boughtItems = TranslateToEquivalentItem(boughtItems) - local function TryRemoveItem(itemName, tbToRemoveFirst) - if DotaTime() > -60 and self:IsConsumableItem(itemName) then + local function TryRemoveItemWithName(itemName, tbToRemoveFirst) + if self:IsConsumableItem(itemName) then table.remove(tbToRemoveFirst, 1) return true end @@ -762,14 +715,37 @@ M.CreateItemInformationTable = function(self, npcBot, itemTable) end end end - local infoTable = GetBot().itemInformationTable - while TryRemoveItem(infoTable[1].name, infoTable) do end - if infoTable[1].recipe then - while #infoTable[1].recipe > 0 and TryRemoveItem(infoTable[1].recipe[1], infoTable[1].recipe) do end + + local function TryRemoveItem(item, tbToRemoveFirst) + if self:IsConsumableItem(item.name) then + table.remove(tbToRemoveFirst, 1) + return true + end + for i, boughtItem in ipairs(boughtItems) do + if boughtItem and boughtItem == item.name then + table.remove(boughtItems, i) + table.remove(tbToRemoveFirst, 1) + return true + elseif item.usedAsRecipeOf and AbilityExtensions:Contains(boughtItems, item.usedAsRecipeOf) then + table.remove(tbToRemoveFirst, 1) + return true + end + end + end + local infoTable = npcBot.itemInformationTable + while TryRemoveItem(infoTable[1], infoTable) do end + while infoTable[1] and infoTable[1].recipe do + while #infoTable[1].recipe > 0 and TryRemoveItemWithName(infoTable[1].recipe[1], infoTable[1].recipe) do end if #infoTable[1].recipe == 0 then table.remove(infoTable, 1) + else + break end end + if npcBot:HasModifier("modifier_item_ultimate_scepter") then + AbilityExtensions:Remove_Modify(infoTable, function(t) return t.name == "item_ultimate_scepter" or t.name == "item_recipe_ultimate_scepter" end) + end + end local g = {} @@ -806,82 +782,86 @@ M.CreateItemInformationTable = function(self, npcBot, itemTable) table.insert(g, itemInformation) end npcBot.itemInformationTable = g - RemoveBoughtItems() + if DotaTime() > -60 then + RemoveBoughtItems() + end + --print(npcBot:GetUnitName()..": item table:") + --AbilityExtensions:DebugArray(g) + --print("bought items: ") + --AbilityExtensions:DebugArray(AbilityExtensions:Map(AbilityExtensions:GetAllBoughtItems(npcBot), function(t) return t:GetName() end)) end -function M.SellExtraItemExtend() - local npcBot=GetBot() - local level=npcBot:GetLevel() - local item_travel_boots = M.NoNeedTpscrollForTravelBoots(); - -- local item_travel_boots_1 = item_travel_boots[1]; - -- local item_travel_boots_2 = item_travel_boots[2]; +local sNextItem +local UseCourier = function() + local npcBot = GetBot() + local courier = AbilityExtensions:GetMyCourier(npcBot) + if courier == nil then + return + end + local courierState = GetCourierState(courier) + if courierState == COURIER_STATE_DEAD then + return + end + local courierItemNumber = #AbilityExtensions:GetCourierItems(courier) - if(M.IsItemSlotsFull()) - then - if(GameTime()>6*60 or level>=6) and AbilityExtensions:GetEmptyItemSlots(npcBot) < 2 - then - M.SellSpecifiedItem("item_faerie_fire") - M.SellSpecifiedItem("item_tango") - M.SellSpecifiedItem("item_clarity") - M.SellSpecifiedItem("item_flask") + if not npcBot:IsAlive() then + if courierState ~= COURIER_STATE_RETURNING_TO_BASE and courierState ~= COURIER_STATE_AT_BASE then + npcBot:ActionImmediate_Courier(courier, COURIER_ACTION_RETURN) end - if(GameTime()>25*60 or level>=10) and AbilityExtensions:GetEmptyItemSlots(npcBot) < 2 - then - --M.SellSpecifiedItem("item_stout_shield") - M.SellSpecifiedItem("item_orb_of_venom") - M.SellSpecifiedItem("item_enchanted_mango") - M.SellSpecifiedItem("item_bracer") - M.SellSpecifiedItem("item_null_talisman") - M.SellSpecifiedItem("item_wraith_band") - --M.SellSpecifiedItem("item_poor_mans_shield") + return + end + local nearSecretShop = courier:DistanceFromSecretShop() <= 180 + local function IsWaitingAtSecretShop() + return courierState == COURIER_STATE_IDLE and nearSecretShop and npcBot:GetGold() >= GetItemCost(sNextItem)*0.9 + end + + if courier.returnWhenCarryingTooMany then + if courier:DistanceFromFountain() <= 1200 and courierState == COURIER_STATE_AT_BASE and (courier.returnCarryNumber < courierItemNumber or #AbilityExtensions:GetStashItems(npcBot) > 0) then + npcBot:ActionImmediate_Courier(courier, COURIER_ACTION_TAKE_AND_TRANSFER_ITEMS) + courier.returnWhenCarryingTooMany = nil + return end - if(GameTime()>35*60 or level>=15) and AbilityExtensions:GetEmptyItemSlots(npcBot) < 2 - then - M.SellSpecifiedItem("item_branches") - M.SellSpecifiedItem("item_bottle") - M.SellSpecifiedItem("item_magic_wand") - M.SellSpecifiedItem("item_flask") - M.SellSpecifiedItem("item_ancient_janggo") - M.SellSpecifiedItem("item_ring_of_basilius") - M.SellSpecifiedItem("item_quelling_blade") - M.SellSpecifiedItem("item_soul_ring") - M.SellSpecifiedItem("item_buckler") - M.SellSpecifiedItem("item_ring_of_basilius") - M.SellSpecifiedItem("item_headdress") + if courierState == COURIER_STATE_AT_BASE and IsItemPurchasedFromSecretShop(sNextItem) and npcBot:GetGold() >= GetItemCost(sNextItem)*0.9 then + npcBot:ActionImmediate_Courier(courier, COURIER_ACTION_SECRET_SHOP) + return + end + npcBot:ActionImmediate_Courier(courier, COURIER_ACTION_RETURN) + return + end + if AbilityExtensions:GetEmptyItemSlots(npcBot) == 0 and courierItemNumber > 0 and GetUnitToUnitDistance(npcBot, courier) <= 400 then + courier.returnCarryNumber = courierItemNumber + npcBot:ActionImmediate_Courier(courier, COURIER_ACTION_RETURN) + return + end + if #AbilityExtensions:GetStashItems(npcBot) ~= 0 then + if (courierState == COURIER_STATE_AT_BASE or courierState == COURIER_STATE_IDLE) and not IsWaitingAtSecretShop() then + npcBot:ActionImmediate_Courier(courier, COURIER_ACTION_TAKE_AND_TRANSFER_ITEMS) + return end - if(GameTime()>40*60 or level>=20) and AbilityExtensions:GetEmptyItemSlots(npcBot) < 2 - then - M.SellSpecifiedItem("item_vladmir") - M.SellSpecifiedItem("item_urn_of_shadows") - M.SellSpecifiedItem("item_drums_of_endurance") - M.SellSpecifiedItem("item_hand_of_midas") - M.SellSpecifiedItem("item_dust") + end + if #AbilityExtensions:GetCourierItems(courier) ~= 0 then + if courierState ~= COURIER_STATE_DELIVERING_ITEMS and not IsWaitingAtSecretShop() then + npcBot:ActionImmediate_Courier(courier, COURIER_ACTION_TRANSFER_ITEMS) + return end - if(GameTime()>40*60 and npcBot:GetGold()>2500 and (item_travel_boots[1]==nil and item_travel_boots[2]==nil) and npcBot.HaveTravelBoots~=true ) - then - table.insert(npcBot.itemInformationTable, { name = "item_travel_boots", recipe = {"item_boots", "item_recipe_travel_boots" }}) - npcBot.HaveTravelBoots = true + end + if IsItemPurchasedFromSecretShop(sNextItem) and npcBot:GetGold() >= GetItemCost(sNextItem)*0.9 then + courier.returnWhenCarryingTooMany = nil + if courierState == COURIER_STATE_AT_BASE then + -- print("courier usage a2") + npcBot:ActionImmediate_Courier(courier, COURIER_ACTION_SECRET_SHOP) + return end - if GameTime()>45*60 and npcBot:GetGold()>2000 and (item_travel_boots[1]==nil and item_travel_boots[2]==nil) and not npcBot.HaveTravelBoots2 then - table.insert(npcBot.itemInformationTable, { name = "item_travel_boots_2", recipe = { "item_recipe_travel_boots" }}) - npcBot.HaveTravelBoots2 = true + if nearSecretShop and npcBot:GetGold() >= GetItemCost(sNextItem) then + -- print("courier usage a1") + npcBot:ActionImmediate_PurchaseItem(sNextItem) + return end end - - if(item_travel_boots[1]~=nil or item_travel_boots[2]~=nil) - then - M.SellSpecifiedItem("item_boots") - M.SellSpecifiedItem("item_arcane_boots") - M.SellSpecifiedItem("item_phase_boots") - M.SellSpecifiedItem("item_power_treads_agi") - M.SellSpecifiedItem("item_power_treads_int") - M.SellSpecifiedItem("item_power_treads_str") - M.SellSpecifiedItem("item_tranquil_boots") - end - end +UseCourier = AbilityExtensions:EveryManySeconds(0.5, UseCourier) M.ItemPurchaseExtend = function(self, ItemsToBuy) local function GetTopItemToBuy() @@ -909,7 +889,7 @@ M.ItemPurchaseExtend = function(self, ItemsToBuy) if GetGameState() == DOTA_GAMERULES_STATE_POSTGAME then return end - local npcBot = GetBot(); + local npcBot = GetBot() local function RemoveInvisibleItemsWhenBountyHunter() local enemies = AbilityExtensions:Filter(GetBot():GetNearbyHeroes(1500, true, BOT_MODE_NONE), function(t) @@ -934,25 +914,24 @@ M.ItemPurchaseExtend = function(self, ItemsToBuy) return end - RemoveInvisibleItemsWhenBountyHunter() - local sNextItem = GetTopItemToBuy() - if sNextItem == nil then - print(npcBot:GetUnitName()..": ".."purchase a nil item") - return - end + --RemoveInvisibleItemsWhenBountyHunter() + sNextItem = GetTopItemToBuy() npcBot:SetNextItemPurchaseValue( GetItemCost( sNextItem ) ) - M.SellExtraItemExtend(ItemsToBuy) + M.SellExtraItem(ItemsToBuy) if npcBot:DistanceFromFountain()<=2500 or npcBot:GetHealth()/npcBot:GetMaxHealth()<=0.35 then - npcBot.secretShopMode = false + npcBot.secretShopMode = false end if IsItemPurchasedFromSecretShop( sNextItem )==false then - npcBot.secretShopMode = false + npcBot.secretShopMode = false end - if ( npcBot:GetGold() >= GetItemCost( sNextItem ) ) then + if npcBot:GetGold() >= GetItemCost( sNextItem ) then + if sNextItem == "item_aghanims_shard" and GetItemStockCount(sNextItem) < 1 then + return + end if npcBot.secretShopMode~=true then if (IsItemPurchasedFromSecretShop( sNextItem ) and sNextItem ~= "item_bottle") then @@ -965,10 +944,10 @@ M.ItemPurchaseExtend = function(self, ItemsToBuy) if(npcBot:DistanceFromSecretShop() <= 250) then PurchaseResult=npcBot:ActionImmediate_PurchaseItem( sNextItem ) end - local courier=GetCourier(0) + local courier = AbilityExtensions:GetMyCourier(npcBot) local ItemCount=M.GetItemSlotsCount2(courier) if(courier:DistanceFromSecretShop() <= 250 and ItemCount<9) then - PurchaseResult=GetCourier(0):ActionImmediate_PurchaseItem( sNextItem ) + PurchaseResult = courier:ActionImmediate_PurchaseItem( sNextItem ) end else PurchaseResult=npcBot:ActionImmediate_PurchaseItem( sNextItem ) @@ -1001,6 +980,7 @@ M.ItemPurchaseExtend = function(self, ItemsToBuy) npcBot.secretShopMode = false; end + UseCourier() end M.RemoveItemPurchase = function(self, itemTable, itemName) diff --git a/util/ItemUsageSystem.lua b/util/ItemUsageSystem.lua index 933755d9..8d3eb237 100644 --- a/util/ItemUsageSystem.lua +++ b/util/ItemUsageSystem.lua @@ -52,7 +52,7 @@ local function GiveToMidLaner() if DotaTime() <= 0 then return nil end for k, _ in pairs(teamPlayers) do local member = GetTeamMember(k) - if member ~= nil and not member:IsIllusion() and member:IsAlive() and member:GetMaxHealth()-member:GetHealth() >= 150 then + if member ~= nil and not member:IsIllusion() and member:IsAlive() and member:GetMaxHealth()-member:GetHealth() >= 200 then local num_sts = GetItemCount(member, "item_tango_single") local num_ff = GetItemCount(member, "item_faerie_fire") local num_stg = GetItemCharges(member, "item_tango") @@ -280,6 +280,7 @@ function M.UnImplementedItemUsage() if npcBot:IsChanneling() or npcBot:IsUsingAbility() or npcBot:IsInvisible() or npcBot:IsMuted() then return end + local notBlasted = not npcBot:HasModifier("modifier_ice_blast") local tableNearbyEnemyHeroes = npcBot:GetNearbyHeroes(800, true, BOT_MODE_NONE) local nearByTowers = npcBot:GetNearbyTowers(1000, true) @@ -333,58 +334,23 @@ function M.UnImplementedItemUsage() end local pt = IsItemAvailable("item_power_treads") - if pt ~= nil and pt:IsFullyCastable() then + if pt ~= nil and pt:IsFullyCastable() and notBlasted then UsePowerTreads(pt) - -- if - -- mode == BOT_MODE_RETREAT and pt:GetPowerTreadsStat() ~= ATTRIBUTE_STRENGTH and - -- npcBot:WasRecentlyDamagedByAnyHero(5.0) - -- then - -- npcBot:Action_UseAbility(pt) - -- return - -- elseif mode == BOT_MODE_ATTACK and CanSwitchPTStat(pt) then - -- npcBot:Action_UseAbility(pt) - -- return - -- else - -- local enemies = npcBot:GetNearbyHeroes(1300, true, BOT_MODE_NONE) - -- if #enemies == 0 and mode ~= BOT_MODE_RETREAT and CanSwitchPTStat(pt) then - -- npcBot:Action_UseAbility(pt) - -- return - -- end - -- end end - local bas = IsItemAvailable("item_ring_of_basilius") - if bas ~= nil and bas:IsFullyCastable() then - if mode == BOT_MODE_LANING and not bas:GetToggleState() then - npcBot:Action_UseAbility(bas) - return - elseif mode ~= BOT_MODE_LANING and bas:GetToggleState() then - npcBot:Action_UseAbility(bas) - return - end - end - - local buck = IsItemAvailable("item_buckler") - if buck ~= nil and buck:IsFullyCastable() then - if mode == BOT_MODE_LANING and not buck:GetToggleState() then - npcBot:Action_UseAbility(buck) - return - elseif mode ~= BOT_MODE_LANING and buck:GetToggleState() then - npcBot:Action_UseAbility(buck) - return - end - end - - -- local aq = IsItemAvailable("item_ring_of_aquila") - -- if aq ~= nil and aq:IsFullyCastable() then - -- if mode == BOT_MODE_LANING and not aq:GetToggleState() then - -- npcBot:Action_UseAbility(aq) - -- return - -- elseif mode ~= BOT_MODE_LANING and aq:GetToggleState() then - -- npcBot:Action_UseAbility(aq) - -- return - -- end - -- end + --local ringOfBasilius = IsItemAvailable("item_ring_of_basilius") + --if ringOfBasilius and ringOfBasilius:IsFullyCastable() then + -- if (npcBot:GetActiveMode() == BOT_MODE_LANING) ~= ringOfBasilius:GetToggleState() then + -- ringOfBasilius:ToggleAutoCast() + -- end + --end + -- + --local buckler = IsItemAvailable("item_buckler") + --if buckler and buckler:IsFullyCastable() then + -- if (npcBot:GetActiveMode() == BOT_MODE_LANING) ~= buckler:GetToggleState() then + -- buckler:ToggleAutoCast() + -- end + --end -- give tango to ally local itg = IsItemAvailable("item_tango") @@ -423,17 +389,6 @@ function M.UnImplementedItemUsage() end end - --[[local its=IsItemAvailable("item_tango_single"); - if its~=nil and its:IsFullyCastable() and its:GetCooldownTimeRemaining() == 0 then - if DotaTime() > 10*60 and npcBot:DistanceFromFountain() > 1300 - then - local trees = npcBot:GetNearbyTrees(1300); - if trees[1] ~= nil then - npcBot:Action_UseAbilityOnTree(its, trees[1]); - return; - end - end - end]] local its = IsItemAvailable("item_tango_single") local tango if (its ~= nil) then @@ -457,16 +412,24 @@ function M.UnImplementedItemUsage() end end - if (DotaTime() > 7 * 60) then - for i = 0, 5 do - local sCurItem = npcBot:GetItemInSlot(i) - if (sCurItem ~= nil and (sCurItem:GetName() == "item_tango" or sCurItem:GetName() == "item_tango_single")) then - local trees = npcBot:GetNearbyTrees(1000) - if trees[1] ~= nil then - npcBot:Action_UseAbilityOnTree(sCurItem, trees[1]) - return + if (DotaTime() > 10 * 60) then + local emptySlots = AbilityExtensions:GetEmptyInventorySlots(npcBot) + if emptySlots < 2 then + for i = 0, 5 do + local tower = npcBot:GetNearbyTowers(1000, true)[1] + local sCurItem = npcBot:GetItemInSlot(i) + if (sCurItem ~= nil and (sCurItem:GetName() == "item_tango" or sCurItem:GetName() == "item_tango_single")) then + local trees = AbilityExtensions:Filter(npcBot:GetNearbyTrees(300), function(t) + if tower == nil then + return true + end + return GetUnitToLocationDistance(tower, GetTreeLocation(t)) > tower:GetAttackRange() + end) + if trees[1] ~= nil then + npcBot:Action_UseAbilityOnTree(sCurItem, trees[1]) + return + end end - --npcBot:Action_DropItem(sCurItem,npcBot:GetLocation()); end end end @@ -493,6 +456,15 @@ function M.UnImplementedItemUsage() end end + local itemQuellingBlade = IsItemAvailable("item_quelling_blade") or IsItemAvailable("item_bfury") + if itemQuellingBlade ~= nil and itemQuellingBlade:IsFullyCastable() then + local trees = npcBot:GetNearbyTrees(250) + if #trees >= 8 and AbilityExtensions:Contains(npcBot:GetNearbyHeroes(900, true, BOT_MODE_NONE), function(t) return t:GetUnitName() == "npc_dota_hero_furion" end) then + npcBot:Action_UseAbilityOnTree(itemQuellingBlade, trees[1]) + return + end + end + -- local irt = IsItemAvailable("item_iron_talon") -- if irt ~= nil and irt:IsFullyCastable() then -- if npcBot:GetActiveMode() == BOT_MODE_FARM then @@ -537,7 +509,7 @@ function M.UnImplementedItemUsage() end local ff = IsItemAvailable("item_faerie_fire") - if ff ~= nil and ff:IsFullyCastable() then + if ff ~= nil and ff:IsFullyCastable() and notBlasted then if npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH and (npcBot:GetHealth() / npcBot:GetMaxHealth()) < 0.15 and npcBot:WasRecentlyDamagedByAnyHero(3) @@ -548,7 +520,7 @@ function M.UnImplementedItemUsage() end local sr = IsItemAvailable("item_soul_ring") - if sr ~= nil and sr:IsFullyCastable() then + if sr ~= nil and sr:IsFullyCastable() and notBlasted then if (npcBot:GetActiveMode() == BOT_MODE_LANING or npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_TOP or npcBot:GetActiveMode() == BOT_MODE_PUSH_TOWER_MID or @@ -563,7 +535,7 @@ function M.UnImplementedItemUsage() end local bst = IsItemAvailable("item_bloodstone") - if bst ~= nil and bst:IsFullyCastable() then + if bst ~= nil and bst:IsFullyCastable() and notBlasted then if npcBot:GetActiveMode() == BOT_MODE_RETREAT and npcBot:GetActiveModeDesire() >= BOT_MODE_DESIRE_HIGH and (npcBot:GetHealth() / npcBot:GetMaxHealth()) < 0.2 @@ -580,7 +552,7 @@ function M.UnImplementedItemUsage() npcBot:GetActiveMode() == BOT_MODE_ROAM or npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or npcBot:GetActiveMode() == BOT_MODE_GANK or - npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY) + npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY) and not AbilityExtensions:IsSeverelyDisabled(npcBot) then npcBot:Action_UseAbility(pb) return @@ -605,15 +577,89 @@ function M.UnImplementedItemUsage() end end - local sc = IsItemAvailable("item_solar_crest") + local IsUsingArmlet = npcBot:HasModifier("modifier_item_armlet_unholy_health") + local itemArmlet = IsItemAvailable("item_armlet") + if itemArmlet then + if itemArmlet.lastOpenTime == nil and IsUsingArmlet then + itemArmlet.lastOpenTime = DotaTime() + return + end + if not IsUsingArmlet then + itemArmlet.lastOpenTime = nil + return + end + end + + if itemArmlet and itemArmlet:IsFullyCastable() and notBlasted then + if AbilityExtensions:IsFarmingOrPushing(npcBot) then + local target = npcBot:GetAttackTarget() + if target and target:IsAlive() and (AbilityExtensions:GetHealthPercent(npcBot) >= 0.45 or npcBot:GetHealth() <= 400 or npcBot:GetUnitName() == "npc_bot_hero_huskar" and npcBot:GetLevel() >= 7) then + if not IsUsingArmlet then + npcBot:Action_UseAbility(itemArmlet) + itemArmlet.lastOpenTime = DotaTime() + return + else + if npcBot:GetHealth() <= 250 and not npcBot:WasRecentlyDamagedByAnyHero(0.8) then + npcBot:Action_UseAbility(itemArmlet) + itemArmlet.lastOpenTime = DotaTime() + end + end + else + if IsUsingArmlet then + npcBot:Action_UseAbility(itemArmlet) + itemArmlet.lastOpenTime = nil + return + end + end + elseif AbilityExtensions:IsAttackingEnemies(npcBot) or AbilityExtensions:IsRetreating(npcBot) then + if not IsUsingArmlet then + if #npcBot:GetNearbyHeroes(1599, true, BOT_MODE_NONE) > 0 or npcBot:WasRecentlyDamagedByAnyHero(2.5) then + npcBot:Action_UseAbility(itemArmlet) + itemArmlet.lastOpenTime = DotaTime() + return + end + else + if npcBot:GetHealth() <= 300 then + local projectiles = npcBot:GetIncomingTrackingProjectiles() + if (#projectiles == 0 or AbilityExtensions:CannotBeKilledNormally(npcBot)) and DotaTime() - itemArmlet.lastOpenTime >= 0.6 then + npcBot:Action_UseAbility(itemArmlet) + npcBot:ActionQueue_UseAbility(itemArmlet) + itemArmlet.lastOpenTime = DotaTime() + return + end + end + end + end + end + + local sc = IsItemAvailable("item_solar_crest") or IsItemAvailable("item_medallion_of_courage") if sc ~= nil and sc:IsFullyCastable() then + if npcBot:GetActiveMode() == BOT_MODE_ROSHAN then + local target = npcBot:GetTarget() + if AbilityExtensions:IsRoshan(target) then + npcBot:Action_UseAbilityOnEntity(sc, target) + return + end + end + + local allies = AbilityExtensions:GetNearbyNonIllusionHeroes(npcBot) + allies = AbilityExtensions:Filter(allies, AbilityExtensions.PhysicalCanCastFunction) + allies = AbilityExtensions:Filter(allies, function(t) + return not t:HasModifier("modifier_item_medallion_of_courage_armor_addition") + end) + allies = AbilityExtensions:First(allies, function(t) return AbilityExtensions:IsSeverelyDisabledOrSlowed(t) end) + if allies then + npcBot:Action_UseAbilityOnEntity(sc, allies) + return + end + if (npcBot:GetActiveMode() == BOT_MODE_ATTACK or npcBot:GetActiveMode() == BOT_MODE_ROAM or npcBot:GetActiveMode() == BOT_MODE_TEAM_ROAM or npcBot:GetActiveMode() == BOT_MODE_GANK or npcBot:GetActiveMode() == BOT_MODE_DEFEND_ALLY) then - if (npcTarget ~= nil and npcTarget:IsHero() and GetUnitToUnitDistance(npcTarget, npcBot) < 900) then + if (npcTarget ~= nil and npcTarget:IsHero() and GetUnitToUnitDistance(npcTarget, npcBot) < 900) and not npcTarget:HasModifier("modifier_item_medallion_of_courage_armor_addition") and not npcTarget:HasModifier("modifier_item_medallion_of_courage_armor_reduction") then npcBot:Action_UseAbilityOnEntity(sc, npcTarget) return end @@ -628,11 +674,12 @@ function M.UnImplementedItemUsage() #tableNearbyEnemyHeroes > 0 and CanCastOnTarget(Ally)) or (IsDisabled(Ally) and CanCastOnTarget(Ally)) - then + then npcBot:Action_UseAbilityOnEntity(sc, Ally) return end end + end local se = IsItemAvailable("item_silver_edge") @@ -651,7 +698,7 @@ function M.UnImplementedItemUsage() then if (npcTarget ~= nil and npcTarget:IsHero() and GetUnitToUnitDistance(npcTarget, npcBot) > 1000 and - GetUnitToUnitDistance(npcTarget, npcBot) < 2500) + GetUnitToUnitDistance(npcTarget, npcBot) < 2500) and not IsLocationVisible(npcBot) then npcBot:Action_UseAbility(se) return @@ -721,6 +768,24 @@ function M.UnImplementedItemUsage() end end + local itemEtherealBlade = IsItemAvailable("item_ethereal_blade") + if itemEtherealBlade and itemEtherealBlade:IsFullyCastable() then + if npcTarget ~= nil and AbilityExtensions:NormalCanCast(npcTarget) then + npcBot:Action_UseAbilityOnEntity(itemEtherealBlade, npcBot) + return + end + end + + local itemDagon = AbilityExtensions:Aggregate(nil, AbilityExtensions:Range(1, 5), function(seed, dagonLevelIndex) + return seed or IsItemAvailable("item_dagon_"..dagonLevelIndex) + end) + if itemDagon and itemDagon:IsFullyCastable() then + if npcTarget ~= nil and AbilityExtensions:NormalCanCast(npcTarget) then + npcBot:Action_UseAbilityOnEntity(itemDagon, npcBot) + return + end + end + local glimer = IsItemAvailable("item_glimmer_cape") if glimer ~= nil and glimer:IsFullyCastable() then if @@ -734,7 +799,7 @@ function M.UnImplementedItemUsage() end end - local hod = IsItemAvailable("item_helm_of_the_dominator") + local hod = IsItemAvailable("item_helm_of_the_overlord") or IsItemAvailable("item_helm_of_the_dominator") if hod ~= nil and hod:IsFullyCastable() then local maxHP = 0 local NCreep = nil @@ -772,14 +837,15 @@ function M.UnImplementedItemUsage() end end + local function NotSuitableForGuardianGreaves(t) + return not t:HasModifier("modifier_ice_blast") and not t:HasModifier("modifier_item_mekansm_noheal") and not t:HasModifier("modifier_item:guardian_greaves_noheal") + end local guardian = IsItemAvailable("item_guardian_greaves") if guardian ~= nil and guardian:IsFullyCastable() then - local Allies = npcBot:GetNearbyHeroes(1000, false, BOT_MODE_NONE) - for _, Ally in pairs(Allies) do - if - Ally:GetHealth() / Ally:GetMaxHealth() < 0.35 and tableNearbyEnemyHeroes ~= nil and - #tableNearbyEnemyHeroes > 0 - then + local allys = npcBot:GetNearbyHeroes(1000, false, BOT_MODE_NONE) + allys = AbilityExtensions:Filter(allys, NotSuitableForGuardianGreaves) + for _, ally in pairs(allys) do + if ally:GetHealth() / ally:GetMaxHealth() < 0.35 and tableNearbyEnemyHeroes ~= nil and #tableNearbyEnemyHeroes > 0 then npcBot:Action_UseAbility(guardian) return end @@ -787,12 +853,12 @@ function M.UnImplementedItemUsage() end local satanic = IsItemAvailable("item_satanic") - if satanic ~= nil and satanic:IsFullyCastable() then + if satanic ~= nil and satanic:IsFullyCastable() and notBlasted then if npcBot:GetHealth() / npcBot:GetMaxHealth() < 0.50 and tableNearbyEnemyHeroes ~= nil and #tableNearbyEnemyHeroes > 0 and npcBot:GetActiveMode() == BOT_MODE_ATTACK - then + then npcBot:Action_UseAbility(satanic) return end @@ -801,6 +867,7 @@ function M.UnImplementedItemUsage() local ggr = IsItemAvailable("item_guardian_greaves") if ggr ~= nil and ggr:IsFullyCastable() then local allys = npcBot:GetNearbyHeroes(900, false, BOT_MODE_NONE) + allys = AbilityExtensions:Filter(allys, NotSuitableForGuardianGreaves) local factor = 0 for k, v in pairs(allys) do @@ -831,16 +898,16 @@ function M.UnImplementedItemUsage() return; end end]] - local stick = IsItemAvailable("item_flask") - if stick ~= nil and stick:IsFullyCastable() then + local stick = IsItemAvailable("item_magic_stick") + if stick ~= nil and stick:IsFullyCastable() and stick:GetCurrentCharges() > 0 and notBlasted then if DotaTime() > 0 then local tableNearbyEnemyHeroes = npcBot:GetNearbyHeroes(500, true, BOT_MODE_NONE) if ((npcBot:GetHealth() / npcBot:GetMaxHealth() < 0.4 or npcBot:GetMana() / npcBot:GetMaxMana() < 0.2) and #tableNearbyEnemyHeroes >= 1 and - GetItemCharges(npcBot, "item_flask") >= 1) or + GetItemCharges(npcBot, "item_magic_stick") >= 1) or ((npcBot:GetHealth() / npcBot:GetMaxHealth() < 0.7 and npcBot:GetMana() / npcBot:GetMaxMana() < 0.7) and - GetItemCharges(npcBot, "item_flask") >= 7) + GetItemCharges(npcBot, "item_magic_stick") >= 7) then npcBot:Action_UseAbility(stick) return @@ -849,7 +916,7 @@ function M.UnImplementedItemUsage() end local wand = IsItemAvailable("item_magic_wand") - if wand ~= nil and wand:IsFullyCastable() then + if wand ~= nil and wand:IsFullyCastable() and wand:GetCurrentCharges() > 0 and notBlasted then if DotaTime() > 0 then local tableNearbyEnemyHeroes = npcBot:GetNearbyHeroes(500, true, BOT_MODE_NONE) if @@ -866,7 +933,7 @@ function M.UnImplementedItemUsage() end local holyLocket = IsItemAvailable("item_holy_locket") - if holyLocket ~= nil and holyLocket:IsFullyCastable() then + if holyLocket ~= nil and holyLocket:IsFullyCastable() and notBlasted then if DotaTime() > 0 then local tableNearbyEnemyHeroes = npcBot:GetNearbyHeroes(500, true, BOT_MODE_NONE) if @@ -876,14 +943,14 @@ function M.UnImplementedItemUsage() ((npcBot:GetHealth() / npcBot:GetMaxHealth() < 0.7 and npcBot:GetMana() / npcBot:GetMaxMana() < 0.7) and GetItemCharges(npcBot, "item_holy_locket") >= 12) then - npcBot:Action_UseAbility(wand, npcBot) + npcBot:Action_UseAbilityOnEntity(wand, npcBot) return end end end local bottle = IsItemAvailable("item_bottle") - if bottle ~= nil and bottle:IsFullyCastable() then + if bottle ~= nil and bottle:IsFullyCastable() and notBlasted then local tableNearbyEnemyHeroes = npcBot:GetNearbyHeroes(650, true, BOT_MODE_NONE) if GetItemCharges(npcBot, "item_bottle") > 0 and not npcBot:HasModifier("modifier_bottle_regeneration") then if @@ -898,11 +965,10 @@ function M.UnImplementedItemUsage() end end - local cyclone = IsItemAvailable("item_cyclone") + local cyclone = IsItemAvailable("item_cyclone") or IsItemAvailable("item_wind_waker") if cyclone ~= nil and cyclone:IsFullyCastable() then if - npcTarget ~= nil and npcTarget:IsChanneling() or - (npcTarget:HasModifier("modifier_teleporting") or AbilityExtensions:CannotKillNormally(npcTarget)) and + npcTarget ~= nil and (npcTarget:IsChanneling() and not AbilityExtensions:IsOrGoingToBeSeverelyDisabled(npcTarget) or AbilityExtensions:CannotBeKilledNormally(npcTarget)) and CanCastOnTarget(npcTarget) and GetUnitToUnitDistance(npcBot, npcTarget) < 775 then @@ -911,18 +977,6 @@ function M.UnImplementedItemUsage() end end - local windWaker = IsItemAvailable("item_wind_waker") - if windWaker ~= nil and windWaker:IsFullyCastable() then - if npcTarget and npcTarget:IsChanneling() - or (npcTarget:HasModifier("modifier_teleporting") or AbilityExtensions:CannotKillNormally(npcTarget)) and - CanCastOnTarget(npcTarget) and - GetUnitToUnitDistance(npcBot, npcTarget) < 775 - then - npcBot:Action_UseAbilityOnEntity(windWaker, npcTarget) - return - end - end - local metham = IsItemAvailable("item_meteor_hammer") if metham ~= nil and metham:IsFullyCastable() then local tableNearbyAttackingAlliedHeroes = npcBot:GetNearbyHeroes(1000, false, BOT_MODE_ATTACK) @@ -968,7 +1022,8 @@ function M.UnImplementedItemUsage() npcTarget ~= nil and npcTarget:IsHero() and AbilityExtensions:MayNotBeIllusion(npcBot, npcTarget) and CanCastOnTarget(npcTarget) and GetUnitToUnitDistance(npcBot, npcTarget) < 900 and npcTarget:HasModifier("modifier_item_spirit_vessel_damage") == false and - npcTarget:GetHealth() / npcTarget:GetMaxHealth() < 0.65 + npcTarget:GetHealth() / npcTarget:GetMaxHealth() < 0.65 and + not npcTarget:HasModifier("modifier_ice_blast") then npcBot:Action_UseAbilityOnEntity(sv, npcTarget) return @@ -980,7 +1035,8 @@ function M.UnImplementedItemUsage() not Ally:IsIllusion() and Ally:HasModifier("modifier_item_spirit_vessel_heal") == false and CanCastOnTarget(Ally) and Ally:GetHealth() / Ally:GetMaxHealth() < 0.35 and #tableNearbyEnemyHeroes == 0 and - Ally:WasRecentlyDamagedByAnyHero(2.5) == false + Ally:WasRecentlyDamagedByAnyHero(2.5) == false and + not Ally:HasModifier("modifier_ice_blast") then npcBot:Action_UseAbilityOnEntity(sv, Ally) return diff --git a/util/NewMinionUtil.lua b/util/NewMinionUtil.lua index 32511b1d..05bc6ea3 100644 --- a/util/NewMinionUtil.lua +++ b/util/NewMinionUtil.lua @@ -39,12 +39,6 @@ function IsHawk(unit_name) or unit_name == "npc_dota_beastmaster_hawk_4"; end -function HawkThink(minion) - if CantMove(minion) then return end - minion:Action_MoveToLocation(bot:GetLocation()); - return -end - function IsTornado(unit_name) return unit_name == "npc_dota_enraged_wildkin_tornado"; end @@ -333,7 +327,7 @@ function CantBeControlled(unit_name) or unit_name == "npc_dota_phoenix_sun" or unit_name == "npc_dota_techies_minefield_sign" or unit_name == "npc_dota_treant_eyes" - or unit_name == "dota_death_prophet_exorcism_spirit" + or unit_name == "npc_dota_death_prophet_exorcism_spirit" or unit_name == "npc_dota_dark_willow_creature"; end @@ -445,7 +439,7 @@ function CastThink(minion, ability) if CheckFlag(ability:GetBehavior(), ABILITY_BEHAVIOR_UNIT_TARGET) then if ability:GetName() == "ogre_magi_frost_armor" then local castRange = ability:GetCastRange(); - local allies = GetNearbyHeroes(castRange+200, false, BOT_MODE_NONE); + local allies = minion:GetNearbyHeroes(castRange+200, false, BOT_MODE_NONE); if #allies > 0 then for i=1, #allies do if IsValidTarget(allies[i]) and CanCastOnTarget(allies[i], ability) diff --git a/util/PushUtility.lua b/util/PushUtility.lua index 5191680a..e57aab5d 100644 --- a/util/PushUtility.lua +++ b/util/PushUtility.lua @@ -124,7 +124,7 @@ function GetUnitPushLaneDesire(npcBot,lane) return desire end -function isNocreeps(npcBot,lane) --判断兵线位置在不在塔前,不要越塔 +function isNoCreeps(npcBot,lane) --判断兵线位置在不在塔前,不要越塔 local front = GetLaneFrontLocation( GetTeam(), lane, 0 ) local AllyTower = GetNearestBuilding(GetTeam(), front) local EnemyTower = GetNearestBuilding(GetOpposingTeam(), front) @@ -170,10 +170,10 @@ function getTargetLocation(npcBot,lane) end -function IsCreepAttackTower(creepsNearyTower,EnemyTower) - if(creepsNearyTower~=nil and #creepsNearyTower>=1) +function IsCreepAttackTower(creepsNearTower,EnemyTower) + if(creepsNearTower~=nil and #creepsNearTower>=1) then - for k,v in pairs(creepsNearyTower) + for k,v in pairs(creepsNearTower) do if(v:GetAttackTarget()==EnemyTower) then @@ -184,7 +184,7 @@ function IsCreepAttackTower(creepsNearyTower,EnemyTower) return false; end -function IsSafe(npcBot,lane,creepsNearyTower) +function IsSafe(npcBot,lane,creepsNearTower) local front = GetLaneFrontLocation( GetTeam(), lane, 0 ) local EnemyTower = GetNearestBuilding(GetOpposingTeam(), front) @@ -204,9 +204,9 @@ function IsSafe(npcBot,lane,creepsNearyTower) end local CreepMinDistance=99999 - if(creepsNearyTower~=nil and #creepsNearyTower>=2) + if(creepsNearTower~=nil and #creepsNearTower>=2) then - for k,v in pairs(creepsNearyTower) + for k,v in pairs(creepsNearTower) do local tempDistance=GetUnitToUnitDistance(v,EnemyTower) if(tempDistance 4000 then if travel then npcBot:Action_UseAbilityOnLocation( travel, front ) @@ -253,11 +250,11 @@ function tryTP( npcBot,lane ) return false; end -function getCreepsNearTower(npcBot,tower) +local function getCreepsNearTower(npcBot,tower) local creeps = {} for k,v in pairs(npcBot:GetNearbyCreeps(1600,false)) do - if(GetUnitToUnitDistance(v,EnemyTower)<800) + if(GetUnitToUnitDistance(v, tower)<800) then table.insert(creeps,v) end @@ -265,7 +262,7 @@ function getCreepsNearTower(npcBot,tower) return creeps end -function getMyTarget(npcBot,lane,TargetLocation) +local function getMyTarget(npcBot,lane,TargetLocation) local team = GetTeam() local front = GetLaneFrontLocation( team, lane, 0 ) local EnemyTower = GetNearestBuilding(GetOpposingTeam(), front) @@ -298,16 +295,16 @@ function UnitPushLaneThink(npcBot,lane) local EnemyTower = GetNearestBuilding(GetOpposingTeam(), front) local TowerDistance = GetUnitToUnitDistance(npcBot,EnemyTower) - local creepsNearyTower = getCreepsNearTower(npcBot,EnemyTower); - local TargetLocation = getTargetLocation(npcBot,lane) --Scatter station to avoid AOE - local CreepAttackTower = IsCreepAttackTower(creepsNearyTower,EnemyTower) - local Safe = IsSafe(npcBot,lane,creepsNearyTower); - local Nocreeps=isNocreeps(npcBot,lane) + local creepsNearTower = getCreepsNearTower(npcBot,EnemyTower); + local TargetLocation = getTargetLocation(npcBot,lane) --Scatter positions to avoid AOE + local CreepAttackTower = IsCreepAttackTower(creepsNearTower,EnemyTower) + local Safe = IsSafe(npcBot,lane,creepsNearTower); + local noCreeps=isNoCreeps(npcBot,lane) - --print(getShortName(npcBot).."\tCreepAttackTower: "..tostring(CreepAttackTower).." Safe:"..tostring(Safe).." NoCreeps:"..tostring(Nocreeps)) + --print(getShortName(npcBot).."\tCreepAttackTower: "..tostring(CreepAttackTower).." Safe:"..tostring(Safe).." noCreeps:"..tostring(noCreeps)) - local enemys = npcBot:GetNearbyHeroes(1000,true,BOT_MODE_NONE) + local enemys = npcBot:GetNearbyHeroes(1200,true,BOT_MODE_NONE) local target=getMyTarget(npcBot,lane,TargetLocation) @@ -318,10 +315,10 @@ function UnitPushLaneThink(npcBot,lane) local goodSituation=true; - if(npcBot:GetLevel()>=12 and npcBot:GetHealth()>=1500) + if (npcBot:GetLevel()>=12 and npcBot:GetHealth()>=1500 or npcBot:GetHealth() >= 700 and #enemys == 0) then goodSituation=true; - elseif ((Safe==false or Nocreeps==true) and EnemyTower:GetHealth()/EnemyTower:GetMaxHealth()>=0.2) + elseif ((Safe==false or noCreeps==true) and EnemyTower:GetHealth()/EnemyTower:GetMaxHealth()>=0.2) then goodSituation=false; end @@ -329,13 +326,13 @@ function UnitPushLaneThink(npcBot,lane) local MinDelta=200 if(IsEnemyTooMany()) then - AssmbleWithAlly(npcBot) + AssembleWithAlly(npcBot) elseif goodSituation==false then StepBack( npcBot ) --print(getCurrentFileName().." "..getShortName(npcBot).." situation is not good"); elseif npcBot:WasRecentlyDamagedByTower(1) then --if I'm under attck of tower, then try to avoid attack if not TransferHatred( npcBot ) or (enemys~=nil and #enemys>=1) or AbilityExtensions:Any(npcBot:GetNearbyTowers(700, true), function(t) - return t:GetAttackTarget() == npcBot and t:HasModifier("modifier_fountain_glyph") + t:HasModifier("modifier_fountain_glyph") end) then StepBack( npcBot ) @@ -609,7 +606,7 @@ function TransferHatred( unit ) return false end -function AssmbleWithAlly(unit) +function AssembleWithAlly(unit) if not NotNilOrDead(unit) then return end @@ -681,7 +678,7 @@ function StepBackCreeps(unit) end end else - local g = GetUnitToUnitDistance(tower, friendCreeps[1]) + 10 + local g = GetUnitToUnitDistance(tower, friendCreeps[1]) + unit:GetBoundingRadius() unit:Action_MoveDirectly(AbilityExtensions:GetPointFromLineByDistance(tower:GetLocation(), unit:GetLocation(), g)) coroutine.yield(g) TransferHatred(unit) @@ -718,7 +715,7 @@ function IsEnemyTooMany() for _,enemy in pairs(enemies) do local Lane=GetLane(GetTeam(),enemy) - if NotNilOrDead(enemy) and GetUnitToUnitDistance(npcBot,ally)<3000 and MyLane==Lane then + if NotNilOrDead(enemy) and GetUnitToUnitDistance(npcBot,enemy)<3000 and MyLane==Lane then EnemyCount=EnemyCount+1 end end @@ -747,8 +744,8 @@ function strippath(filename) end -EnemyHeroListTimer=-1000; -EnemyHeroList=nil; +local EnemyHeroListTimer=-1000; +local EnemyHeroList=nil; function GetRealHero(Candidates) if Candidates==nil or #Candidates==0 then @@ -780,7 +777,7 @@ function GetRealHero(Candidates) for i,unit in pairs(Candidates) do local int = unit:GetAttributeValue(2); local baseRegen=0.01; - if unit:GetUnitName()==npc_dota_hero_techies then + if unit:GetUnitName()=="npc_dota_hero_techies" then baseRegen=0.02; end diff --git a/util/RoleUtility.lua b/util/RoleUtility.lua index f2dce397..d8df84d7 100644 --- a/util/RoleUtility.lua +++ b/util/RoleUtility.lua @@ -1456,7 +1456,6 @@ X["phase_boots"] = { ["npc_dota_hero_spectre"] = 1, ["npc_dota_hero_tiny"] = 1, ["npc_dota_hero_troll_warlord"] = 1, - ["npc_dota_hero_alchemist"] = 1, ["npc_dota_hero_life_stealer"] = 1, ["npc_dota_hero_monkey_king"] = 1, ["npc_dota_hero_ember_spirit"] = 1, diff --git a/utility.lua b/utility.lua index 1171302c..1dd453af 100644 --- a/utility.lua +++ b/utility.lua @@ -15,7 +15,7 @@ function utilityModule.HasImmuneDebuff(npcEnemy) end function utilityModule.NCanCast( npcEnemy )--normal judgement - return npcEnemy:CanBeSeen() and not npcEnemy:IsMagicImmune() and not npcEnemy:IsInvulnerable() and not utilityModule.HasImmuneDebuff(npcEnemy) and not npcEnemy:IsIllusion() + return npcEnemy:CanBeSeen() and not npcEnemy:IsMagicImmune() and not npcEnemy:IsInvulnerable() and not utilityModule.HasImmuneDebuff(npcEnemy) end function utilityModule.MiCanCast( npcEnemy )--magic immune @@ -23,7 +23,7 @@ function utilityModule.MiCanCast( npcEnemy )--magic immune end function utilityModule.UCanCast( npcEnemy )--magic immune - return npcEnemy:CanBeSeen() and not npcEnemy:IsInvulnerable() and not utilityModule.HasImmuneDebuff(npcEnemy) and not npcEnemy:IsIllusion() and not npcEnemy:HasModifier("modifier_item_sphere") and not npcEnemy:HasModifier("modifier_item_sphere_target") + return npcEnemy:CanBeSeen() and not npcEnemy:IsInvulnerable() and not utilityModule.HasImmuneDebuff(npcEnemy) and not npcEnemy:IsIllusion() end function utilityModule.CanCastNoTarget()