Kain2030

Auto Carry Plugin - Twitch - v1.0e

Sep 3rd, 2013
2,323
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 15.89 KB | None | 0 0
  1. --[[
  2.  
  3.         Auto Carry Plugin - Twitch Edition
  4.         Author: Kain
  5.         Copyright 2013
  6.  
  7.         Dependency: Sida's Auto Carry
  8.  
  9.         How to install:
  10.             Make sure you already have AutoCarry installed.
  11.             Name the script EXACTLY "SidasAutoCarryPlugin - Twitch.lua" without the quotes.
  12.             Place the plugin in BoL/Scripts/Common folder.
  13.  
  14.         Version History:
  15.             Version: 1.0e: http://pastebin.com/rnB5tVTF
  16.                 Combo
  17.                 Spray and Pray Multi-shot
  18.                 AoE MEC Venom Cask
  19.                 Expunge Runner
  20.                 Expunge at Max Damage
  21.                 Expunge Killsteal
  22. --]]
  23.  
  24. local version = "1.0e"
  25.  
  26. AutoCarry.PluginMenu:addParam("sep", "----- Twitch by Kain: v"..version.." -----", SCRIPT_PARAM_INFO, "")
  27. AutoCarry.PluginMenu:addParam("sep", "----- [ Expunge ] -----", SCRIPT_PARAM_INFO, "")
  28. AutoCarry.PluginMenu:addParam("UseE", "Auto Expunge", SCRIPT_PARAM_ONOFF, true)
  29. AutoCarry.PluginMenu:addParam("ExpungeAt6", "Expunge at 6 Stacks", SCRIPT_PARAM_ONOFF, true)
  30. AutoCarry.PluginMenu:addParam("ExpungeMaxDamage", "Expunge at Max Damage", SCRIPT_PARAM_ONOFF, true)
  31. AutoCarry.PluginMenu:addParam("ExpungeRunner", "Expunge Runner", SCRIPT_PARAM_ONOFF, true)
  32. AutoCarry.PluginMenu:addParam("KillSteal", "Expunge for Kills", SCRIPT_PARAM_ONOFF, true)
  33. AutoCarry.PluginMenu:addParam("sep", "----- [ Misc ] -----", SCRIPT_PARAM_INFO, "")
  34. AutoCarry.PluginMenu:addParam("UseW", "Auto Venom Cask", SCRIPT_PARAM_ONOFF, true)
  35. AutoCarry.PluginMenu:addParam("UseWMEC", "Auto MEC for Venom Cask", SCRIPT_PARAM_ONOFF, true)
  36. if VIP_USER then
  37.     AutoCarry.PluginMenu:addParam("AutoUlt", "Auto Ultimate in good situations", SCRIPT_PARAM_ONOFF, true)
  38.     AutoCarry.PluginMenu:addParam("MinUltEnemies", "Min. R Enemies",SCRIPT_PARAM_SLICE, 3, 1, 5, 0)
  39. end
  40. AutoCarry.PluginMenu:addParam("sep", "----- [ Draw ] -----", SCRIPT_PARAM_INFO, "")
  41. AutoCarry.PluginMenu:addParam("Draw", "Draw Poison Circles", SCRIPT_PARAM_ONOFF, true)
  42. AutoCarry.PluginMenu:addParam("DisableDraw", "Disable Draw", SCRIPT_PARAM_ONOFF, false)
  43. AutoCarry.PluginMenu:addParam("DrawFurthest", "Draw Furthest Spell Available", SCRIPT_PARAM_ONOFF, true)
  44. AutoCarry.PluginMenu:addParam("DrawW", "Draw Venom Cask", SCRIPT_PARAM_ONOFF, true)
  45. AutoCarry.PluginMenu:addParam("DrawE", "Draw Expunge", SCRIPT_PARAM_ONOFF, true)
  46. AutoCarry.PluginMenu:addParam("DrawR", "Draw Spray and Pray", SCRIPT_PARAM_ONOFF, true)
  47.  
  48. local WRange, WSpeed, WDelay, WWidth = 950, 1.4, 250, 275
  49. local WRadius = WWidth / 2
  50. local ERange = 1200
  51. local RRange, RSpeed, RDelay, RWidth = 850, 1.0, 200, 250
  52.  
  53. local SkillW = { spellKey = _W, range = WRange, speed = WSpeed, delay = WDelay, width = WWidth, configName = "venomCask", displayName = "W (Venom Cask)", enabled = false, skillShot = true, minions = false, reset = false, reqTarget = true }
  54. local SkillR = { spellKey = _R, range = RRange, speed = RSpeed, delay = RDelay, width = RWidth, configName = "sprayandpray", displayName = "R (Spray and Pray)", enabled = true, skillShot = false, minions = false, reset = false, reqTarget = true }
  55.  
  56. local QReady, WReady, EReady, RReady = false, false, false, false
  57.  
  58. local Target = nil
  59.  
  60. -- Direction
  61. local enemyLastDistance = {}
  62. local direction_towards = 1
  63. local direction_away = 2
  64.  
  65. local debugMode = false
  66.  
  67. function PluginOnLoad()
  68.     for _, enemy in pairs(AutoCarry.EnemyTable) do
  69.         enemy.PoisonStacks = 0
  70.         enemy.LastPoison = 0
  71.         enemyLastDistance[enemy.networkID] = 0
  72.     end
  73. end
  74.  
  75. function SpellCheck()
  76.     QReady = (myHero:CanUseSpell(_Q) == READY)
  77.     WReady = (myHero:CanUseSpell(SkillW.spellKey) == READY)
  78.     EReady = (myHero:CanUseSpell(_E) == READY)
  79.     RReady = (myHero:CanUseSpell(SkillR.spellKey) == READY)
  80. end
  81.  
  82. function PluginOnTick()
  83.     -- Disable SAC Reborn's auto W. AoE MEC W is much better!
  84.     if AutoCarry.Skills then
  85.         AutoCarry.Skills:GetSkill(_W).Enabled = false
  86.     end
  87.  
  88.     Target = AutoCarry.GetAttackTarget(true)
  89.  
  90.     SpellCheck()
  91.  
  92.     if AutoCarry.PluginMenu.UseW then
  93.         VenomCask()
  94.     end
  95.  
  96.     if AutoCarry.PluginMenu.UseE then
  97.         Expunge()
  98.     end
  99.  
  100.     if VIP_USER and AutoCarry.PluginMenu.AutoUlt then
  101.         CastR()
  102.     end
  103. end
  104.  
  105. function VenomCask()
  106.     if not WReady or not Target or Target.dead then return false end
  107.  
  108.     -- for _, enemy in pairs(AutoCarry.EnemyTable) do
  109.     --  if enemy and not enemy.dead and ValidTarget(enemy, WRange) then
  110.     --      enemyCount = enemyCount + 1
  111.     --  end
  112.     -- end
  113.  
  114.     if AutoCarry.PluginMenu.UseWMEC and EnemyCount(myHero, WRange) >= 2 then
  115.         local spellPos = GetAoESpellPosition(WRadius, Target, WDelay)
  116.         if spellPos and GetDistance(spellPos) <= WRange then
  117.             if EnemyCount(spellPos, WRadius) >= 2 then
  118.                 if debugMode then PrintChat("venomcask mec") end
  119.                 CastSpell(SkillW.spellKey, spellPos.x, spellPos.z)
  120.                 return true
  121.             end
  122.         end
  123.     elseif IsEnemyHealthLow(Target) and GetDistance(Target) <= WRange then
  124.         if debugMode then PrintChat("venomcask normal") end
  125.         AutoCarry.CastSkillshot(SkillW, Target)
  126.         return true
  127.     end
  128.  
  129.     return false
  130. end
  131.  
  132. function Expunge()
  133.     local expungeTarget = nil
  134.     local maxPoisonStacks = 0
  135.     local enemyCount = 0
  136.  
  137.     for _, enemy in pairs(AutoCarry.EnemyTable) do
  138.         if enemy and enemy.PoisonStacks and enemy.PoisonStacks > 0 and ValidTarget(enemy, ERange) then
  139.             enemyCount = enemyCount + 1
  140.             if enemy.PoisonStacks > maxPoisonStacks then
  141.                 expungeTarget = enemy.charName
  142.                 maxPoisonStacks = enemy.PoisonStacks
  143.             end
  144.         end
  145.     end
  146.  
  147.     for _, enemy in pairs(AutoCarry.EnemyTable) do
  148.         if not enemy.PoisonStacks or (enemy.PoisonStacks > 0 and GetTickCount() > enemy.LastPoison + 6500) then
  149.             enemy.PoisonStacks = 0
  150.         elseif enemy.PoisonStacks > 0 and ValidTarget(enemy, ERange) then
  151.             local isMaxDamage, trueDamage = GetExpungeDamage(enemy)
  152.             local enemyDirection = EnemyDirection(enemy)
  153.  
  154.             if (AutoCarry.PluginMenu.ExpungeAt6 and enemy.PoisonStacks == 6)
  155.                 or (AutoCarry.PluginMenu.KillSteal and enemy.health < trueDamage)
  156.                 or (AutoCarry.PluginMenu.ExpungeMaxDamage and isMaxDamage)
  157.                 or (AutoCarry.PluginMenu.ExpungeRunner and enemyDirection and enemyDirection == direction_away and enemyCount <= 3
  158.                     and maxPoisonStacks >= 3 and enemy.charName == expungeTarget and GetDistance(enemy) > WRange) then
  159.                 CastSpell(_E)
  160.                 break
  161.             end
  162.         end
  163.     end
  164. end
  165.  
  166. function EnemyCount(point, range)
  167.     local count = 0
  168.  
  169.     for _, enemy in pairs(AutoCarry.EnemyTable) do
  170.         if enemy and not enemy.dead and GetDistance(point, enemy) <= range then
  171.             count = count + 1
  172.         end
  173.     end            
  174.  
  175.     return count
  176. end
  177.  
  178. -- Enemy Direction
  179.  
  180. function GetEnemyLastDistance(enemy)
  181.     if enemy and not enemy.dead then
  182.         return enemyLastDistance[enemy.networkID]
  183.     end
  184.  
  185.     return false
  186. end
  187.  
  188. function UpdateEnemyDistance(enemy)
  189.     if enemy and not enemy.dead then
  190.         enemyLastDistance[enemy.networkID] = GetDistance(enemy)
  191.     end
  192. end
  193.  
  194. function EnemyDirection(enemy)
  195.     if enemy and not enemy.dead then
  196.         local lastDistance = GetEnemyLastDistance(enemy)
  197.         local currentDistance = GetDistance(enemy)
  198.  
  199.         if currentDistance then
  200.             UpdateEnemyDistance(enemy)
  201.         end
  202.  
  203.         if currentDistance < lastDistance then
  204.             return direction_towards
  205.         elseif currentDistance > lastDistance then
  206.             return direction_away
  207.         end
  208.     end
  209.  
  210.     return false
  211. end
  212.  
  213. function PluginOnCreateObj(obj)
  214.     if obj and obj.valid and obj.name:lower():find("twitch_poison_counter") then
  215.         for _, enemy in pairs(AutoCarry.EnemyTable) do
  216.             if GetDistance(enemy, obj) <= 80 then
  217.                 enemy.PoisonStacks = GetStacks(obj.name)
  218.                 enemy.LastPoison = GetTickCount()
  219.             end
  220.         end
  221.     end
  222. end
  223.  
  224. -- Draw
  225.  
  226. function PluginOnDraw()
  227.     if AutoCarry.PluginMenu.Draw then
  228.         for i, enemy in pairs(AutoCarry.EnemyTable) do
  229.             if ValidTarget(enemy, ERange) then
  230.                 if enemy.PoisonStacks > 0 then DrawCircle(enemy.x, enemy.y, enemy.z, (60+(20 * enemy.PoisonStacks)), 0xFFFFFF) end
  231.             end
  232.         end
  233.     end
  234.  
  235.     if not AutoCarry.PluginMenu.DisableDraw and not myHero.dead then
  236.         local farSpell = FindFurthestReadySpell()
  237.  
  238.         if AutoCarry.PluginMenu.DrawW and WReady and ((AutoCarry.PluginMenu.DrawFurthest and farSpell and farSpell == WRange) or not AutoCarry.PluginMenu.DrawFurthest) then
  239.             DrawCircle(myHero.x, myHero.y, myHero.z, WRange, 0xFFFF00) -- Yellow
  240.         end
  241.        
  242.         if AutoCarry.PluginMenu.DrawE and EReady and ((AutoCarry.PluginMenu.DrawFurthest and farSpell and farSpell == ERange) or not AutoCarry.PluginMenu.DrawFurthest) then
  243.             DrawCircle(myHero.x, myHero.y, myHero.z, ERange, 0x00FF00) -- Green
  244.         end
  245.  
  246.         if AutoCarry.PluginMenu.DrawR and RReady and ((AutoCarry.PluginMenu.DrawFurthest and farSpell and farSpell == RRange) or not AutoCarry.PluginMenu.DrawFurthest) then
  247.             DrawCircle(myHero.x, myHero.y, myHero.z, RRange, 0xFF0000) -- Red
  248.         end
  249.  
  250.         Target = AutoCarry.GetAttackTarget()
  251.         if Target ~= nil then
  252.             for j=0, 10 do
  253.                 DrawCircle(Target.x, Target.y, Target.z, 40 + j*1.5, 0x00FF00) -- Green
  254.             end
  255.         end
  256.     end
  257. end
  258.  
  259. function FindFurthestReadySpell()
  260.     local farSpell = nil
  261.  
  262.     if AutoCarry.PluginMenu.DrawW and WReady then farSpell = WRange end
  263.     if AutoCarry.PluginMenu.DrawE and EReady and (not farSpell or ERange > farSpell) then farSpell = ERange end
  264.     if AutoCarry.PluginMenu.DrawR and RReady and (not farSpell or RRange > farSpell) then farSpell = RRange end
  265.  
  266.     return farSpell
  267. end
  268.  
  269. function GetExpungeDamage(enemy)
  270.     local baseDamage = GetSpellData(_E).level > 0 and (GetSpellData(_E).level * 15) + 5 or 0
  271.     local stackDamage = enemy.PoisonStacks > 0 and (enemy.PoisonStacks * 5) + 10 + (myHero.ap * (0.2 * enemy.PoisonStacks)) + (myHero.addDamage * (0.25 * enemy.PoisonStacks)) or 0
  272.     local totalDamage = baseDamage+stackDamage
  273.     local maxDamage = GetExpungeMaxDamage()
  274.  
  275.     local isMaxDamage = false
  276.  
  277.     if totalDamage > maxDamage then
  278.         totalDamage = maxDamage
  279.         isMaxDamage = true
  280.     end
  281.  
  282.     local trueDamage = totalDamage * (100 / (100 + enemy.armor))
  283.  
  284.     return isMaxDamage, trueDamage
  285. end
  286.  
  287. function GetExpungeMaxDamage()
  288.     return 65 + (GetSpellData(_E).level * 45) + (myHero.ap * 0.2) + (myHero.addDamage * 0.25)
  289. end
  290.  
  291. function GetStacks(str)
  292.     -- Format: twitch_poison_counter_0[1-6].troy
  293.     for i = 1, 6 do
  294.         if str:lower():find("twitch_poison_counter_0"..i..".troy") then return i end
  295.     end
  296.  
  297.     return 0
  298. end
  299.  
  300. function CastR(enemy)
  301.     if not enemy then enemy = Target end
  302.  
  303.     if not AutoCarry.PluginMenu.AutoUlt or not VIP_USER or not enemy or enemy.dead or not RReady or enemy.type ~= myHero.type or not ValidTarget(enemy, RRange) then return false end
  304.  
  305.     local distance = GetDistance(enemy)
  306.  
  307.     local enemyCount = 0
  308.    
  309.     for _, enemy in pairs(AutoCarry.EnemyTable) do
  310.         if ValidTarget(enemy, RRange) then
  311.             enemyCount = enemyCount + 1
  312.         end
  313.     end
  314.  
  315.     if enemyCount < 2 then return false end
  316.  
  317.     local tpR = VIP_USER and TargetPredictionVIP(range, SkillR.speed*1000, 0, SkillR.width) or TargetPrediction(range, SkillR.speed, 0, SkillR.width)
  318.  
  319.     local hitCount, hitEnemy = 0, nil
  320.     local predPos = nil
  321.  
  322.     if tpR then
  323.         predPos = tpR:GetPrediction(enemy)
  324.     end
  325.  
  326.     -- Find multishot possibilities.
  327.     hitCount, hitEnemy = FindRMultishot(enemy, predPos)
  328.  
  329.     local lowHealthHitCount = 0
  330.     if hitEnemy and hitCount > 0 then
  331.         for _, enemy in pairs(hitEnemy) do
  332.             if IsEnemyHealthLow(enemy) then
  333.                 lowHealthHitCount = lowHealthHitCount + 1
  334.             end
  335.         end
  336.  
  337.         -- Fire if we can hit at least three enemies in a line or at least two where one is almost dead already.
  338.         if (AutoCarry.PluginMenu.MinUltEnemies and hitCount >= AutoCarry.PluginMenu.MinUltEnemies) or (hitCount >= 2 and lowHealthHitCount >= 1) then
  339.             if debugMode then PrintChat("Ultimate") end
  340.             CastSpell(_R)
  341.             return true
  342.         end
  343.     end
  344.  
  345.     return false
  346. end
  347.  
  348. function FindRMultishot(enemy, predPos)
  349.     local hitCount = 0
  350.     local hitEnemy = {}
  351.  
  352.     if not RReady or not enemy or enemy.dead or not predPos then return hitCount, hitEnemy end
  353.  
  354.     local h, heroes = false, nil
  355.  
  356.     if VIP_USER then
  357.         h, heroes = GetHeroCollision(SkillR, myHero, predPos)
  358.     end
  359.  
  360.     if not h then return hitCount, hitEnemy end
  361.  
  362.     if h then
  363.         for index, hero in pairs(heroes) do
  364.             hitCount = hitCount + 1
  365.             if GetDistance(hero) < SkillR.range then
  366.                 table.insert(hitEnemy, hero)
  367.             end
  368.         end
  369.     end
  370.  
  371.     return hitCount, hitEnemy
  372. end
  373.  
  374. function GetHeroCollision(skill, source, destination)
  375.     if VIP_USER then
  376.         local col = Collision(skill.range, skill.speed*1000, skill.delay/1000, skill.width)
  377.  
  378.         if col then
  379.             local ret, heroes = col:GetHeroCollision(source, destination, 2) -- 2 = HERO_ENEMY
  380.             return ret, heroes
  381.         else
  382.             return false, nil
  383.         end
  384.     else
  385.         return false, nil
  386.     end
  387. end
  388.  
  389. function IsEnemyHealthLow(enemy)
  390.     local enemyLowHealth = .40
  391.  
  392.     if enemy and not enemy.dead and enemy.health < (enemy.maxHealth * enemyLowHealth) then
  393.         return true
  394.     else
  395.         return false
  396.     end
  397. end
  398.  
  399. -- End of Twitch script
  400.  
  401. --[[
  402.     AoE_Skillshot_Position 2.0 by monogato
  403.    
  404.     GetAoESpellPosition(radius, main_target, [delay]) returns best position in order to catch as many enemies as possible with your AoE skillshot, making sure you get the main target.
  405.     Note: You can optionally add delay in ms for prediction (VIP if avaliable, normal else).
  406. ]]
  407.  
  408. function GetCenter(points)
  409.     local sum_x = 0
  410.     local sum_z = 0
  411.    
  412.     for i = 1, #points do
  413.         sum_x = sum_x + points[i].x
  414.         sum_z = sum_z + points[i].z
  415.     end
  416.    
  417.     local center = {x = sum_x / #points, y = 0, z = sum_z / #points}
  418.    
  419.     return center
  420. end
  421.  
  422. function ContainsThemAll(circle, points)
  423.     local radius_sqr = circle.radius*circle.radius
  424.     local contains_them_all = true
  425.     local i = 1
  426.    
  427.     while contains_them_all and i <= #points do
  428.         contains_them_all = GetDistanceSqr(points[i], circle.center) <= radius_sqr
  429.         i = i + 1
  430.     end
  431.    
  432.     return contains_them_all
  433. end
  434.  
  435. -- The first element (which is gonna be main_target) is untouchable.
  436. function FarthestFromPositionIndex(points, position)
  437.     local index = 2
  438.     local actual_dist_sqr
  439.     local max_dist_sqr = GetDistanceSqr(points[index], position)
  440.    
  441.     for i = 3, #points do
  442.         actual_dist_sqr = GetDistanceSqr(points[i], position)
  443.         if actual_dist_sqr > max_dist_sqr then
  444.             index = i
  445.             max_dist_sqr = actual_dist_sqr
  446.         end
  447.     end
  448.    
  449.     return index
  450. end
  451.  
  452. function RemoveWorst(targets, position)
  453.     local worst_target = FarthestFromPositionIndex(targets, position)
  454.    
  455.     table.remove(targets, worst_target)
  456.    
  457.     return targets
  458. end
  459.  
  460. function GetInitialTargets(radius, main_target)
  461.     local targets = {main_target}
  462.     local diameter_sqr = 4 * radius * radius
  463.    
  464.     for i=1, heroManager.iCount do
  465.         target = heroManager:GetHero(i)
  466.         if target.networkID ~= main_target.networkID and ValidTarget(target) and GetDistanceSqr(main_target, target) < diameter_sqr then table.insert(targets, target) end
  467.     end
  468.    
  469.     return targets
  470. end
  471.  
  472. function GetPredictedInitialTargets(radius, main_target, delay)
  473.     if VIP_USER and not vip_target_predictor then vip_target_predictor = TargetPredictionVIP(nil, nil, delay/1000) end
  474.     local predicted_main_target = VIP_USER and vip_target_predictor:GetPrediction(main_target) or GetPredictionPos(main_target, delay)
  475.     local predicted_targets = {predicted_main_target}
  476.     local diameter_sqr = 4 * radius * radius
  477.    
  478.     for i=1, heroManager.iCount do
  479.         target = heroManager:GetHero(i)
  480.         if ValidTarget(target) then
  481.             predicted_target = VIP_USER and vip_target_predictor:GetPrediction(target) or GetPredictionPos(target, delay)
  482.             if target.networkID ~= main_target.networkID and GetDistanceSqr(predicted_main_target, predicted_target) < diameter_sqr then table.insert(predicted_targets, predicted_target) end
  483.         end
  484.     end
  485.    
  486.     return predicted_targets
  487. end
  488.  
  489. -- I don´t need range since main_target is gonna be close enough. You can add it if you do.
  490. function GetAoESpellPosition(radius, main_target, delay)
  491.     local targets = delay and GetPredictedInitialTargets(radius, main_target, delay) or GetInitialTargets(radius, main_target)
  492.     local position = GetCenter(targets)
  493.     local best_pos_found = true
  494.     local circle = Circle(position, radius)
  495.     circle.center = position
  496.    
  497.     if #targets > 2 then best_pos_found = ContainsThemAll(circle, targets) end
  498.    
  499.     while not best_pos_found do
  500.         targets = RemoveWorst(targets, position)
  501.         position = GetCenter(targets)
  502.         circle.center = position
  503.         best_pos_found = ContainsThemAll(circle, targets)
  504.     end
  505.    
  506.     return position
  507. end
Advertisement
Add Comment
Please, Sign In to add comment