if myHero.charName ~= 'Zyra' then return end
--~~~~~~ General Localizations
local pi, pi2, sin, cos, atan, atan2, acos, huge, sqrt, max, ceil, abs = math.pi, 2*math.pi, math.sin, math.cos, math.atan, math.atan2, math.acos, math.huge, math.sqrt, math.max, math.floor, math.abs
local lshift, rshift, band, bxor, DwordToFloat = bit32.lshift, bit32.rshift, bit32.band, bit32.bxor, DwordToFloat
local clock = os.clock
local pairs, ipairs = pairs, ipairs
local insert, remove = table.insert, table.remove
local TEAM_ALLY, TEAM_ENEMY, SAVE_FILE, DPExist
local function Normalize(x,z)
local length = sqrt(x * x + z * z)
return { ['x'] = x / length, ['z'] = z / length, }
end
local function NormalizeX(v1, v2, length)
x, z = v1.x - v2.x, v1.z - v2.z
local nLength = sqrt(x * x + z * z)
return { ['x'] = v2.x + ((x / nLength) * length), ['z'] = v2.z + ((z / nLength) * length)}
end
local CircleDraw = {
[1] = function(pos, range, color)
local c = WorldToScreen(D3DXVECTOR3(pos.x, pos.y or 0, pos.z))
if c.x < WINDOW_W+200 and c.y < WINDOW_H+200 and c.x > -200 and c.y > -200 then
local points = {}
for theta = 0, (pi2+(pi/16)), (pi/16) do
local tS = WorldToScreen(D3DXVECTOR3(pos.x+(range*cos(theta)), pos.y or 0, pos.z-(range*sin(theta))))
points[#points + 1] = D3DXVECTOR2(tS.x, tS.y)
end
DrawLines2(points, 2, bit32.bor(color, 0xAA000000))
end
end,
[2] = function(pos, range, color)
DrawCircle(pos.x, pos.y or 0, pos.z, range + 70, color)
end,
[3] = function() return end,
}
function Print(text, isError)
if isError then
print('[Pew Zyra] '..text..'')
return
end
print('[Pew Zyra] '..text..'')
end
--~~~~~~End Localizations
AddLoadCallback(function()
SAVE_FILE = { ['Prediction'] = 'HPred', }
if FileExist(LIB_PATH..'/Saves/PewZyra.save') then
local file = io.open(LIB_PATH..'/Saves/PewZyra.save', 'r')
local content = file:read('*all')
if content then
SAVE_FILE = JSON:decode(content)
end
file:close()
end
DPExist = FileExist(LIB_PATH..'DivinePred.lua')
if DPExist then require('DivinePred') end
if FileExist(LIB_PATH..'HPrediction.lua') then require('HPrediction') end
if FileExist(LIB_PATH..'FHPrediction.lua') then require('FHPrediction') end
TEAM_ALLY, TEAM_ENEMY = myHero.team, 300 - myHero.team
local isLoaded, loadTime = false, clock()
AddTickCallback(function()
if _Pewalk and not isLoaded then
isLoaded = true
Print('Load Completed')
Zyra()
elseif loadTime + 5 < clock() and not isLoaded then
Print('Standalone Pewalk is now required, check forum!!', true)
isLoaded = true
end
end)
end)
class 'Zyra'
function Zyra:__init()
-----------------------
--Update
-----------------------
local version = 2.6 --0.1 increments
local Downloads = {
[1] = {
version = version,
useHttps = true,
host = 'raw.githubusercontent.com',
onlineVersion = '/PewPewPew2/BoL/master/Versions/PewZyra.version',
onlinePath = '/PewPewPew2/BoL/master/PewZyra.lua',
localPath = SCRIPT_PATH.._ENV.FILE_NAME,
onUpdateComplete = function() Print('Update Complete. Please reload. (F9 F9)') end,
onLoad = function() Print('Loaded latest version. v'..version..'.') end,
onNewVersion = function() Print('New version found, downloading now...') end,
onError = function() Print('There was an error during update.') end,
checkExist = false,
endScript = false,
},
[2] = {
version = 0,
useHttps = true,
host = 'raw.githubusercontent.com',
onlineVersion = '/BolHTTF/BoL/master/HTTF/Version/HPrediction.version',
onlinePath = '/BolHTTF/BoL/master/HTTF/Common/HPrediction.lua',
localPath = LIB_PATH..'/HPrediction.lua',
onUpdateComplete = function() Print('HPrediction Download Complete. Please reload.') end,
onLoad = function() return end,
onNewVersion = function() Print('HPrediction cannot be found, downloading now...') end,
onError = function() Print('There was an error downloading HPrediction.') end,
checkExist = true,
endScript = true,
},
[3] = {
version = 0,
useHttps = true,
host = 'raw.githubusercontent.com',
onlineVersion = '/PewPewPew2/BoL/master/Versions/PewPacketLib.version',
onlinePath = '/PewPewPew2/BoL/master/PewPacketLib.lua',
localPath = LIB_PATH..'/PewPacketLib.lua',
onUpdateComplete = function() Print('PewPacketLib Download Complete. Please reload.') end,
onLoad = function() return end,
onNewVersion = function() Print('PewPacketLib cannot be found, downloading now...') end,
onError = function() Print('There was an error downloading PewPacketLib.') end,
checkExist = true,
endScript = true,
},
}
local criticalDownload = false
for _, dl in ipairs(Downloads) do
if not dl.checkExist or not FileExist(dl.localPath) then
ScriptUpdate(
dl.version,
dl.useHttps,
dl.host,
dl.onlineVersion,
dl.onlinePath,
dl.localPath,
dl.onUpdateComplete,
dl.onLoad,
dl.onNewVersion,
dl.onError
)
if dl.endScript then criticalDownload = true end
end
end
if criticalDownload then return end
require 'PewPacketLib'
-----------------------
--General Init
-----------------------
self.wCasts = {}
self.Dashing = {}
self.LastPaths = {}
self.Enemies = {}
for i=1, heroManager.iCount do
local h = heroManager:getHero(i)
if h and h.team == TEAM_ENEMY then
self.Enemies[#self.Enemies + 1] = h
self.Dashing[h.networkID] = {}
self.LastPaths[h.networkID] = {pos=Vector(0,0,0), time=0}
end
end
self:CreateMenu()
-----------------------
--Spells Init
-----------------------
self.Spells = {
[_Q] = {
['bReady'] = false,
['range'] = 800,
['rangeSqr'] = 640000,
['radius'] = 95,
['speed'] = huge,
['delay'] = 0.85,
['damage'] = function() return (35 * myHero:GetSpellData(_Q).level) + 35 + (myHero.ap * 0.55) end,
['mana'] = function() return 60 end,
},
[_W] = {
['bReady'] = false,
['range'] = 850,
['rangeSqr'] = 722500,
['speed'] = huge,
['delay'] = 0.00,
['Active'] = {},
},
[_E] = {
['bReady'] = false,
['range'] = 1100,
['rangeSqr'] = 1690000,
['speed'] = 1150,
['delay'] = 0.25,
['width'] = 70,
['damage'] = function() return 25 + (35 * myHero:GetSpellData(_E).level) + (myHero.ap * 0.5) end,
['mana'] = function() return 65 + (myHero:GetSpellData(_E).level * 5) end,
},
[_R] = {
['bReady'] = false,
['range'] = 700,
['rangeSqr'] = 490000,
['delay'] = 0.25,
['radius'] = 560,
['damage'] = function() return 95 + (myHero:GetSpellData(_R).level * 85) + (myHero.ap * 0.7) end,
['mana'] = function() return 80 + (myHero:GetSpellData(_R).level * 20) end,
},
}
self.JungleW = {
['SRU_Red'] = true,
['SRU_RedMini'] = true,
['SRU_Dragon_Elder'] = true,
['SRU_Dragon_Fire'] = true,
['SRU_Dragon_Water'] = true,
['SRU_Dragon_Air'] = true,
['SRU_Dragon_Earth'] = true,
['SRU_RiftHerald'] = true,
['SRU_Baron'] = true,
['SRU_Blue'] = true,
['SRU_BlueMini'] = true,
['SRU_BlueMini2'] = true,
}
self.Ignite = myHero:GetSpellData(SUMMONER_1).name:lower() == 'summonerdot' and SUMMONER_1 or myHero:GetSpellData(SUMMONER_2).name:lower() == 'summonerdot' and SUMMONER_2 or nil
self.ePolygon = CreatePolygon({['x'] = 0, ['z'] = 0,},{['x'] = 0, ['z'] = 0,},{['x'] = 0, ['z'] = 0,},{['x'] = 0, ['z'] = 0,})
self.wZones = {}
self.wCount = 0
self.xOffsets = {
['AniviaEgg'] = -0.1,
['Darius'] = -0.05,
['Renekton'] = -0.05,
['Sion'] = -0.05,
['Thresh'] = -0.03,
}
self.Seeds = {}
self.PlantDurations = {5,5,5,5.5,5.5,5.5,6,6,6,6.5,6.5,6.5,7,7,7,7.5,7.5,7.5}
_Pewalk.DisableSkillFarm(_Q)
_Pewalk.DisableSkillFarm(_E)
-----------------------
--Predictions
-----------------------
self.HP = HPrediction()
local SQ, SE = self.Spells[_Q], self.Spells[_E]
self.HP_Q = HPSkillshot({type = 'PromptCircle', delay = SQ.delay, range = SQ.range, radius = SQ.radius})
self.HP_E = HPSkillshot({type = 'DelayLine', delay = SE.delay, range = SE.range, width = SE.width*2, speed = SE.speed, IsLowAccuracy = true})
if FHPrediction then
self.FH_Q = {range = SQ.range, speed = huge, delay = SQ.delay, radius = SQ.radius, type = SkillShotType.SkillshotCircle,}
self.FH_E = {range = SE.range, speed = SE.speed, delay = SE.delay, radius = SE.width, type = SkillShotType.SkillshotMissileLine,}
end
if DPExist then
AddTickCallback(function()
if not self.DivineInitialized and DivinePred.isAuthed() then
self.DP = DivinePred()
self.DP_Q = CircleSS(huge, SQ.range, SQ.radius, SQ.delay, huge)
self.DP_E = LineSS(SE.speed, SE.range, SE.width, SE.delay, huge)
self.DP:bindSS('Q',self.DP_Q,50,50)
self.DP:bindSS('E',self.DP_E,50,50)
self.DivineInitialized = true
end
end)
end
self.CrowdControl = {
[5] = 'Stun',
[8] = 'Taunt',
[9] = 'Polymorph',
[11] = 'Snare',
[22] = 'Charm',
[24] = 'Suppresion',
[29] = 'KnockUp',
}
self.DrawPrediction = {['Time'] = 0,}
self.PredictionDrawing = {}
for i=1, 7 do self.PredictionDrawing[i] = {x=0, y=0, z=0} end
-----------------------
--Callbacks
-----------------------
self.Packets = GetLoseVisionPacketData()
if self.Packets then AddRecvPacketCallback2(function(p) self:RecvPacket(p) end) end
AddNewPathCallback(function(...) self:NewPath(...) end)
AddTickCallback(function() self:Tick() end)
AddCastSpellCallback(function(...) self:CastSpell(...) end)
AddDrawCallback(function() self:Draw() end)
AddCreateObjCallback(function(o) self:CreateObj(o) end)
AddExitCallback(function() self:Save() end)
AddUnloadCallback(function() self:Save() end)
end
function Zyra:CarryE()
local target = _Pewalk.GetTarget(self.Spells[_E].range)
if target then
local CastPos, HitChance = self:GetPrediction(target, 'E', true)
if CastPos and HitChance > self.Menu.E.HitChance2 then
self:SetWZone(CastPos, _E, 0.22 + (GetDistance(CastPos) / self.Spells[_E].speed), target)
CastSpell(_E, CastPos.x, CastPos.z)
end
end
end
function Zyra:CarryQ()
local target = _Pewalk.GetTarget(self.Spells[_Q].range + self.Spells[_Q].radius)
if target then
local CastPos, HitChance = self:GetPrediction(target, 'Q', false)
if CastPos and HitChance > self.Menu.Q.HitChance2 then
self:SetWZone(CastPos, _Q, 0.9, target)
CastSpell(_Q, CastPos.x, CastPos.z)
end
end
end
function Zyra:CastSpell(iSlot,startPos,endPos,target)
if iSlot == _Q or iSlot == _E then
for i=#self.wZones, 1, -1 do
local zone = self.wZones[i]
if zone and zone.time > clock() and GetDistanceSqr(zone.pos, endPos) < 90000 then
self.wZones[i].valid = true
else
remove(self.wZones, i)
end
end
elseif iSlot == _W then
self.wCasts[clock()] = Vector(endPos)
end
end
function Zyra:Compute(minimum, enemies, validRange, radius, delay, mTeam)
local Targets = {}
for i, e in ipairs(enemies) do
if _Pewalk.ValidTarget(e, validRange) and (mTeam==nil or mTeam==e.team) then
insert(Targets, e)
end
end
for i, e in ipairs(Targets) do
local ppos = self:Position(e, 0.3)
local crcl = {[1] = e, cntr = {x=ppos.x, z=ppos.z}, cntrsm = {x=e.x, z=e.z}, pred = {[1] = ppos},}
for k, e2 in ipairs(Targets) do
if e~=e2 and GetDistanceSqr(crcl.cntr, e2) < radius * radius then
insert(crcl, e2)
local ppos = self:Position(e2, 0.3)
insert(crcl.pred, ppos)
crcl.cntrsm.x = crcl.cntrsm.x + ppos.x
crcl.cntrsm.z = crcl.cntrsm.z + ppos.z
crcl.cntr.x = crcl.cntrsm.x / #crcl
crcl.cntr.z = crcl.cntrsm.z / #crcl
end
end
for k=#crcl, 1, -1 do
local e2= crcl[k]
local escpDst = (delay + (GetLatency() * 0.001)) * e2.ms
if GetDistance(e2, crcl.cntr) > radius-escpDst then
remove(crcl, k)
crcl.cntrsm.x = crcl.cntrsm.x - crcl.pred[k].x
crcl.cntrsm.z = crcl.cntrsm.z - crcl.pred[k].z
crcl.cntr.x = crcl.cntrsm.x / #crcl
crcl.cntr.z = crcl.cntrsm.z / #crcl
remove(crcl.pred, k)
end
end
if #crcl >= minimum and GetDistance(crcl.cntr) < validRange - radius then
return crcl.cntr, crcl
end
end
end
function Zyra:CreateMenu()
self.Menu = scriptConfig('Pew Zyra', 'Zyra')
self.Menu:addSubMenu('Keys', 'Keys')
self.Menu.Keys:addSubMenu('-Skills-', 'SkillsInfo')
self.Menu.Keys:addKey('Jungle', 'Jungle Clear', 17, false)
self.Menu.Keys:setValue('Jungle', false)
self.Menu.Keys:addKey('LaneClear', 'Lane Clear', ('G'):byte(), false)
self.Menu.Keys:setValue('LaneClear', false)
self.Menu.Keys:addKey('Combo', 'Advanced Kill Secure', ('T'):byte(), true)
self.Menu:addSubMenu('Advanced Kill Secure', 'Combo')
self.Menu.Combo:addParam('DrawDC', 'Draw Damage Calcuations', SCRIPT_PARAM_LIST, 1, {'When A.K.S. Active', 'Always', 'Off'})
self.Menu.Combo:addParam('DrawKN', 'Draw Kill Notifcation', SCRIPT_PARAM_LIST, 1, {'Above HP Bar', 'Below HP Bar', 'Off',})
self.Menu:addSubMenu('Deadly Bloom (Q)', 'Q')
self.Menu.Q:addParam('info', '-Farming-', SCRIPT_PARAM_INFO, '')
self.Menu.Q:addParam('Jungle', 'Use in Jungle Clear', SCRIPT_PARAM_ONOFF, true)
self.Menu.Q:addParam('Clear', 'Use in Lane Clear', SCRIPT_PARAM_ONOFF, true)
self.Menu.Q:addParam('Farm', 'Use to Last Hit', SCRIPT_PARAM_ONOFF, true)
self.Menu.Q:addParam('space', '', SCRIPT_PARAM_INFO, '')
self.Menu.Q:addParam('info', '-Combat-', SCRIPT_PARAM_INFO, '')
self.Menu.Q:addParam('HarassLaneClear', 'Harass in Lane Clear', SCRIPT_PARAM_ONOFF, true)
self.Menu.Q:addParam('HarassMixed', 'Harass in Mixed Mode', SCRIPT_PARAM_ONOFF, true)
self.Menu.Q:addParam('CombatCarry', 'Use in Carry Mode', SCRIPT_PARAM_ONOFF, true)
self.Menu.Q:addParam('CombatKS', 'Use to Killsteal', SCRIPT_PARAM_ONOFF, true)
self.Menu.Q:addParam('HitChance2', 'Hit Probability', SCRIPT_PARAM_SLICE, 1.8, 0, 3, 1)
self.Menu.Q:addParam('space', '', SCRIPT_PARAM_INFO, '')
self.Menu.Q:addParam('info', '-Miscellaneous-', SCRIPT_PARAM_INFO, '')
self.Menu.Q:addParam('Draw', 'Draw Range', SCRIPT_PARAM_LIST, 3, { 'Low FPS', 'Normal', 'None', })
self.Menu.Q:addParam('Prediction', 'Prediction Selection', SCRIPT_PARAM_LIST, 1, { 'HPrediction', FHPrediction and 'Fun House Prediction' or 'Fun House Prediction Not Found!', })
self.Menu:addSubMenu('Rampant Growth (W)', 'W')
self.Menu.W:addParam('info', '-Combat-', SCRIPT_PARAM_INFO, '')
self.Menu.W:addParam('CombatCarry', 'Use in Carry Mode', SCRIPT_PARAM_ONOFF, true)
self.Menu.W:addParam('Vision', 'Use On Lose Vision (Grass)', SCRIPT_PARAM_ONOFF, true)
self.Menu.W:addParam('Vision2', 'Lose Vision Min. Seed Count', SCRIPT_PARAM_SLICE, 2, 1, 2)
self.Menu.W:addParam('LaneClear', 'Use in Lane Clear', SCRIPT_PARAM_ONOFF, true)
self.Menu.W:addParam('LaneClear2', 'Lane Clear Min. Seed Count', SCRIPT_PARAM_SLICE, 2, 1, 2)
self.Menu.W:addParam('space', '', SCRIPT_PARAM_INFO, '')
self.Menu.W:addParam('info', '-Miscellaneous-', SCRIPT_PARAM_INFO, '')
self.Menu.W:addParam('Draw', 'Draw Range', SCRIPT_PARAM_LIST, 3, { 'Low FPS', 'Normal', 'None', })
self.Menu.W:addParam('DrawTimer', 'Draw Seed Duration', SCRIPT_PARAM_ONOFF, true)
self.Menu:addSubMenu('Grasping Roots (E)', 'E')
self.Menu.E:addParam('info', '-Farming-', SCRIPT_PARAM_INFO, '')
self.Menu.E:addParam('Jungle', 'Use in Jungle Clear', SCRIPT_PARAM_ONOFF, true)
self.Menu.E:addParam('Clear', 'Use in Lane Clear', SCRIPT_PARAM_ONOFF, true)
self.Menu.E:addParam('Farm', 'Use to Last Hit', SCRIPT_PARAM_ONOFF, false)
self.Menu.E:addParam('space', '', SCRIPT_PARAM_INFO, '')
self.Menu.E:addParam('info', '-Combat-', SCRIPT_PARAM_INFO, '')
self.Menu.E:addParam('HarassLaneClear', 'Harass in Lane Clear', SCRIPT_PARAM_ONOFF, true)
self.Menu.E:addParam('HarassMixed', 'Harass in Mixed Mode', SCRIPT_PARAM_ONOFF, true)
self.Menu.E:addParam('CombatCarry', 'Use in Carry Mode', SCRIPT_PARAM_ONOFF, true)
self.Menu.E:addParam('CombatKS', 'Use to Killsteal', SCRIPT_PARAM_ONOFF, true)
self.Menu.E:addParam('HitChance2', 'Hit Probability', SCRIPT_PARAM_SLICE, 0.9, 0, 3, 1)
self.Menu.E:addParam('space', '', SCRIPT_PARAM_INFO, '')
self.Menu.E:addParam('info', '-Miscellaneous-', SCRIPT_PARAM_INFO, '')
self.Menu.E:addParam('Draw', 'Draw Range', SCRIPT_PARAM_LIST, 3, { 'Low FPS', 'Normal', 'None', })
self.Menu.E:addParam('DrawPrediction', 'Draw Prediction', SCRIPT_PARAM_ONOFF, true)
self.Menu.E:addParam('Prediction', 'Prediction Selection', SCRIPT_PARAM_LIST, 1, { 'HPrediction', FHPrediction and 'Fun House Prediction' or 'Fun House Prediction Not Found!', })
self.Menu:addSubMenu('Stranglethorns (R)', 'R')
self.Menu.R:addParam('info', '-Combat-', SCRIPT_PARAM_INFO, '')
self.Menu.R:addParam('CombatKS', 'Use in Advanced Kill Secure', SCRIPT_PARAM_ONOFF, true)
self.Menu.R:addParam('Efficiency', 'Minimum A.K.S. Efficiency', SCRIPT_PARAM_SLICE, .25, 0, 1, 2)
self.Menu.R:addParam('AutoAlways', 'Auto Use if Can Hit (Anytime)', SCRIPT_PARAM_SLICE, 3, 2, 5)
self.Menu.R:addParam('AutoCarry', 'Auto Use if Can Hit (Carry Mode)', SCRIPT_PARAM_SLICE, 2, 2, 5)
self.Menu.R:addParam('space', '', SCRIPT_PARAM_INFO, '')
self.Menu.R:addParam('3', '-Miscellaneous-', SCRIPT_PARAM_INFO, '')
self.Menu.R:addParam('Draw', 'Draw Range', SCRIPT_PARAM_LIST, 3, { 'Low FPS', 'Normal', 'None', })
self.CurrentQPred = self.Menu.Q.Prediction
self.CurrentEPred = self.Menu.E.Prediction
AddTickCallback(function()
if self.CurrentQPred~=self.Menu.Q.Prediction then
for i, param in ipairs(self.Menu.Q._param) do
if param.var == 'HitChance2' then
if self.Menu.Q.Prediction == 1 then
param.max = 3
self.Menu.Q.HitChance2 = 1.8
else
param.max = 2
self.Menu.Q.HitChance2 = 1.3
end
end
end
self.CurrentQPred = self.Menu.Q.Prediction
end
if self.CurrentEPred~=self.Menu.E.Prediction then
for i, param in ipairs(self.Menu.E._param) do
if param.var == 'HitChance2' then
if self.Menu.E.Prediction == 1 then
param.max = 3
self.Menu.E.HitChance2 = 0.9
else
param.max = 2
self.Menu.E.HitChance2 = 0.8
end
end
end
self.CurrentEPred = self.Menu.E.Prediction
end
end)
end
function Zyra:CreateObj(o)
if o.valid then
if o.name == 'Seed' and o.team == myHero.team and GetDistanceSqr(o) > 10000 then
local duration = 46
for time, endPos in pairs(self.wCasts) do
if clock() - time < 1 and GetDistanceSqr(endPos, o) < 2500 then
duration = 61
end
self.wCasts[time] = nil
end
insert(self.Seeds, #self.Seeds+1, o)
self.Seeds[#self.Seeds].endTime = clock() + duration
end
end
end
function Zyra:Draw()
if myHero.dead then return end
CircleDraw[self.Menu.Q.Draw](myHero, self.Spells[_Q].range, 0xFF0000)
CircleDraw[self.Menu.W.Draw](myHero, self.Spells[_W].range, 0x0000FF)
CircleDraw[self.Menu.E.Draw](myHero, self.Spells[_E].range, 0x00FF00)
CircleDraw[self.Menu.R.Draw](myHero, self.Spells[_R].range, 0xFF9900)
if self.Menu.W.DrawTimer then
for i=#self.Seeds, 1, -1 do
local seed = self.Seeds[i]
if seed and seed.valid then
if not seed.transformed and seed.health ~= 1 then
seed.endTime = clock() + self.PlantDurations[myHero.level < 19 and myHero.level or 18]
seed.transformed = true
end
local timeRemaining = seed.endTime - clock()
if timeRemaining > 10 then
DrawText3D(('%u'):format(timeRemaining),seed.x,seed.y+200,seed.z,22,0xFFFF9900,true)
elseif timeRemaining > 0 then
DrawText3D(('%.1f'):format(timeRemaining),seed.x,seed.y+200,seed.z,22,0xFFFF9900,true)
end
else
remove(self.Seeds, i)
end
end
end
if self.Menu.E.DrawPrediction then
if self.DrawPrediction.Time > clock() and self.DrawPrediction.EndPos then
local EndPos = NormalizeX(self.DrawPrediction.EndPos, self.DrawPrediction.StartPos, self.Spells[_E].range)
local EndArrow = NormalizeX(self.DrawPrediction.EndPos, self.DrawPrediction.StartPos, self.Spells[_E].range-50)
local Perpindicular = Normalize(
EndArrow.x-(EndArrow.x-(self.DrawPrediction.StartPos.z-EndArrow.z)),
EndArrow.z-(EndArrow.z+(self.DrawPrediction.StartPos.x-EndArrow.x))
)
local StartArrow = NormalizeX(self.DrawPrediction.EndPos, self.DrawPrediction.StartPos, 50)
self.PredictionDrawing[1].x = EndArrow.x + (Perpindicular.x*40)
self.PredictionDrawing[1].y = myHero.y
self.PredictionDrawing[1].z = EndArrow.z + (Perpindicular.z*40)
self.PredictionDrawing[2].x = self.DrawPrediction.StartPos.x + (Perpindicular.x*40)
self.PredictionDrawing[2].y = myHero.y
self.PredictionDrawing[2].z = self.DrawPrediction.StartPos.z + (Perpindicular.z*40)
self.PredictionDrawing[3].x = StartArrow.x
self.PredictionDrawing[3].y = myHero.y
self.PredictionDrawing[3].z = StartArrow.z
self.PredictionDrawing[4].x = self.DrawPrediction.StartPos.x + (Perpindicular.x*(-40))
self.PredictionDrawing[4].y = myHero.y
self.PredictionDrawing[4].z = self.DrawPrediction.StartPos.z + (Perpindicular.z*(-40))
self.PredictionDrawing[5].x = EndArrow.x + (Perpindicular.x*(-40))
self.PredictionDrawing[5].y = myHero.y
self.PredictionDrawing[5].z = EndArrow.z + (Perpindicular.z*(-40))
self.PredictionDrawing[6].x = EndPos.x
self.PredictionDrawing[6].y = myHero.y
self.PredictionDrawing[6].z = EndPos.z
self.PredictionDrawing[7] = self.PredictionDrawing[1]
local EndIndicator = NormalizeX(EndPos, StartArrow, (self.Spells[_E].range-102) * self.DrawPrediction.Ratio)
local HitChanceIndicator = NormalizeX(EndPos, StartArrow, (self.Spells[_E].range-102) * (self.Menu.E.HitChance2 / (self.Menu.E.Prediction==1 and 3 or 2)))
DrawLine3D(
HitChanceIndicator.x + (Perpindicular.x*(-30)),
myHero.y,
HitChanceIndicator.z + (Perpindicular.z*(-30)),
HitChanceIndicator.x + (Perpindicular.x*(30)),
myHero.y,
HitChanceIndicator.z + (Perpindicular.z*(30)),
3,
0x78FFFFFF
)
for i=-2, 2, 1 do
DrawLine3D(
self.PredictionDrawing[3].x + (Perpindicular.x*(10*i)),
myHero.y,
self.PredictionDrawing[3].z + (Perpindicular.z*(10*i)),
EndIndicator.x + (Perpindicular.x*(10*i)),
myHero.y,
EndIndicator.z + (Perpindicular.z*(10*i)),
2,
self.DrawPrediction.Color
)
end
DrawLines3D(self.PredictionDrawing,2,0x78FFFFFF)
end
end
self:GetCombo()
if GetInGameTimer() > 4 then
local bar = GetUnitHPBarPos(myHero)
local x, y = bar.x - 68, bar.y - 16 + ((GetUnitHPBarOffset(myHero).y + 0.4) * 44)
DrawLine(x,y,x-30,y,23,0x64000000)
DrawLines2({D3DXVECTOR2(x,y-11),D3DXVECTOR2(x-30,y-11),D3DXVECTOR2(x-30,y+12),D3DXVECTOR2(x,y+12),},2,0xFF474D49)
local mode = _Pewalk.GetActiveMode()
local text1 = mode.Farm and 'FARM' or mode.LaneClear and 'CLEAR' or mode.Mixed and 'MIXED' or mode.Carry and 'CARRY' or self.Menu.Keys.Escape and 'ECP.' or '-----'
DrawText(text1,9,x-14-(GetTextArea(text1, 9).x / 2),y-8,0xFFFFFFFF)
local text2, color = 'OFF', 0xFFFFFFFF
if self.Menu.Keys.Combo then
text2, color = 'ACTIVE', 0xFF00FF00
end
DrawText(text2,9,x-14-(GetTextArea(text2, 9).x / 2),y+2,color)
end
end
function Zyra:FarmQ()
if self.Menu.Q.Farm then
local target = _Pewalk.GetSkillFarmTarget(self.Spells[_Q].delay, self.Spells[_Q].damage, self.Spells[_Q].speed, self.Spells[_Q].range, false)
if target then
CastSpell(_Q, target.x, target.z)
end
end
end
function Zyra:FarmE()
if self.Menu.E.Farm then
local target = _Pewalk.GetSkillFarmTarget(self.Spells[_E].delay, self.Spells[_E].damage(), self.Spells[_E].speed, self.Spells[_E].range, false)
if target then
CastSpell(_E, target.x, target.z)
end
end
end
function Zyra:GetCombo()
if self.ActiveCombo and self.Menu.Keys.Combo then
if self.ActiveCombo.endTime < clock() or not _Pewalk.ValidTarget(self.ActiveCombo.target) then
self.ActiveCombo = nil
else
for i, slot in ipairs(self.ActiveCombo) do
if myHero:CanUseSpell(slot) == READY then
if slot == self.Ignite and _Pewalk.ValidTarget(self.ActiveCombo.target) then
CastSpell(slot, self.ActiveCombo.target)
else
if slot == _Q or slot == _E then
local slotToString = slot == _Q and 'Q' or slot == _E and 'E'
local CP, HC = self:GetPrediction(self.ActiveCombo.target, slotToString, false, true)
if CP then
CastSpell(slot, CP.x, CP.z)
end
elseif slot == _R then
CastSpell(slot, self.ActiveCombo.target.x, self.ActiveCombo.target.z)
end
end
end
end
end
end
for i, enemy in ipairs(self.Enemies) do
if _Pewalk.ValidTarget(enemy) then
local qDamage, wDamage, eDamage, rDamage, iDamage, tDamage = 0, 0, 0, 0, 0, 0
local magicReduction = 100 / (100 + ((enemy.magicArmor * myHero.magicPenPercent) - myHero.magicPen))
local RemainingMana = myHero.mana
local finalCombo = {}
local distance = GetDistanceSqr(enemy)
if self.qReady then
qDamage = self.Spells[_Q].damage() * magicReduction
if distance < 640000 then
local CP, HC = self:GetPrediction(enemy, 'Q', false, true)
if HC > .5 then
tDamage = qDamage
finalCombo[1] = {slot=_Q, pos=CP}
RemainingMana = RemainingMana - self.Spells[_Q].mana()
end
end
end
if self.eReady then
eDamage = self.Spells[_E].damage() * magicReduction
if distance < 640000 then
local CP, HC = self:GetPrediction(enemy, 'E', false, true)
if HC > .5 and tDamage < enemy.health then
finalCombo[#finalCombo + 1] = {slot=_E, pos=CP}
tDamage = tDamage + eDamage
RemainingMana = RemainingMana - self.Spells[_E].mana()
end
end
end
if self.wReady then
if qDamage~=0 or eDamage~=0 then
wDamage = (46 + (13 * myHero.level) + (.4 * myHero.ap)) * magicReduction
if finalCombo[1] and tDamage < enemy.health then
finalCombo[#finalCombo + 1] = {slot=_W, pos=finalCombo[1].pos}
tDamage = tDamage + wDamage
end
end
end
if self.rReady then
rDamage = self.Spells[_R].damage() * magicReduction
if distance < 490000 and tDamage < enemy.health and enemy.health - tDamage > rDamage * self.Menu.R.Efficiency then
finalCombo[#finalCombo + 1] = {slot=_R, pos=CP}
tDamage = tDamage + rDamage
RemainingMana = RemainingMana - self.Spells[_R].mana()
end
end
if self.iReady and tDamage < enemy.health then
iDamage = 50 + (myHero.level * 20)
if distance < 302500 then
finalCombo[#finalCombo + 1] = {slot=self.Ignite, target=enemy}
tDamage = tDamage + iDamage
end
end
if self.Menu.Combo.DrawDC == 2 or (self.Menu.Combo.DrawDC == 1 and self.Menu.Keys.Combo) then
if PewtilityHPBars and PewtilityHPBars.Active then
PewtilityHPBars.Addon[enemy.networkID] = {}
if qDamage > 0 then
insert(PewtilityHPBars.Addon[enemy.networkID], {
['color'] = 0xAAFFAABB,
['damage'] = qDamage,
['text'] = 'Q',
})
end
if wDamage > 0 then
insert(PewtilityHPBars.Addon[enemy.networkID], {
['color'] = 0xAA99AA00,
['damage'] = wDamage,
['text'] = 'W',
})
end
if eDamage > 0 then
insert(PewtilityHPBars.Addon[enemy.networkID], {
['color'] = 0xAA0099BB,
['damage'] = eDamage,
['text'] = 'E',
})
end
if rDamage > 0 then
insert(PewtilityHPBars.Addon[enemy.networkID], {
['color'] = 0xAA336644,
['damage'] = rDamage,
['text'] = 'R',
})
end
if iDamage > 0 then
insert(PewtilityHPBars.Addon[enemy.networkID], {
['color'] = 0xAA22BB94,
['damage'] = iDamage,
['text'] = 'I',
})
end
PewtilityHPBars.Addon[enemy.networkID].bMana = RemainingMana > 0
else
local Center = GetUnitHPBarPos(enemy)
if Center.x > -100 and Center.x < WINDOW_W+100 and Center.y > -100 and Center.y < WINDOW_H+100 then
local Offset = GetUnitHPBarOffset(enemy)
local y = Center.y + (Offset.y * 53) + 2
local x = Center.x + ((self.xOffsets[enemy.charName] or 0) * 140) - 66
local xo = x + ((enemy.health / enemy.maxHealth) * 104)
if qDamage > 0 and xo > x then
local ax = (qDamage / enemy.maxHealth) * 104
local bx = xo - ax
DrawLine(bx>x and bx or x,y,xo,y,9,0xAAFFAABB)
DrawText('Q',11,xo+2,y-4,0xFFFFFFFF)
xo = bx
if xo < x then return end
end
if wDamage > 0 and xo > x then
local ax = (wDamage / enemy.maxHealth) * 104
local bx = xo - ax
DrawLine(bx>x and bx or x,y,xo,y,9,0xAA99AA00)
DrawText('W',11,xo+2,y-4,0xFFFFFFFF)
xo = bx
if xo < x then return end
end
if eDamage > 0 and xo > x then
local ax = (eDamage / enemy.maxHealth) * 104
local bx = xo - ax
DrawLine(bx>x and bx or x,y,xo,y,9,0xAA0099BB)
DrawText('E',11,xo+2,y-4,0xFFFFFFFF)
xo = bx
if xo < x then return end
end
if rDamage > 0 and xo > x then
local ax = (rDamage / enemy.maxHealth) * 104
local bx = xo - ax
DrawLine(bx>x and bx or x,y,xo,y,9,0xAA336644)
DrawText('R',11,xo+2,y-4,0xFFFFFFFF)
xo = bx
end
if iDamage > 0 and xo > x then
local ax = (iDamage / enemy.maxHealth) * 104
local bx = xo - ax
DrawLine(bx>x and bx or x,y,xo,y,9,0xAA22BB94)
DrawText('I',11,xo+2,y-4,0xFFFFFFFF)
xo = bx
end
if self.Menu.Combo.DrawKN < 3 and tDamage > enemy.health then
DrawText(
RemainingMana > 0 and 'Can Kill!' or 'Need More Mana!!',
16,
x,
y + (self.Menu.Combo.DrawKN == 1 and -22 or 14),
0xFFFFFFFF
)
end
end
end
end
if tDamage > enemy.health and (not self.ActiveCombo or self.ActiveCombo.endTime < clock()) then
self.ActiveCombo = {
endTime = clock() + 2,
target = enemy,
}
for _, info in ipairs(finalCombo) do
self.ActiveCombo[#self.ActiveCombo+1] = info.slot
end
end
end
end
end
function Zyra:GetPrediction(target, spell, draw, hpOnly)
for i, buff in pairs(_Pewalk.GetBuffs(target)) do
if self.CrowdControl[buff.type] then
return target, 3
end
end
if self.Menu[spell].Prediction == 2 and FHPrediction and not hpOnly then
self.FH_Q.radius = 95 + target.boundingRadius
local CastPos, HitChance = FHPrediction.GetPrediction(self['FH_'..spell], target, myHero)
if draw and CastPos then
self.DrawPrediction.EndPos = CastPos
self.DrawPrediction.StartPos = myHero
self.DrawPrediction.Time = clock() + 1
self.DrawPrediction.Ratio = math.min(1, HitChance / self.Menu.E.HitChance2)
self.DrawPrediction.Color = ARGB(185, (1.25-self.DrawPrediction.Ratio) * 255, self.DrawPrediction.Ratio * 200, 0)
end
return CastPos, HitChance
else
self.HP_Q.Properties.Raw.radius = 95 + target.boundingRadius
local CastPos, HitChance = self.HP:GetPredict(self['HP_'..spell], target, myHero)
if draw then
self.DrawPrediction.EndPos = CastPos
self.DrawPrediction.StartPos = {x=myHero.x, y=myHero.y, z=myHero.z}
self.DrawPrediction.Time = clock() + 1
self.DrawPrediction.Ratio = math.min(1, HitChance / self.Menu.E.HitChance2)
self.DrawPrediction.Color = ARGB(255, (1-self.DrawPrediction.Ratio) * 255, self.DrawPrediction.Ratio * 255, 0)
self.DrawPrediction.Chance = HitChance
end
return CastPos, HitChance
end
end
function Zyra:JungleE()
local eMinions = {}
for i, minion in ipairs(_Pewalk.GetMinions()) do
if _Pewalk.ValidTarget(minion, self.Spells[_E].range + 100, true) and minion.team == 300 then
eMinions[#eMinions + 1] = minion.hasMovePath and NormalizeX(minion.endPath, minion, 150) or minion
end
end
local nMinions = #eMinions
if nMinions > 1 then
local highHit = {['count'] = 0,}
for i, iMin in ipairs(eMinions) do
if GetDistanceSqr(iMin) < self.Spells[_E].rangeSqr then
local ePos = NormalizeX(iMin, myHero, self.Spells[_E].range)
local d1 = Normalize(myHero.x-(myHero.x-(myHero.z-ePos.z)), myHero.z-(myHero.z+(myHero.x-ePos.x)))
self.ePolygon.points[1].x, self.ePolygon.points[1].z = myHero.x + d1.x*-128, myHero.z + (d1.z*(-128))
self.ePolygon.points[2].x, self.ePolygon.points[2].z = myHero.x + d1.x*128, myHero.z + (d1.z*128)
self.ePolygon.points[3].x, self.ePolygon.points[3].z = ePos.x + d1.x*128, ePos.z + (d1.z*128)
self.ePolygon.points[4].x, self.ePolygon.points[4].z = ePos.x + d1.x*-128, ePos.z + (d1.z*(-128))
local count = 1
for f, eMin in ipairs(eMinions) do
if i~=f and self.ePolygon:contains(eMin.x, eMin.z) then
count = count+1
end
end
if highHit.count < count then
highHit.count = count
highHit.minion = iMin
end
end
end
if highHit.count >= nMinions - 1 then
CastSpell(_E, highHit.minion.x, highHit.minion.z)
end
elseif nMinions == 1 then
CastSpell(_E, eMinions[1].x, eMinions[1].z)
end
end
function Zyra:JungleQ()
if _Pewalk.CanMove() then
local CP, Hits = self:Compute(1, _Pewalk.GetMinions(), 1060, 260, 0.1, 300)
if CP then
for _, unit in ipairs(Hits) do
if self.JungleW[unit.charName] then
self:SetWZone(CP, _Q, 0.85, unit)
end
end
CastSpell(_Q, CP.x, CP.z)
return
end
end
end
function Zyra:LaneE()
local eMinions = {}
for i, minion in ipairs(_Pewalk.GetMinions()) do
if _Pewalk.ValidTarget(minion, self.Spells[_E].range + 100, true) and minion.team == TEAM_ENEMY then
eMinions[#eMinions + 1] = minion.hasMovePath and NormalizeX(minion.endPath, minion, 150) or minion
end
end
local nMinions = #eMinions
if nMinions > 1 then
local highHit = {['count'] = 0,}
for i, iMin in ipairs(eMinions) do
if GetDistanceSqr(iMin) < self.Spells[_E].rangeSqr then
local ePos = NormalizeX(iMin, myHero, self.Spells[_E].range)
local d1 = Normalize(myHero.x-(myHero.x-(myHero.z-ePos.z)), myHero.z-(myHero.z+(myHero.x-ePos.x)))
self.ePolygon.points[1].x, self.ePolygon.points[1].z = myHero.x + (d1.x*(-128)), myHero.z + (d1.z*(-128))
self.ePolygon.points[2].x, self.ePolygon.points[2].z = myHero.x + (d1.x*128), myHero.z + (d1.z*128)
self.ePolygon.points[3].x, self.ePolygon.points[3].z = ePos.x + (d1.x*128), ePos.z + (d1.z*128)
self.ePolygon.points[4].x, self.ePolygon.points[4].z = ePos.x + (d1.x*(-128)), ePos.z + (d1.z*(-128))
local count = 1
for f, eMin in ipairs(eMinions) do
if i~=f and self.ePolygon:contains(eMin.x, eMin.z) then
count = count+1
end
end
if highHit.count < count then
highHit.count = count
highHit.minion = iMin
end
end
end
if highHit.count >= nMinions * 0.67 or highHit.count > 6 and self:WindWalkCheck(myHero, highHit.minion) then
CastSpell(_E, highHit.minion.x, highHit.minion.z)
if self.Menu.W.LaneClear and self.wCount > self.Menu.W.LaneClear2-1 then
self:SetWZone(highHit.minion, _E, 0.85, nil, true)
end
end
end
end
function Zyra:LaneQ()
if _Pewalk.CanMove() then
local CP = self:Compute(3, _Pewalk.GetMinions(), 1060, 260, 0.1, TEAM_ENEMY)
if CP then
CastSpell(_Q, CP.x, CP.z)
if self.Menu.W.LaneClear and self.wCount > self.Menu.W.LaneClear2-1 then
self:SetWZone(CP, _Q, 0.85, nil, true)
end
return
end
end
end
function Zyra:NewPath(unit,startPos,endPos,isDash,dashSpeed,dashGravity,dashDistance)
if unit.valid and unit.type == 'AIHeroClient' and unit.team == TEAM_ENEMY then
if isDash then
if GetDistanceSqr(endPos, startPos) > 62500 then
self.Dashing[unit.networkID].time = clock() + (GetDistance(startPos, endPos) / dashSpeed)
self.Dashing[unit.networkID].endPos = {x=endPos.x, z=endPos.z,}
self.Dashing[unit.networkID].startPos = {x=startPos.x, z=startPos.z,}
end
elseif endPos.x~=self.LastPaths[unit.networkID].pos.x then
self.LastPaths[unit.networkID].pos = Vector(endPos)
self.LastPaths[unit.networkID].time = clock()
end
end
end
function Zyra:Position(unit, delay)
local Waypoints = {[1] = { ['x'] = unit.x, ['z'] = unit.z, },}
local pathPotential = unit.ms * delay
if unit.hasMovePath then
for i = unit.pathIndex, unit.pathCount do
local p = unit:GetPath(i)
Waypoints[#Waypoints+1] = { ['x'] = p.x, ['z'] = p.z, }
end
else
return Waypoints[1]
end
for i = 1, #Waypoints - 1 do
local CurrentDistance = GetDistance(Waypoints[i], Waypoints[i + 1])
if pathPotential < CurrentDistance then
return NormalizeX(Waypoints[i + 1], Waypoints[i], pathPotential)
elseif i == (#Waypoints - 1) then
return Waypoints[i + 1]
end
pathPotential = pathPotential - CurrentDistance
end
return Waypoints[1]
end
function Zyra:RecvPacket(p)
if p.header == self.Packets.Header then
p.pos=self.Packets.Pos
local o = objManager:GetObjectByNetworkId(p:DecodeF())
if o and o.valid and o.type == 'AIHeroClient' and o.team == TEAM_ENEMY then
local CastPos = self:Position(o, 0.75)
if IsWallOfGrass(D3DXVECTOR3(CastPos.x,myHero.y,CastPos.z)) then
self.Spells[_W].Active[#self.Spells[_W].Active+1] = {
['unit'] = o,
['startTime'] = clock(),
['endTime'] = clock() + 0.5,
['pos'] = CastPos,
}
end
end
end
end
function Zyra:Save()
if not SAVE_FILE.Menu then SAVE_FILE.Menu = {} end
for i, entry in ipairs(self.Menu._param) do
SAVE_FILE.Menu[entry.var] = entry
SAVE_FILE.Menu[entry.var].Value = self.Menu[entry.var]
end
local function iterateMenu(m)
for i, subMenu in ipairs(m._subInstances) do
iterateMenu(subMenu)
for _, entry in ipairs(subMenu._param) do
if not SAVE_FILE.Menu[subMenu.name] then SAVE_FILE.Menu[subMenu.name] = {} end
SAVE_FILE.Menu[subMenu.name][entry.var] = entry
SAVE_FILE.Menu[subMenu.name][entry.var].Value = subMenu[entry.var]
end
end
end
iterateMenu(self.Menu)
local file = io.open(LIB_PATH..'/Saves/PewZyra.save', 'w')
file:write(JSON:encode(SAVE_FILE))
file:close()
end
function Zyra:SetWZone(pos, spell, time, target, removeAfterCast)
self.wZones[#self.wZones + 1] = {
['pos'] = {['x'] = pos.x, ['y'] = pos.y or myHero.y, ['z'] = pos.z,},
['spell'] = spell,
['time'] = clock() + time,
['valid'] = false,
['target'] = target,
['removeAfterCast'] = removeAfterCast,
}
end
function Zyra:Tick()
self.qReady = myHero:CanUseSpell(_Q) == READY
self.wReady = myHero:CanUseSpell(_W) == READY
self.eReady = myHero:CanUseSpell(_E) == READY
self.rReady = myHero:CanUseSpell(_R) == READY
self.iReady = self.Ignite and myHero:CanUseSpell(self.Ignite) == READY
self.wCount = self.wReady and myHero:GetSpellData(_W).stacks or 0 --ReadDWORD(GetPtrS(myHero:GetSpellData(_W))+0x18)
local OM = _Pewalk.GetActiveMode()
_Pewalk.AllowAttack(not (OM.Carry and self.eReady))
if self.wReady then
if self.Menu.W.Vision and self.wCount > self.Menu.W.Vision2-1 then
for i=#self.Spells[_W].Active, 1, -1 do
local active = self.Spells[_W].Active[i]
if not active.unit.visible and active.endTime > clock() then
if active.startTime < clock() and GetDistanceSqr(active.pos) < self.Spells[_W].rangeSqr then
CastSpell(_W, active.pos.x, active.pos.z)
table.remove(self.Spells[_W].Active, i)
end
else
table.remove(self.Spells[_W].Active, i)
end
end
end
for i=#self.wZones, 1, -1 do
local zone = self.wZones[i]
if zone and zone.time > clock() then
if zone.valid and GetDistanceSqr(zone.pos) < self.Spells[_W].rangeSqr then
CastSpell(_W, zone.pos.x, zone.pos.z)
if zone.spell == _E or zone.removeAfterCast then
remove(self.wZones, i)
end
end
else
remove(self.wZones, i)
end
end
end
if Evade or not _Pewalk.CanMove() then return end
if self.Menu.Keys.LaneClear then
if self.qReady then
if self.Menu.Q.Clear then
self:LaneQ()
self.LastLaneQ = clock() + 1.1
end
elseif self.eReady and self.Menu.E.Clear then
if not self.LastLaneQ or self.LastLaneQ < clock() then
self:LaneE()
end
end
end
if self.Menu.Keys.Jungle then
if self.qReady and self.Menu.Q.Jungle then
self:JungleQ()
end
if self.eReady and self.Menu.E.Jungle then
self:JungleE()
end
end
if OM.Carry then
if self.Menu.Q.CombatCarry and self.qReady then
self:CarryQ()
end
if self.eReady and self.Menu.E.CombatCarry then
self:CarryE()
end
elseif OM.LaneClear then
if self.qReady then
self:FarmQ()
if self.Menu.Q.HarassLaneClear and not _Pewalk.WaitForMinion() and not self.Menu.Keys.LaneClear then
self:CarryQ()
end
end
if self.eReady then
self:FarmE()
if self.Menu.E.HarassLaneClear and not _Pewalk.WaitForMinion() and not self.Menu.Keys.LaneClear then
self:CarryE()
end
end
elseif OM.Mixed then
if self.qReady and self.Menu.Q.HarassMixed and not _Pewalk.WaitForMinion() then
self:CarryQ()
end
if self.eReady and self.Menu.E.HarassMixed then
self:CarryE()
end
elseif OM.Farm then
if self.qReady then
self:FarmQ()
end
if self.eReady then
self:FarmE()
end
end
if self.rReady then
local CP = self:Compute(OM.Carry and self.Menu.R.AutoCarry or self.Menu.R.AutoAlways, self.Enemies, 1260, 560, 0.3)
if CP then
CastSpell(_R, CP.x, CP.z)
end
end
end
function Zyra:WindWallCheck(StartPos, EndPos)
if self.WindWall == nil then
self.WindWall = {}
for i, enemy in ipairs(self.Enemies) do
if enemy.charName == 'Yasuo' then
AddCreateObjCallback(function(o)
if o.valid and o.type == 'MissileClient' and o.spellOwner then
if o.spellOwner.charName == 'Yasuo' and o.spellOwner.team ~= myHero.team then
if o.spellName:lower() == 'yasuowmovingwallmisl' then
self.WindWall.Left = o
elseif o.spellName:lower() == 'yasuowmovingwallmisr' then
self.WindWall.Right = o
end
end
end
end)
end
end
end
if self.WindWall.Left and self.WindWall.Left.valid and self.WindWall.Right and self.WindWall.Right.valid then
local wL, wR = NormalizeX(self.WindWall.Right, self.WindWall.Left, -85), NormalizeX(self.WindWall.Left, self.WindWall.Right, -85)
local cS, cE = NormalizeX(EndPos, StartPos, -85), NormalizeX(StartPos, EndPos, -85)
local ab = ((wR.z - cS.z) * (wL.x - cS.x) - (wL.z - cS.z) * (wR.x - cS.x) <= 0)
local ba = ((wR.z - cE.z) * (wL.x - cE.x) - (wL.z - cE.z) * (wR.x - cE.x) <= 0)
if ab ~= ba then
local cd = ((wL.z - cS.z) * (cE.x - cS.x) - (cE.z - cS.z) * (wL.x - cS.x) <= 0)
local dc = ((wR.z - cS.z) * (cE.x - cS.x) - (cE.z - cS.z) * (wR.x - cS.x) <= 0)
if cd ~= dc then
wL.x,wR.x,cS.x,cE.x=wL.x+.0001,wR.x+.001,cS.x+.01,cE.x+.1
local a, b, c, d = cS.x - cE.x, wL.x - wR.x, cS.z - cE.z, wL.z - wR.z
if b * c - d * a ~= 0 then
return false
end
end
end
end
return true
end
class 'CreatePolygon'
function CreatePolygon:__init(...)
self.points = {...}
end
function CreatePolygon:contains(px, pz)
if #self.points == 3 then
local p1, p2, p3 = self.points[1], self.points[2], self.points[3]
local VERTEX_A = ((pz - p1.z) * (p2.x - p1.x)) - ((px - p1.x) * (p2.z - p1.z))
local VERTEX_B = ((pz - p2.z) * (p3.x - p2.x)) - ((px - p2.x) * (p3.z - p2.z))
local VERTEX_C = ((pz - p3.z) * (p1.x - p3.x)) - ((px - p3.x) * (p1.z - p3.z))
return (VERTEX_A * VERTEX_B >= 0 and VERTEX_B * VERTEX_C >= 0)
else
for j, triangle in ipairs(self:triangulate()) do
if triangle:contains(px, pz) then
return true
end
end
return false
end
end
function CreatePolygon:triangulate()
if not self.triangles then
self.triangles = {}
local nVertices = #self.points
if nVertices > 3 then
if nVertices == 4 then
insert(self.triangles, CreatePolygon(self.points[1], self.points[2], self.points[3]))
insert(self.triangles, CreatePolygon(self.points[1], self.points[3], self.points[4]))
end
elseif #self.points == 3 then
insert(self.triangles, self)
end
end
return self.triangles
end
function CreatePolygon:intersects(x1, z1, x2, z2)
for i=1, #self.points-1 do
local lx1, lz1, lx2, lz2 = self.points[i].x, self.points[i].z, self.points[i+1].x, self.points[i+1].z
if ((z2 - lz1) * (x1 - lx1) - (z1 - lz1) * (x2 - lx1) <= 0) ~= ((z2 - lz2) * (x1 - lx2) - (z1 - lz2) * (x2 - lx2) <= 0) then
if ((z1 - lz1) * (lx2 - lx1) - (lz2 - lz1) * (x1 - lx1) <= 0) ~= ((z2 - lz1) * (lx2 - lx1) - (lz2 - lz1) * (x2 - lx1) <= 0) then
return true
end
end
end
local lx1, lz1, lx2, lz2 = self.points[1].x, self.points[1].z, self.points[#self.points].x, self.points[#self.points].z
if ((z2 - lz1) * (x1 - lx1) - (z1 - lz1) * (x2 - lx1) <= 0) ~= ((z2 - lz2) * (x1 - lx2) - (z1 - lz2) * (x2 - lx2) <= 0) then
if ((z1 - lz1) * (lx2 - lx1) - (lz2 - lz1) * (x1 - lx1) <= 0) ~= ((z2 - lz1) * (lx2 - lx1) - (lz2 - lz1) * (x2 - lx1) <= 0) then
return true
end
end
return false
end
function scriptConfig:addKey(var, name, key, defaultToggle)
local sub = scriptConfig(name, var, self)
sub:addParam(var, 'Key', defaultToggle and SCRIPT_PARAM_ONKEYTOGGLE or SCRIPT_PARAM_ONKEYDOWN, false, key)
sub:addParam(var..'Toggle', 'Toggle', SCRIPT_PARAM_ONOFF, defaultToggle)
AddTickCallback(function()
self[var] = sub[var]
self[var..'_param'] = sub._param[1]
self[var..'_param'].isToggle = sub[var..'Toggle']
if sub.lastToggle ~= sub[var..'Toggle'] then
sub.lastToggle = sub[var..'Toggle']
sub._param[1].pType = sub[var..'Toggle'] and SCRIPT_PARAM_ONKEYTOGGLE or SCRIPT_PARAM_ONKEYDOWN
end
end)
AddMsgCallback(function(m,k)
if m==256 and self[var..'_param'] and k==self[var..'_param'].key then
self[var] = true
end
end)
end
local o_OnDraw = scriptConfig.OnDraw
function scriptConfig:OnDraw()
if #self._subInstances > 0 or #self._param > 0 then
o_OnDraw(self)
end
end
function scriptConfig:setValue(var, value)
for i, instance in ipairs(self._subInstances) do
if instance.name == var then
for k, param in ipairs(instance._param) do
if param.var == var then
instance[var] = value
end
end
end
end
end
class "ScriptUpdate"
function ScriptUpdate:__init(LocalVersion,UseHttps, Host, VersionPath, ScriptPath, SavePath, CallbackUpdate, CallbackNoUpdate, CallbackNewVersion,CallbackError)
self.LocalVersion = LocalVersion
self.Host = Host
self.VersionPath = '/BoL/TCPUpdater/GetScript'..(UseHttps and '5' or '6')..'.php?script='..self:Base64Encode(self.Host..VersionPath)..'&rand='..math.random(99999999)
self.ScriptPath = '/BoL/TCPUpdater/GetScript'..(UseHttps and '5' or '6')..'.php?script='..self:Base64Encode(self.Host..ScriptPath)..'&rand='..math.random(99999999)
self.SavePath = SavePath
self.CallbackUpdate = CallbackUpdate
self.CallbackNoUpdate = CallbackNoUpdate
self.CallbackNewVersion = CallbackNewVersion
self.CallbackError = CallbackError
self:CreateSocket(self.VersionPath)
self.DownloadStatus = 'Connect to Server for VersionInfo'
AddTickCallback(function() self:GetOnlineVersion() end)
end
function ScriptUpdate:print(str)
print(''..os.clock()..': '..str)
end
function ScriptUpdate:OnDraw()
if self.DownloadStatus ~= 'Downloading Script (100%)' and self.DownloadStatus ~= 'Downloading VersionInfo (100%)'then
DrawText('Download Status: '..(self.DownloadStatus or 'Unknown'),50,10,50,ARGB(0xFF,0xFF,0xFF,0xFF))
end
end
function ScriptUpdate:CreateSocket(url)
if not self.LuaSocket then
self.LuaSocket = require("socket")
else
self.Socket:close()
self.Socket = nil
self.Size = nil
self.RecvStarted = false
end
self.LuaSocket = require("socket")
self.Socket = self.LuaSocket.tcp()
self.Socket:settimeout(0, 'b')
self.Socket:settimeout(99999999, 't')
self.Socket:connect('sx-bol.eu', 80)
self.Url = url
self.Started = false
self.LastPrint = ""
self.File = ""
end
function ScriptUpdate:Base64Encode(data)
local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
return ((data:gsub('.', function(x)
local r,b='',x:byte()
for i=8,1,-1 do r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0') end
return r;
end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
if (#x < 6) then return '' end
local c=0
for i=1,6 do c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0) end
return b:sub(c+1,c+1)
end)..({ '', '==', '=' })[#data%3+1])
end
function ScriptUpdate:GetOnlineVersion()
if self.GotScriptVersion then return end
self.Receive, self.Status, self.Snipped = self.Socket:receive(1024)
if self.Status == 'timeout' and not self.Started then
self.Started = true
self.Socket:send("GET "..self.Url.." HTTP/1.1\r\nHost: sx-bol.eu\r\n\r\n")
end
if (self.Receive or (#self.Snipped > 0)) and not self.RecvStarted then
self.RecvStarted = true
self.DownloadStatus = 'Downloading VersionInfo (0%)'
end
self.File = self.File .. (self.Receive or self.Snipped)
if self.File:find('') then
if not self.Size then
self.Size = tonumber(self.File:sub(self.File:find('')+6,self.File:find('')-1))
end
if self.File:find('') then
local _,ScriptFind = self.File:find('')
local ScriptEnd = self.File:find('')
if ScriptEnd then ScriptEnd = ScriptEnd - 1 end
local DownloadedSize = self.File:sub(ScriptFind+1,ScriptEnd or -1):len()
self.DownloadStatus = 'Downloading VersionInfo ('..math.round(100/self.Size*DownloadedSize,2)..'%)'
end
end
if self.File:find('') then
self.DownloadStatus = 'Downloading VersionInfo (100%)'
local a,b = self.File:find('\r\n\r\n')
self.File = self.File:sub(a,-1)
self.NewFile = ''
for line,content in ipairs(self.File:split('\n')) do
if content:len() > 5 then
self.NewFile = self.NewFile .. content
end
end
local HeaderEnd, ContentStart = self.File:find('')
local ContentEnd, _ = self.File:find('')
if not ContentStart or not ContentEnd then
if self.CallbackError and type(self.CallbackError) == 'function' then
self.CallbackError()
end
else
self.OnlineVersion = (Base64Decode(self.File:sub(ContentStart + 1,ContentEnd-1)))
self.OnlineVersion = tonumber(self.OnlineVersion)
if self.OnlineVersion > self.LocalVersion then
if self.CallbackNewVersion and type(self.CallbackNewVersion) == 'function' then
self.CallbackNewVersion(self.OnlineVersion,self.LocalVersion)
end
self:CreateSocket(self.ScriptPath)
self.DownloadStatus = 'Connect to Server for ScriptDownload'
AddDrawCallback(function() self:OnDraw() end)
AddTickCallback(function() self:DownloadUpdate() end)
else
if self.CallbackNoUpdate and type(self.CallbackNoUpdate) == 'function' then
self.CallbackNoUpdate(self.LocalVersion)
end
end
end
self.GotScriptVersion = true
end
end
function ScriptUpdate:DownloadUpdate()
if self.GotScriptUpdate then return end
self.Receive, self.Status, self.Snipped = self.Socket:receive(1024)
if self.Status == 'timeout' and not self.Started then
self.Started = true
self.Socket:send("GET "..self.Url.." HTTP/1.1\r\nHost: sx-bol.eu\r\n\r\n")
end
if (self.Receive or (#self.Snipped > 0)) and not self.RecvStarted then
self.RecvStarted = true
self.DownloadStatus = 'Downloading Script (0%)'
end
self.File = self.File .. (self.Receive or self.Snipped)
if self.File:find('') then
if not self.Size then
self.Size = tonumber(self.File:sub(self.File:find('')+6,self.File:find('')-1))
end
if self.File:find('') then
local _,ScriptFind = self.File:find('')
local ScriptEnd = self.File:find('')
if ScriptEnd then ScriptEnd = ScriptEnd - 1 end
local DownloadedSize = self.File:sub(ScriptFind+1,ScriptEnd or -1):len()
self.DownloadStatus = 'Downloading Script ('..math.round(100/self.Size*DownloadedSize,2)..'%)'
end
end
if self.File:find('') then
self.DownloadStatus = 'Downloading Script (100%)'
local a,b = self.File:find('\r\n\r\n')
self.File = self.File:sub(a,-1)
self.NewFile = ''
for line,content in ipairs(self.File:split('\n')) do
if content:len() > 5 then
self.NewFile = self.NewFile .. content
end
end
local HeaderEnd, ContentStart = self.NewFile:find('')
local ContentEnd, _ = self.NewFile:find('')
if not ContentStart or not ContentEnd then
if self.CallbackError and type(self.CallbackError) == 'function' then
self.CallbackError()
end
else
local newf = self.NewFile:sub(ContentStart+1,ContentEnd-1)
local newf = newf:gsub('\r','')
if newf:len() ~= self.Size then
if self.CallbackError and type(self.CallbackError) == 'function' then
self.CallbackError()
end
return
end
local newf = Base64Decode(newf)
if type(load(newf)) ~= 'function' then
if self.CallbackError and type(self.CallbackError) == 'function' then
self.CallbackError()
end
else
local f = io.open(self.SavePath,"w+b")
f:write(newf)
f:close()
if self.CallbackUpdate and type(self.CallbackUpdate) == 'function' then
self.CallbackUpdate(self.OnlineVersion,self.LocalVersion)
end
end
end
self.GotScriptUpdate = true
end
end