Kain2030

Zyra - Rise of the Thorns - v2.1

Sep 9th, 2013
981
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 24.47 KB | None | 0 0
  1. --[[
  2.         Zyra: Rise of the Thorns
  3.         Author: Kain
  4.         Version: See version variable below.
  5.         Copyright 2013
  6.  
  7.         How to install:
  8.             Place the plugin in BoL/Scripts folder.
  9.        
  10.         Version History:
  11.             Version: 2.1:
  12.                 Fixed Q not firing, and missing sometimes when it does.
  13.                 Fixed Q-W combo.
  14.                 Fixed Q and W not firing when E hasn't been learned yet.
  15.             Version 2.0c:
  16.                 Completely rewrote script.
  17.                 Combos: E+Q+WW+R, E+Q+WW, E+Q+W, E+WW, E+W, Q+WW, E+WW, depending on combo config and situations.
  18.                 SBTW: Script does just great, when are you're doing is holding spacebar.
  19.                 Pro Mode: Q, W, E, R keys all work as normal, if you choose to use them manually, except Q, E, R all use built in combos and prediction, so you don't have to worry.
  20.                 VIP Prediction supported: It has non-VIP prediction also, but you're going to have a much better experience with VIP.
  21.                 Harass Mode: Q+WW, E+WW, Q+E+WW, depending on harass config.
  22.                 Sida's Auto Carry: Revamped and Reborn supported
  23.                 Fully customizable Combo (Q, W, E, R), Harass (Q, W, E), and Draw
  24.                 Killsteal with Deadly Bloom and Stranglethorns
  25.                 Auto Passive prediction with Killsteal
  26.                 Stranglethorns Group prediction using AoE Skillshot Position library, which is built in. This lib is better than MEC for group prediction. Will use VIP prediction on all targets.
  27.                 Auto Ignite
  28.                 Extensive configuration options in two menus.
  29.                 Support Role Mode: One-click Enable to disable killsteal and other options to be a good ADC support. Leave off if you just dont't give a ****.
  30.                 Range Circles: Smart range circles turn on and off as their respective spells are available.
  31.  
  32.             Version: 1.0 Alpha: Unreleased
  33. --]]
  34.  
  35. if myHero.charName ~= "Zyra" then return end
  36.  
  37. function OnLoad()
  38.     Vars()
  39.     Menu()
  40.  
  41.     PrintChat(" >> Zyra: Rise of the Thorns by Kain loaded!")
  42. end
  43.  
  44. function Vars()
  45.     version = "2.1"
  46.  
  47.     QRange, QSpeed, QDelay, QRadius = 825, math.huge, 0.7, 85 -- Old Delay: 0.500
  48.     WRange, WSpeed, WDelay, WRadius = 825, math.huge, 0.2432, 10
  49.     ERange, ESpeed, EDelay, EWidth = 1100, 1150, 0.16, 70 -- Some discrepency on delay: between .16 and .25
  50.     RRange, RSpeed, RDelay, RRadius = 700, math.huge, 0.500, 500
  51.     PRange, PSpeed, PDelay, PWidth = 1470, 1870, 0.500, 60 -- Need to review this. Passive missing more than it should.
  52.  
  53.     igniteRange = 600
  54.  
  55.     ts = TargetSelector(TARGET_LESS_CAST_PRIORITY, QRange, DAMAGE_MAGIC, false)
  56.  
  57.     if VIP_USER then
  58.         tpQ = TargetPredictionVIP(QRange, QSpeed, QDelay, QRadius*2)
  59.         tpE = TargetPredictionVIP(ERange, ESpeed, EDelay, EWidth)
  60.         tpR = TargetPredictionVIP(RRange, RSpeed, RDelay, RRadius*2)
  61.         tpP = TargetPredictionVIP(PRange, PSpeed, PDelay, PWidth)
  62.     else
  63.         tpQ = TargetPrediction(QRange, QSpeed, QDelay*1000, QRadius*2)
  64.         tpE = TargetPrediction(ERange, ESpeed/1000, EDelay*1000, EWidth)
  65.         tpR = TargetPrediction(RRange, RSpeed, RDelay*1000, RRadius*2)
  66.         tpP = TargetPrediction(PRange, PSpeed/1000, PDelay*1000, PWidth)
  67.     end
  68.  
  69.     igniteSlot = ((myHero:GetSpellData(SUMMONER_1).name:find("SummonerDot") and SUMMONER_1) or (myHero:GetSpellData(SUMMONER_2).name:find("SummonerDot") and SUMMONER_2) or nil)
  70.  
  71.     KeyQ = string.byte("Q")
  72.     KeyW = string.byte("W")
  73.     KeyE = string.byte("E")
  74.     KeyR = string.byte("R")
  75.  
  76.     lastE = 0
  77.  
  78.     updateTextTimers = {}
  79.     enemyMinions = {}
  80.  
  81.     IgniteRange = 600
  82.  
  83.     if myHero:GetSpellData(SUMMONER_1).name:find("SummonerDot") then
  84.         ignite = SUMMONER_1
  85.     elseif myHero:GetSpellData(SUMMONER_2).name:find("SummonerDot") then
  86.         ignite = SUMMONER_2
  87.     else
  88.         ignite = nil
  89.     end
  90.  
  91.     QReady, WReady, EReady, RReady = false, false, false, false
  92.     DFGSlot, HXGSlot, BWCSlot, STDSlot, SheenSlot, TrinitySlot, LichBaneSlot = nil, nil, nil, nil, nil, nil, nil
  93.     DFGReady, HXGReady, BWCReady, STDReady, IReady = false, false, false, false, false
  94.  
  95.     enemyMinions = minionManager(MINION_ENEMY, ERange, myHero, MINION_SORT_HEALTH_ASC)
  96.  
  97.     -- Objects
  98.     objZyraQ = "zyra_Q_cas.troy"
  99.     objZyraE = "Zyra_E_sequence_impact.troy"
  100.  
  101.     isSACRunning = IsRunningSAC()
  102.  
  103.     debugMode = false
  104. end
  105.  
  106. function Menu()
  107.     ZyraConfig = scriptConfig("Zyra by Kain: Main - v"..version, "Zyra")
  108.  
  109.     ZyraConfig:addParam("sep", "----- [ Main ] -----", SCRIPT_PARAM_INFO, "")
  110.     ZyraConfig:addParam("Combo","Combo", SCRIPT_PARAM_ONKEYDOWN, false, 32)
  111.     ZyraConfig:addParam("Harass", "Harass", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("C"))
  112.     ZyraConfig:addParam("Farm", "Farm", SCRIPT_PARAM_ONKEYDOWN, false, string.byte("V"))
  113.     ZyraConfig:addParam("SupportMode", "Support Role Mode", SCRIPT_PARAM_ONOFF, false)
  114.  
  115.     ZyraConfig:addParam("sep", "----- [ Combo Spells ] -----", SCRIPT_PARAM_INFO, "")
  116.     ZyraConfig:addParam("ComboQ", "Use Deadly Bloom", SCRIPT_PARAM_ONOFF, true)
  117.     ZyraConfig:addParam("ComboW", "Use Rampant Growth", SCRIPT_PARAM_ONOFF, true)
  118.     ZyraConfig:addParam("ComboE", "Use Grasping Roots", SCRIPT_PARAM_ONOFF, true)
  119.     ZyraConfig:addParam("DoubleW", "Double Seed on Combo", SCRIPT_PARAM_ONOFF, true)
  120.  
  121.     ZyraConfig:addParam("sep", "----- [ Harass Spells ] -----", SCRIPT_PARAM_INFO, "")
  122.     ZyraConfig:addParam("HarassQ", "Use Deadly Bloom", SCRIPT_PARAM_ONOFF, true)
  123.     ZyraConfig:addParam("HarassW", "Use Rampant Growth", SCRIPT_PARAM_ONOFF, true)
  124.     ZyraConfig:addParam("HarassE", "Use Grasping Roots", SCRIPT_PARAM_ONOFF, false)
  125.  
  126.     ZyraConfig:addParam("sep", "----- [ Strangle Group ] -----", SCRIPT_PARAM_INFO, "")
  127.     ZyraConfig:addParam("UltGroup", "Ult Enemy Team", SCRIPT_PARAM_ONOFF, true)
  128.     ZyraConfig:addParam("UltGroupMinimum", "Ult Enemy Team Min.", SCRIPT_PARAM_SLICE, 3, 2, 5, 0)
  129.  
  130.     ZyraConfig:addParam("sep", "----- [ Killsteal ] -----", SCRIPT_PARAM_INFO, "")
  131.     ZyraConfig:addParam("UltKillsteal", "Stranglethorn Killsteal", SCRIPT_PARAM_ONOFF, true)
  132.     ZyraConfig:addParam("DeadlyBloomKS", "Deadly Bloom Killsteal", SCRIPT_PARAM_ONOFF, true)
  133.  
  134.     ZyraExtraConfig = scriptConfig("Zyra by Kain: Extras", "Zyra")
  135.     ZyraExtraConfig:addParam("sep", "----- [ Misc ] -----", SCRIPT_PARAM_INFO, "")
  136.     ZyraExtraConfig:addParam("MinionMarker", "Minion Marker", SCRIPT_PARAM_ONOFF, true)
  137.     ZyraExtraConfig:addParam("Passive", "Auto Passive", SCRIPT_PARAM_ONOFF, true)
  138.  
  139.     ZyraExtraConfig:addParam("sep", "----- [ Advanced ] -----", SCRIPT_PARAM_INFO, "")
  140.     ZyraExtraConfig:addParam("HitChanceMin", "Prediction Hit Chance Min.", SCRIPT_PARAM_SLICE, 60, 1, 100, 0)
  141.     ZyraExtraConfig:addParam("DoubleIgnite", "Don't Double Ignite", SCRIPT_PARAM_ONOFF, true)
  142.     ZyraExtraConfig:addParam("ProMode", "Use Auto QWER Keys", SCRIPT_PARAM_ONOFF, true)
  143.     ZyraExtraConfig:addParam("sep", "----- [ Draw ] -----", SCRIPT_PARAM_INFO, "")
  144.     ZyraExtraConfig:addParam("DisableDraw", "Disable Draw", SCRIPT_PARAM_ONOFF, false)
  145.     ZyraExtraConfig:addParam("DrawFurthest", "Draw Furthest Spell Available", SCRIPT_PARAM_ONOFF, true)
  146.     ZyraExtraConfig:addParam("DrawTargetArrow", "Draw Arrow to Target", SCRIPT_PARAM_ONOFF, true)
  147.     ZyraExtraConfig:addParam("DrawQ", "Draw Deadly Bloom", SCRIPT_PARAM_ONOFF, true)
  148.     ZyraExtraConfig:addParam("DrawW", "Draw Rampant Growth", SCRIPT_PARAM_ONOFF, true)
  149.     ZyraExtraConfig:addParam("DrawE", "Draw Grasping Roots", SCRIPT_PARAM_ONOFF, true)
  150.     ZyraExtraConfig:addParam("DrawR", "Draw Stranglethorns", SCRIPT_PARAM_ONOFF, true)
  151.  
  152.     ZyraConfig:permaShow("Combo")
  153.     ZyraConfig:permaShow("Harass")
  154.     ZyraConfig:permaShow("Farm")
  155.  
  156.     ts.name = "Zyra"
  157.     ZyraConfig:addTS(ts)
  158. end
  159.  
  160. function IsRunningSAC()
  161.     if _G.EnemyMinions then
  162.         return true -- SAC Loaded
  163.     else
  164.         return false -- SAC not running
  165.     end
  166. end
  167.  
  168. function SpellCheck()
  169.     DFGSlot, HXGSlot, BWCSlot, BRKSlot, STDSlot, SheenSlot, TrinitySlot, LichBaneSlot = GetInventorySlotItem(3128),
  170.     GetInventorySlotItem(3146), GetInventorySlotItem(3144), GetInventorySlotItem(3153), GetInventorySlotItem(3131),
  171.     GetInventorySlotItem(3057), GetInventorySlotItem(3078), GetInventorySlotItem(3100)
  172.  
  173.     QReady = (myHero:CanUseSpell(_Q) == READY)
  174.     WReady = (myHero:CanUseSpell(_W) == READY)
  175.     EReady = (myHero:CanUseSpell(_E) == READY)
  176.     RReady = (myHero:CanUseSpell(_R) == READY)
  177.  
  178.     DFGReady = (DFGSlot ~= nil and myHero:CanUseSpell(DFGSlot) == READY)
  179.     HXGReady = (HXGSlot ~= nil and myHero:CanUseSpell(HXGSlot) == READY)
  180.     BWCReady = (BWCSlot ~= nil and myHero:CanUseSpell(BWCSlot) == READY)
  181.     BRKReady = (BRKSlot ~= nil and myHero:CanUseSpell(BRKSlot) == READY)
  182.  
  183.     IReady = (ignite ~= nil and myHero:CanUseSpell(ignite) == READY)
  184. end
  185.  
  186. function UseItems(enemy)
  187.     if enemy and not enemy.dead and GetDistance(enemy) < 550 then
  188.         if DFGReady then CastSpell(DFGSlot, enemy) end
  189.         if HXGReady then CastSpell(HXGSlot, enemy) end
  190.         if BWCReady then CastSpell(BWCSlot, enemy) end
  191.         if BRKReady then CastSpell(BRKSlot, enemy) end
  192.     end
  193. end
  194.  
  195. function OnTick()
  196.     ts:update()
  197.  
  198.     SpellCheck()
  199.  
  200.     if ts ~= nil and ts.target ~= nil then
  201.         if IsPassiveUp() then -- myHero is dead, but in passive state.
  202.             if QReady and ZyraExtraConfig.Passive then
  203.                 Passive()
  204.             end
  205.         elseif not myHero.dead then
  206.             AutoIgnite()
  207.             if ZyraConfig.Combo then
  208.                 -- UseItems(ts.target)
  209.                 Combo()
  210.             end
  211.             if ZyraConfig.Harass then Harass() end
  212.             if ZyraConfig.Farm then Farm() end
  213.         end
  214.     end
  215. end
  216.  
  217. function IsPassiveUp()
  218.     return myHero:GetSpellData(_Q).name == myHero:GetSpellData(_W).name or myHero:GetSpellData(_W).name == myHero:GetSpellData(_E).name
  219. end
  220.  
  221. function OnCreateObj(object)
  222. --[[
  223.     if object then
  224.         if object.name:find(objZyraQ) ~= nil and GetDistance(object) < QRange then
  225.             -- Already handled elsewhere.
  226.         end
  227.  
  228.         if object.name:find(objZyraE) ~= nil and GetDistance(object) < ERange then
  229.             -- Already handled elsewhere.
  230.         end
  231.     end
  232. --]]
  233. end
  234.  
  235. function OnDeleteObj(object)
  236.     -- Nothing to see here.
  237. end
  238.  
  239. function OnProcessSpell(unit, spell)
  240.     if unit.isMe and spell.name == myHero:GetSpellData(_E).name then
  241.         DamageOnRoot(spell)
  242.     end
  243. end
  244.  
  245. function DamageOnRoot(spell)
  246.     if spell.endPos and ts and ts.target and ValidTarget(ts.target) then
  247.         local EPos = tpE:GetPrediction(ts.target)
  248.         if EPos then
  249.             local intersection = LineSegment(Point(myHero.x, myHero.z), Point(spell.endPos.x, spell.endPos.z)):intersectionPoints(LineSegment(Point(ts.target.x, ts.target.z), Point(EPos.x, EPos.z)))[1]
  250.             if intersection and GetDistance(intersection) < QRange then
  251.                 if QReady then
  252.                     CastSpell(_Q, intersection.x, intersection.y)
  253.                 end
  254.                 if WReady then
  255.                     if debugMode then PrintChat("onprocess W: "..intersection.x.."!"..intersection.y) end
  256.                     CastW(intersection.x, intersection.y)
  257.                     if WReady and ZyraConfig.DoubleW then
  258.                         if debugMode then PrintChat("onprocess double W: "..intersection.x.."!"..intersection.y) end
  259.                         CastW(intersection.x, intersection.y)
  260.                     end
  261.                 end
  262.             elseif WReady then
  263.                 if VIP_USER then
  264.                     CastW(spell.endPos.x, spell.endPos.z)
  265.                 end
  266.                 if WReady and ZyraConfig.DoubleW then
  267.                     if VIP_USER then
  268.                         CastW(spell.endPos.x, spell.endPos.z)
  269.                     end
  270.                 end
  271.             end
  272.         end
  273.     end
  274. end
  275.  
  276. function Combo()
  277.     if not ts or not ts.target then return end
  278.  
  279.     if not ValidTarget(ts.target) then return end
  280.  
  281.     -- Root combo
  282.     if EReady and ZyraConfig.ComboE then
  283.         CastE()
  284.     end
  285.  
  286.     -- Fires when target is already rooted.
  287.     if QReady and ZyraConfig.ComboQ then
  288.         CastQ(ts.target)
  289.     end
  290.  
  291.     if not ZyraConfig.SupportMode and QReady and ZyraConfig.DeadlyBloomKS then
  292.         DeadlyBloomKillsteal()
  293.     end
  294.  
  295.     if not ZyraConfig.SupportMode and (not QReady or not ZyraConfig.ComboQ) and (not EReady or not ZyraConfig.ComboE) and RReady and ZyraConfig.UltKillsteal then
  296.         UltKillsteal()
  297.     end
  298.  
  299.     if RReady and ZyraConfig.UltGroup then
  300.         UltGroup(false)
  301.     end
  302. end
  303.  
  304. function CastQ(enemy)
  305.     if not enemy and ts and ts.target then enemy = ts.target end
  306.  
  307.     if not enemy.canMove then
  308.         CastSpell(_Q, enemy.x, enemy.z)
  309.     elseif ENotReadyToUse() then
  310.         local QPos = GetQPrediction(enemy)
  311.         if QPos then
  312.             CastSpell(_Q, QPos.x, QPos.z)
  313.             if ZyraConfig.DoubleW or myHero:CanUseSpell(_E) == NOTLEARNED then
  314.                 CastW(QPos.x, QPos.z)
  315.             end
  316.         end
  317.     end
  318. end
  319.  
  320. function CastW(posX, posZ)
  321.     if VIP_USER then
  322.         Packet("S_CAST", {spellId = _W, fromX = posX, fromY = posZ, toX = posX, toY = posZ}):send()
  323.     else
  324.         CastSpell(_W, posX, posZ)
  325.     end
  326. end
  327.  
  328. function CastE(enemy)
  329.     if not enemy and ts and ts.target then enemy = ts.target end
  330.  
  331.     local EPos = GetEPrediction(ts.target)
  332.     if EPos then
  333.         -- This part is tricky. If non-VIP, then do W normally, then E.
  334.         -- If VIP, then do E, then W using packets.
  335.         if not VIP_USER then CastW(EPos.x, EPos.z) end
  336.         CastSpell(_E, EPos.x, EPos.z)
  337.         if VIP_USER then
  338.             CastW(EPos.x, EPos.z)
  339.         end
  340.         if debugMode then PrintChat("E W") end
  341.     end
  342. end
  343.  
  344. function ENotReadyToUse()
  345.     return (myHero:CanUseSpell(_E) == COOLDOWN and (myHero:GetSpellData(_E).cd - myHero:GetSpellData(_E).currentCd > 1.5)) or myHero:CanUseSpell(_E) == NOTLEARNED
  346. end
  347.  
  348. function Harass()
  349.     if not ValidTarget(ts.target) then return end
  350.  
  351.     if QReady and ZyraConfig.HarassQ then
  352.         local predPos = GetQPrediction(ts.target)
  353.         if predPos then
  354.             CastSpell(_Q, predPos.x, predPos.z)
  355.             if WReady and ZyraConfig.HarassW then
  356.                 CastW(predPos.x, predPos.z)
  357.             end
  358.         end
  359.     end
  360.  
  361.     if EReady and ZyraConfig.HarassE then
  362.         local predPos = GetEPrediction(ts.target)
  363.         if predPos then
  364.             local col = GetECollision(predPos, ts.target)
  365.             if not col then
  366.                 CastSpell(_E, predPos.x, predPos.z)
  367.                 if WReady and ZyraConfig.HarassW then
  368.                     CastW(predPos.x, predPos.z)
  369.                 end
  370.             end
  371.         end
  372.     end
  373. end
  374.  
  375. function Farm()
  376.     enemyMinions:update()
  377.     for _, minion in ipairs(enemyMinions.objects) do
  378.         if ValidTarget(minion) then
  379.             if getDmg("AD", minion, myHero) * 1.1 > minion.health then
  380.                 myHero:Attack(minion)
  381.             elseif getDmg("Q", minion, myHero) > minion.health then
  382.                 CastSpell(_Q, minion.x, minion.z)
  383.             end
  384.         end
  385.     end
  386. end
  387.  
  388. function Passive()
  389.     -- Hit any killable enemy.
  390.     for _, enemy in ipairs(GetEnemyHeroes()) do
  391.         if ValidTarget(enemy, PRange) and getDmg("P", enemy, myHero) > enemy.health then
  392.             local predPos = GetPPrediction(enemy)
  393.             if predPos then
  394.                 CastSpell(_Q, predPos.x, predPos.z)
  395.                 return true
  396.             end
  397.         end
  398.     end
  399.  
  400.     -- No one was killable, so just damage best target.
  401.     if ValidTarget(ts.target, PRange) then
  402.         local predPos = GetPPrediction(ts.target)
  403.         if predPos then
  404.             CastSpell(_Q, predPos.x, predPos.z)
  405.             return true
  406.         end
  407.     end
  408.  
  409.     return false
  410. end
  411.  
  412. function UltGroup(manual)
  413.     if not ts or not ts.target then return false end
  414.  
  415.     if not manual and EnemyCount(myHero, (RRange + RRadius)) < ZyraConfig.UltGroupMinimum then return false end
  416.  
  417.     local spellPos = GetAoESpellPosition(RRadius, ts.target, RDelay * 1000)
  418.  
  419.     if spellPos and GetDistance(spellPos) <= RRange then
  420.         if manual or EnemyCount(spellPos, RRadius) >= ZyraConfig.UltGroupMinimum then
  421.             if debugMode then PrintChat("R AoE") end
  422.             CastSpell(_R, spellPos.x, spellPos.z)
  423.             return true
  424.         end
  425.     end
  426.  
  427.     return false
  428. end
  429.  
  430. function DeadlyBloomKillsteal()
  431.     if not QReady then return false end
  432.  
  433.     for _, enemy in pairs(GetEnemyHeroes()) do
  434.         if enemy and not enemy.dead and enemy.health < getDmg("Q", enemy, myHero) then
  435.             CastQ(enemy)
  436.             return true
  437.         end
  438.     end
  439.  
  440.     return false
  441. end
  442.  
  443. function UltKillsteal()
  444.     for _, enemy in pairs(GetEnemyHeroes()) do
  445.         if enemy and not enemy.dead and enemy.health < getDmg("R", enemy, myHero) then
  446.             local spellPos = GetAoESpellPosition(RRadius, ts.target, RDelay * 1000)
  447.             if spellPos and GetDistance(spellPos) <= RRange then
  448.                 if not enemy.dead then
  449.                     if debugMode then PrintChat("R Killsteal") end
  450.                     CastSpell(_R, spellPos.x, spellPos.z)
  451.                     return true
  452.                 end
  453.             end
  454.         end
  455.     end
  456.  
  457.     return false
  458. end
  459.  
  460. function EnemyCount(point, range)
  461.     local count = 0
  462.  
  463.     for _, enemy in pairs(GetEnemyHeroes()) do
  464.         if enemy and not enemy.dead and GetDistance(point, enemy) <= range then
  465.             count = count + 1
  466.         end
  467.     end            
  468.  
  469.     return count
  470. end
  471.  
  472. function AutoIgnite()
  473.     if IReady and not myHero.dead then
  474.         for _, enemy in ipairs(GetEnemyHeroes()) do
  475.             if ValidTarget(enemy) then
  476.                 if enemy ~= nil and enemy.team ~= myHero.team and not enemy.dead and enemy.visible and GetDistance(enemy) < IgniteRange and enemy.health < getDmg("IGNITE", enemy, myHero) then
  477.                     if ZyraExtraConfig.DoubleIgnite and not TargetHaveBuff("SummonerDot", enemy) then
  478.                         CastSpell(ignite, enemy)
  479.                     elseif not ZyraExtraConfig.DoubleIgnite then
  480.                         CastSpell(ignite, enemy)
  481.                     end
  482.                 end
  483.             end
  484.         end
  485.     end
  486. end
  487.  
  488. -- Draw
  489.  
  490. function OnDraw()
  491.     if ZyraExtraConfig.DrawTargetArrow and ts ~= nil and ts.target ~= nil and not ts.target.dead and (ZyraConfig.Combo or ZyraConfig.Harass) then
  492.         DrawArrowsToPos(myHero, ts.target)
  493.     end
  494.  
  495.     if not ZyraExtraConfig.DisableDraw and not myHero.dead then
  496.         local farSpell = FindFurthestReadySpell()
  497.  
  498.         -- DrawCircle(myHero.x, myHero.y, myHero.z, getTrueRange(), 0x808080) -- Gray
  499.  
  500.         if ZyraExtraConfig.DrawQ and QReady and ((ZyraExtraConfig.DrawFurthest and farSpell and farSpell == QRange) or not ZyraExtraConfig.DrawFurthest) then
  501.             DrawCircle(myHero.x, myHero.y, myHero.z, QRange, 0x0099CC) -- Blue
  502.         end
  503.  
  504.         if ZyraExtraConfig.DrawW and WReady and ((ZyraExtraConfig.DrawFurthest and farSpell and farSpell == WRange) or not ZyraExtraConfig.DrawFurthest) then
  505.             DrawCircle(myHero.x, myHero.y, myHero.z, WRange, 0xFFFF00) -- Yellow
  506.         end
  507.        
  508.         if ZyraExtraConfig.DrawE and EReady and ((ZyraExtraConfig.DrawFurthest and farSpell and farSpell == ERange) or not ZyraExtraConfig.DrawFurthest) then
  509.             DrawCircle(myHero.x, myHero.y, myHero.z, ERange, 0x00FF00) -- Green
  510.         end
  511.  
  512.         local RRangePlusRadius = RRange + RRadius
  513.         if ZyraExtraConfig.DrawR and RReady and ((ZyraExtraConfig.DrawFurthest and farSpell and farSpell == RRangePlusRadius) or not ZyraExtraConfig.DrawFurthest) then
  514.             DrawCircle(myHero.x, myHero.y, myHero.z, RRangePlusRadius, 0xFF0000) -- Red
  515.         end
  516.  
  517.         if ts ~= nil and ts.target ~= nil then
  518.             for j=0, 10 do
  519.                 DrawCircle(ts.target.x, ts.target.y, ts.target.z, 40 + j*1.5, 0x00FF00) -- Green
  520.             end
  521.         end
  522.  
  523.         MinionMarkerOnDraw()
  524.     end
  525. end
  526.  
  527. function MinionMarkerOnDraw()
  528.     if ZyraExtraConfig.MinionMarker then
  529.         if not ZyraConfig.Farm then enemyMinions:update() end
  530.         for _, minion in ipairs(enemyMinions.objects) do
  531.             if ValidTarget(minion) and getDmg("Q", minion, myHero) > minion.health then
  532.                 for i = 1, 5 do
  533.                     DrawCircle(minion.x, minion.y, minion.z, 50+i, (getDmg("AD", minion, myHero) * 1.1 > minion.health and 0x8080FF00 or 0xFFFF0000))
  534.                 end
  535.             end
  536.         end
  537.     end
  538. end
  539.  
  540. function FindFurthestReadySpell()
  541.     local farSpell = nil
  542.  
  543.     if ZyraExtraConfig.DrawQ and QReady then farSpell = QRange end
  544.     if ZyraExtraConfig.DrawW and WReady and (not farSpell or WRange > farSpell) then farSpell = WRange end
  545.     if ZyraExtraConfig.DrawE and EReady and (not farSpell or ERange > farSpell) then farSpell = ERange end
  546.  
  547.     local RRangePlusRadius = RRange + RRadius
  548.     if ZyraExtraConfig.DrawR and RReady and (not farSpell or RRangePlusRadius > farSpell) then farSpell = RRangePlusRadius end
  549.  
  550.     return farSpell
  551. end
  552.  
  553. function getTrueRange()
  554.     return myHero.range + GetDistance(myHero.minBBox)
  555. end
  556.  
  557. function DrawArrowsToPos(pos1, pos2)
  558.     if pos1 and pos2 then
  559.         startVector = D3DXVECTOR3(pos1.x, pos1.y, pos1.z)
  560.         endVector = D3DXVECTOR3(pos2.x, pos2.y, pos2.z)
  561.         DrawArrows(startVector, endVector, 60, 0xE97FA5, 100)
  562.     end
  563. end
  564.  
  565. function GetQPrediction(enemy)
  566.     if not ValidTarget(enemy) or not IsGoodHitChance(tpQ, enemy) then return end
  567.     return tpQ:GetPrediction(enemy)
  568. end
  569.  
  570. function GetEPrediction(enemy)
  571.     if not ValidTarget(enemy) or not IsGoodHitChance(tpE, enemy) then return end
  572.     return tpE:GetPrediction(enemy)
  573. end
  574.  
  575. function GetECollision(pred, enemy)
  576.     if VIP_USER then
  577.         local col = Collision(ERange, ESpeed, EDelay, EWidth)
  578.         if not col then return false end
  579.         return col:GetMinionCollision(myHero, pred)
  580.     else
  581.         return willHitMinion(pred, EWidth)
  582.     end
  583. end
  584.  
  585. function GetPPrediction(enemy)
  586.     if not ValidTarget(enemy) or not IsGoodHitChance(tpP, enemy) then return end
  587.     return tpP:GetPrediction(enemy)
  588. end
  589.  
  590. function IsGoodHitChance(spellPred, enemy)
  591.     if VIP_USER and spellPred:GetHitChance(enemy) > (ZyraExtraConfig.HitChanceMin / 100) then
  592.         return true
  593.     elseif not VIP_USER then
  594.         return true
  595.     else
  596.         return false
  597.     end
  598. end
  599.  
  600. function willHitMinion(predic, width)
  601.     local hitCount = 0
  602.     for _, minionObjectE in pairs(enemyMinions.objects) do
  603.         if minionObjectE ~= nil and string.find(minionObjectE.name,"Minion_") == 1 and minionObjectE.team ~= myHero.team and minionObjectE.dead == false then
  604.             if predic ~= nil and myHero:GetDistance(minionObjectE) < 900 then
  605.                  ex = myHero.x
  606.                  ez = myHero.z
  607.                  tx = predic.x
  608.                  tz = predic.z
  609.                  dx = ex - tx
  610.                  dz = ez - tz
  611.                  if dx ~= 0 then
  612.                  m = dz/dx
  613.                  c = ez - m*ex
  614.                  end
  615.                  mx = minionObjectE.x
  616.                  mz = minionObjectE.z
  617.                  distanc = (math.abs(mz - m*mx - c))/(math.sqrt(m*m+1))
  618.                  if distanc < width and math.sqrt((tx - ex)*(tx - ex) + (tz - ez)*(tz - ez)) > math.sqrt((tx - mx)*(tx - mx) + (tz - mz)*(tz - mz)) then
  619.                         return true
  620.                  end
  621.             end
  622.         end
  623.      end
  624.  
  625.      return false
  626. end
  627.  
  628. function OnWndMsg(msg,key)
  629.     if ts and ts.target and ZyraExtraConfig.ProMode then
  630.         if msg == KEY_DOWN and key == KeyQ then CastQ() end
  631.         if msg == KEY_DOWN and key == KeyE then CastE() end
  632.         if msg == KEY_DOWN and key == KeyR then UltGroup(true) end
  633.     end
  634. end
  635.  
  636. -- End of Zyra script
  637.  
  638. --[[
  639.     AoE_Skillshot_Position 2.0 by monogato
  640.    
  641.     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.
  642.     Note: You can optionally add delay in ms for prediction (VIP if avaliable, normal else).
  643. ]]
  644.  
  645. function GetCenter(points)
  646.     local sum_x = 0
  647.     local sum_z = 0
  648.    
  649.     for i = 1, #points do
  650.         sum_x = sum_x + points[i].x
  651.         sum_z = sum_z + points[i].z
  652.     end
  653.    
  654.     local center = {x = sum_x / #points, y = 0, z = sum_z / #points}
  655.    
  656.     return center
  657. end
  658.  
  659. function ContainsThemAll(circle, points)
  660.     local radius_sqr = circle.radius*circle.radius
  661.     local contains_them_all = true
  662.     local i = 1
  663.    
  664.     while contains_them_all and i <= #points do
  665.         contains_them_all = GetDistanceSqr(points[i], circle.center) <= radius_sqr
  666.         i = i + 1
  667.     end
  668.    
  669.     return contains_them_all
  670. end
  671.  
  672. -- The first element (which is gonna be main_target) is untouchable.
  673. function FarthestFromPositionIndex(points, position)
  674.     local index = 2
  675.     local actual_dist_sqr
  676.     local max_dist_sqr = GetDistanceSqr(points[index], position)
  677.    
  678.     for i = 3, #points do
  679.         actual_dist_sqr = GetDistanceSqr(points[i], position)
  680.         if actual_dist_sqr > max_dist_sqr then
  681.             index = i
  682.             max_dist_sqr = actual_dist_sqr
  683.         end
  684.     end
  685.    
  686.     return index
  687. end
  688.  
  689. function RemoveWorst(targets, position)
  690.     local worst_target = FarthestFromPositionIndex(targets, position)
  691.    
  692.     table.remove(targets, worst_target)
  693.    
  694.     return targets
  695. end
  696.  
  697. function GetInitialTargets(radius, main_target)
  698.     local targets = {main_target}
  699.     local diameter_sqr = 4 * radius * radius
  700.    
  701.     for i=1, heroManager.iCount do
  702.         target = heroManager:GetHero(i)
  703.         if target.networkID ~= main_target.networkID and ValidTarget(target) and GetDistanceSqr(main_target, target) < diameter_sqr then table.insert(targets, target) end
  704.     end
  705.    
  706.     return targets
  707. end
  708.  
  709. function GetPredictedInitialTargets(radius, main_target, delay)
  710.     if VIP_USER and not vip_target_predictor then vip_target_predictor = TargetPredictionVIP(nil, nil, delay/1000) end
  711.     local predicted_main_target = VIP_USER and vip_target_predictor:GetPrediction(main_target) or GetPredictionPos(main_target, delay)
  712.     local predicted_targets = {predicted_main_target}
  713.     local diameter_sqr = 4 * radius * radius
  714.    
  715.     for i=1, heroManager.iCount do
  716.         target = heroManager:GetHero(i)
  717.         if ValidTarget(target) then
  718.             predicted_target = VIP_USER and vip_target_predictor:GetPrediction(target) or GetPredictionPos(target, delay)
  719.             if target.networkID ~= main_target.networkID and GetDistanceSqr(predicted_main_target, predicted_target) < diameter_sqr then table.insert(predicted_targets, predicted_target) end
  720.         end
  721.     end
  722.    
  723.     return predicted_targets
  724. end
  725.  
  726. -- I don´t need range since main_target is gonna be close enough. You can add it if you do.
  727. function GetAoESpellPosition(radius, main_target, delay)
  728.     local targets = delay and GetPredictedInitialTargets(radius, main_target, delay) or GetInitialTargets(radius, main_target)
  729.     local position = GetCenter(targets)
  730.     local best_pos_found = true
  731.     local circle = Circle(position, radius)
  732.     circle.center = position
  733.    
  734.     if #targets > 2 then best_pos_found = ContainsThemAll(circle, targets) end
  735.    
  736.     while not best_pos_found do
  737.         targets = RemoveWorst(targets, position)
  738.         position = GetCenter(targets)
  739.         circle.center = position
  740.         best_pos_found = ContainsThemAll(circle, targets)
  741.     end
  742.    
  743.     return position
  744. end
Advertisement
Add Comment
Please, Sign In to add comment