--[[
Library designed to make my live easier
Simply automatically integrates things I have in all my scripts to make life easier.
It reduces code in my own scripts and makes it more readable.
Changelog:
* 0.1:
Release
* 0.2:
Fixed a typo (unit > target)
* 0.22
Few more bug fixes
* 0.25
Chargeable spell support
* 0.26
Fixed typo in Prediction helper
Added support for Chargeable spells, this will soon be completely
Deleted DFG in ItemSupport
* 0.27
Fixed spam with barrier
* 0.28
Updated some stuff to current standards
* 0.29
Cleaned up 2 lines
* 0.35
Fixed support for chargeable spells
* 0.36
My bad, forgot to remove debugging stuff
* 0.40
Added Chargeable spell support in SpellHelper class
Added Build-In support for HPRed + DivinePred - only thing that needs to be added by user is DP & HPred instances
* 0.41
Better HPred support
* 0.42 Crash fix
* 0.43 Another crash fix
--]]
_G.GetInventorySlotItem = function(id) return end
local version = 0.43
local AUTO_UPDATE = true
local UPDATE_HOST = "raw.github.com"
local UPDATE_PATH = "/Nickieboy/BoL/master/lib/TotallyLib.lua".."?rand="..math.random(1,10000)
local UPDATE_FILE_PATH = LIB_PATH.."TotallyLib.lua"
local UPDATE_URL = "https://"..UPDATE_HOST..UPDATE_PATH
function AutoupdaterMsg(msg) print("TotallyLib: "..msg..".") end
if AUTO_UPDATE then
local ServerData = GetWebResult(UPDATE_HOST, "/Nickieboy/BoL/master/version/TotallyLib.version")
if ServerData then
ServerVersion = type(tonumber(ServerData)) == "number" and tonumber(ServerData) or nil
if ServerVersion then
if tonumber(version) < ServerVersion then
AutoupdaterMsg("New version available (v"..ServerVersion .. ")")
AutoupdaterMsg("Updating, please don't press F9")
DelayAction(function() DownloadFile(UPDATE_URL, UPDATE_FILE_PATH, function () AutoupdaterMsg("Successfully updated. ("..version.." => "..ServerVersion.."), press F9 twice to load the updated version.") end) end, 3)
else
AutoupdaterMsg("You have got the latest version ("..ServerVersion..")")
end
end
else
AutoupdaterMsg("Error downloading version info")
end
end
_G.TotallyLib_Loaded = true
class 'MenuMisc'
function MenuMisc:__init(Menu, includeSummoners)
assert(Menu, "Menu not found. Not able to load the Menu")
Menu:addSubMenu("Auto Potions", "autopotions")
Menu.autopotions:addParam("usePotion", "Use Potions Automatically", SCRIPT_PARAM_ONOFF, true)
Menu.autopotions:addParam("health", "Health under %", SCRIPT_PARAM_SLICE, 0.25, 0, 0.9, 2)
Menu.autopotions:addParam("mana", "Mana under %", SCRIPT_PARAM_SLICE, 0.25, 0, 0.9, 2)
Menu:addSubMenu("Zhyonas", "zhonyas")
Menu.zhonyas:addParam("zhonyas", "Auto Zhonyas", SCRIPT_PARAM_ONOFF, true)
Menu.zhonyas:addParam("zhonyasunder", "Use Zhonyas under % health", SCRIPT_PARAM_SLICE, 0.20, 0, 1 , 2)
if includeSummoners == true then
Summoners(Menu)
end
self.menu = Menu
self.isRecalling = false
self.healthActive = false
self.manaActive = false
AddTickCallback(function() self:OnTick() end)
AddCreateObjCallback(function(obj) self:OnCreateObj(obj) end)
AddDeleteObjCallback(function(obj) self:OnDeleteObj(obj) end)
AddApplyBuffCallback(function(source, unit, buff) self:ApplyBuff(source, unit, buff) end)
AddRemoveBuffCallback(function(unit, buff) self:RemoveBuff(unit, buff) end)
end
function MenuMisc:ApplyBuff(source, unit, buff)
if source and source.isMe and buff and buff.name then
if buff.name:find("RegenerationPotion") then
self.healthActive = true
end
if buff.name:find("FlaskOfCrystalWater") then
self.manaActive = true
end
end
end
function MenuMisc:RemoveBuff(unit, buff)
if unit and unit.isMe and buff and buff.name then
if buff.name:find("RegenerationPotion") then
self.healthActive = false
end
if buff.name:find("FlaskOfCrystalWater") then
self.manaActive = false
end
end
end
function MenuMisc:DrinkPotions()
if not self.healthActive and not self.isRecalling and not InFountain() then
local healthSlot = GetInventorySlotItem(2003)
if healthSlot ~= nil then
if (myHero.health / myHero.maxHealth <= self.menu.autopotions.health) then
CastSpell(healthSlot)
end
end
end
if not self.manaActive and not self.isRecalling and not InFountain() then
local manaSlot = GetInventorySlotItem(2004)
if manaSlot ~= nil then
if (myHero.mana / myHero.maxMana <= self.menu.autopotions.mana) then
CastSpell(manaSlot)
end
end
end
end
function MenuMisc:CheckZhonyas()
local zhonyasSlot = GetInventorySlotItem(3157)
if zhonyasSlot ~= nil and IsSpellReady(zhonyasSlot) then
if (myHero.health / myHero.maxHealth) <= self.menu.zhonyas.zhonyasunder then
CastSpell(zhonyasSlot)
end
end
end
function MenuMisc:OnCreateObj(obj)
if obj and obj.name and obj.name:find("TeleportHome.troy") then
if GetDistance(obj) <= 50 then
self.isRecalling = true
end
end
end
function MenuMisc:OnDeleteObj(obj)
if obj and obj.name and obj.name:find("TeleportHome.troy") then
if GetDistance(obj) <= 50 then
self.isRecalling = false
end
end
end
function MenuMisc:OnTick()
if self.menu.autopotions.usePotion then self:DrinkPotions() end
if self.menu.zhonyas.zhonyas then self:CheckZhonyas() end
end
bufflist = {
["zedulttargetmark"] = {spellname = "Death Mark", spell = "R", charName = "Zed"}, --correct
["surpression"] = {spellname = "Infinite Duress", spell = "R", charName = "Warwick"}, -- Only QSS
["paranoiamisschance"] = {spellname = "Terrify", spell = "Q", charName = "Fiddlestick"}, --correct
["puncturingtauntarmordebuff"] = {spellname = "Puncturing Taunt", spell = "E", charName = "Rammus"}, --
--["Teemo"] = {spellname = "Blinding Dart", spell = "R", charName = "Teemo"}, --
--["Ahri"] = {spellname = "Charm", spell = "E", charName = "Ahri"}, --
["curseofthesadmummy"] = {spellname = "Curse of the Sad Mummy", spell = "R", charName = "Amumu"}, --correct
["enchantedcrystalarrow"] = {spellname = "Enchanted Crystal Arrow", spell = "R", charName = "Ashe"}, --correct
["Malzahar"] = {spellname = "Nether Grasp", spell = "R", charName = "Malzahar"}, --
--["Skarner"] = {spellname = "Impale", spell = "R", charName = "Skarner"}, --
["veigarstun"] = {spellname = "Primordial Burst", spell = "E", charName = "Veigar"}, --correct
["nasusw"] = {spellname = "Wither", spell = "W", charName = "Nasus"}
}
class 'Summoners'
function Summoners:__init(menu)
self.enemyNames = {}
self:UpdateSummoners()
if menu then
self:LoadToMenu(menu)
end
AddTickCallback(function() self:OnTick() end)
AddApplyBuffCallback(function(source, unit, buff) self:OnApplyBuff(source, unit, buff) end)
end
function Summoners:LoadToMenu(menu)
self.menu = menu
if self.heal ~= nil then
self.menu:addSubMenu("Auto Heal", "autoheal")
self.menu.autoheal:addParam("useHeal", "Use Summoner Heal", SCRIPT_PARAM_ONOFF, true)
self.menu.autoheal:addParam("amountOfHealth", "Under % of health", SCRIPT_PARAM_SLICE, 0.25, 0, 1, 2)
self.menu.autoheal:addParam("helpHeal", "Use Heal to save teammates", SCRIPT_PARAM_ONOFF, false)
end
if self.ignite ~= nil then
self.menu:addSubMenu("Auto Ignite", "autoignite")
self.menu.autoignite:addParam("useIgnite", "Use Summoner Ignite", SCRIPT_PARAM_ONOFF, true)
for i, enemy in ipairs(GetEnemyHeroes()) do
self.menu.autoignite:addParam(enemy.charName, "Use Ignite On " .. enemy.charName, SCRIPT_PARAM_ONOFF, true)
end
end
if self.barrier ~= nil then
self.menu:addSubMenu("Auto Barrier", "autobarrier")
self.menu.autobarrier:addParam("useBarrier", "Use Summoner Barrier", SCRIPT_PARAM_ONOFF, true)
self.menu.autobarrier:addParam("amountOfHealth", "Under % of health", SCRIPT_PARAM_SLICE, 0, 0, 1, 2)
end
if self.cleanse ~= nil then
self.menu:addSubMenu("Auto Cleanse", "autocleanse")
self.menu.autocleanse:addParam("useCleanse", "Use Cleanse", SCRIPT_PARAM_ONOFF, true)
for i, enemy in ipairs(GetEnemyHeroes()) do
if enemy then
table.insert(self.enemyNames, enemy.charName)
end
end
local oneAdded = false
for buff, data in ipairs(bufflist) do
if buff and data and table.contains(self.enemyNames, data.charName) then
oneAdded = true
self.menu.autocleanse:addParam(buff, data.spellname .. " - " .. data.charName .. " (" .. data.spell .. ")", SCRIPT_PARAM_ONOFF, true)
end
end
if not oneAdded then
self.menu.autocleanse:addParam("info", "ERROR", SCRIPT_PARAM_INFO, "No buffs found to be added")
end
end
end
function Summoners:OnApplyBuff(source, unit, buff)
if unit and buff and buff.name and self.cleanse ~= nil and self.menu.autocleanse.useCleanse and self.menu.autocleanse[buff.name] and unit and unit.isMe then
if IsSpellReady(self.cleanse) then
CastSpell(self.cleanse)
end
end
end
function Summoners:UpdateSummoners()
self.heal = GetSummonerSlot("summonerheal")
self.ignite = GetSummonerSlot("summonerdot")
self.barrier = GetSummonerSlot("summonerbarrier")
self.cleanse = GetSummonerSlot("summonerboost")
end
function Summoners:UseHeal()
if IsSpellReady(self.heal) then
if (myHero.health / myHero.maxHealth) <= self.menu.autoheal.amountOfHealth then
CastSpell(self.heal)
end
end
if self.menu.autoheal.helpHeal then
for i, teammate in ipairs(GetAllyHeroes()) do
if GetDistanceSqr(teammate, myHero) <= 700 * 700 then
if (teammate.health / teammate.maxHealth) <= self.menu.autoheal.amountOfHealth then
if IsSpellReady(self.heal) then
CastSpell(self.heal)
end
end
end
end
end
end
function Summoners:Ignite()
for i, enemy in ipairs(GetEnemyHeroes()) do
if GetDistance(enemy, myHero) < 600 and ValidTarget(enemy, 600) and self.menu.autoignite[enemy.charName] then
if myHero:CanUseSpell(self.ignite) == READY then
if enemy.health < self:IgniteDamage() then
CastSpell(self.ignite, enemy)
end
end
end
end
end
function Summoners:IgniteDamage()
return (50 + (20 * myHero.level))
end
function Summoners:Barrier()
if myHero:CanUseSpell(self.barrier) == READY then
if ((myHero.health / myHero.maxHealth) <= self.menu.autobarrier.amountOfHealth) then
CastSpell(self.barrier)
end
end
end
function Summoners:OnTick()
if self.heal ~= nil and self.menu.autoheal.useHeal then self:UseHeal() end
if self.ignite ~= nil and self.menu.autoignite.useIgnite then self:Ignite() end
if self.barrier ~= nil and self.menu.autobarrier.useBarrier then self:Barrier() end
end
class 'SpellHelper'
function SpellHelper:__init(VP, menu)
self.Spells = {}
self.divineLoaded = false
self.HSLoaded = false
if VP and menu then
self.Predict = PredictionHelper(VP, menu)
elseif VP and not menu then
self.VP = VP
end
end
function SpellHelper:InitializePrediction(menu)
self.Predict = PredictionHelper(self.VP)
if self.divineLoaded then
self.Predict:DivinePred(self.DP)
self.Predict:AddCircleSS(self.CircleSS)
self.Predict:AddLineSS(self.LineSS)
end
if self.HSLoaded then
self.Predict:AddHPred(self.HS)
end
self.Predict:LoadToMenu(menu)
end
function SpellHelper:AddDivinePrediction(DP, addSpells)
self.divineLoaded = true
self.DP = DP
self.CircleSS = {}
self.LineSS = {}
if addSpells then
for slot, data in pairs(self.Spells) do
if self.Spells[slot].skillShot then
if self.Spells[slot].typeSkill:find("line") then
local collision = 0
if self.Spells[slot].collision == false then
collision = math.huge
end
self.LineSS[slot] = LineSS(self.Spells[slot].speed, self.Spells[slot].range, self.Spells[slot].radius, (self.Spells[slot].delay * 1000), collision)
elseif self.Spells[slot].typeSkill:find("circ") then
local collision = 0
if self.Spells[slot].collision == false then
collision = math.huge
end
self.CircleSS[slot] = CircleSS(self.Spells[slot].speed, self.Spells[slot].range, self.Spells[slot].radius, (self.Spells[slot].delay * 1000), collision)
end
end
end
end
end
function SpellHelper:AddDP(typeSkill, slot)
if self.divineLoaded then
if typeSkill then
if typeSkill == "Line" then
local collision = 0
if self.Spells[slot].collision == false then
collision = math.huge
end
self.LineSS[slot] = LineSS(self.Spells[slot].speed, self.Spells[slot].range, self.Spells[slot].radius, (self.Spells[slot].delay * 1000), collision)
elseif typeSkill == "Circle" then
local collision = 0
if self.Spells[slot].collision == false then
collision = math.huge
end
self.CircleSS[slot] = CircleSS(self.Spells[slot].speed, self.Spells[slot].range, self.Spells[slot].radius, (self.Spells[slot].delay * 1000), collision)
end
end
end
end
function SpellHelper:HPredStyle(slot, typeHS)
if not typeHS then return end
if typeHS ~= "DelayLine" and typeHS ~= "PromptLine" and typeHS ~= "DelayCircle" and typeHS ~= "PromptCircle" then print("TotallyLib: Not a Valid HPred Type") return end
self.Spells[slot].hPredStyle = typeHS
end
function SpellHelper:AddHPred(HS, addSpells)
self.HS = HS
self.HSLoaded = true
self.HSSpells = {}
if addSpells then
for slot, data in pairs(self.Spells) do
if self.Spells[slot].skillShot then
if self.Spells[slot].hPredStyle then
if myHero.charName:lower() == "xerath" and slot == _Q then
else
if self.Spells[slot].hPredStyle:find("circle") then
self.HS:AddSpell(slotToString(slot), myHero.charName, {collisionM = self.Spells[slot].collision, collisionH = self.Spells[slot].collision, delay = self.Spells[slot].delay, range = self.Spells[slot].range, speed = self.Spells[slot].speed, type = self.Spells[slot].hPredStyle, radius = self.Spells[slot].radius})
--self.HSSpells[slot] = HPSkillshot({type = self.Spells[slot].hPredStyle, delay = self.Spells[slot].delay, range = self.Spells[slot].range, speed = self.Spells[slot].speed, radius = self.Spells[slot].radius, collisionM = self.Spells[slot].collision, collisionH = self.Spells[slot].collision})
else
self.HS:AddSpell(slotToString(slot), myHero.charName, {collisionM = self.Spells[slot].collision, collisionH = self.Spells[slot].collision, delay = self.Spells[slot].delay, range = self.Spells[slot].range, speed = self.Spells[slot].speed, type = self.Spells[slot].hPredStyle, width = self.Spells[slot].radius})
--self.HSSpells[slot] = HPSkillshot({type = self.Spells[slot].hPredStyle, delay = self.Spells[slot].delay, range = self.Spells[slot].range, speed = self.Spells[slot].speed, width = self.Spells[slot].radius, collisionM = self.Spells[slot].collision, collisionH = self.Spells[slot].collision})
end
end
self.HS:AddSpell(slotToString(slot), myHero.charName, {collisionM = self.Spells[slot].collision, collisionH = self.Spells[slot].collision, delay = self.Spells[slot].delay, range = self.Spells[slot].range, speed = self.Spells[slot].speed, type = self.Spells[slot].hPredStyle, radius = self.Spells[slot].radius})
else
if self.Spells[slot].typeSkill == "circ" or self.Spells[slot].typeSkill == "circaoe" then
--self.HSSpells[slot] = HPSkillshot({type = "DelayCircle", delay = self.Spells[slot].delay, range = self.Spells[slot].range, speed = self.Spells[slot].speed, radius = self.Spells[slot].radius, collisionM = self.Spells[slot].collision, collisionH = self.Spells[slot].collision})
self.HS:AddSpell(slotToString(slot), myHero.charName, {collisionM = self.Spells[slot].collision, collisionH = self.Spells[slot].collision, delay = self.Spells[slot].delay, range = self.Spells[slot].range, speed = self.Spells[slot].speed, type = "DelayCircle", radius = self.Spells[slot].radius})
elseif self.Spells[slot].typeSkill == "line" or self.Spells[slot].typeSkill == "lineaoe" then
--self.HSSpells[slot] = HPSkillshot({type = "DelayLine", delay = self.Spells[slot].delay, range = self.Spells[slot].range, speed = self.Spells[slot].speed, width = self.Spells[slot].radius, collisionM = self.Spells[slot].collision, collisionH = self.Spells[slot].collision})
self.HS:AddSpell(slotToString(slot), myHero.charName, {collisionM = self.Spells[slot].collision, collisionH = self.Spells[slot].collision, delay = self.Spells[slot].delay, range = self.Spells[slot].range, speed = self.Spells[slot].speed, type = "DelayLine", width = self.Spells[slot].radius})
end
end
end
end
end
end
function SpellHelper:AddSpell(slot, range)
self.Spells[slot] = {slot = slot, range = range, skillShot = false}
end
function SpellHelper:AddSkillShot(slot, range, delay, width, speed, collision, typeSkill)
self.Spells[slot] = {slot = slot, range = range, delay = delay, radius = width, width = width, speed = speed, collision = collision, typeSkill = typeSkill, skillShot = true, isChargeable = false}
end
function SpellHelper:Ready(slot)
return IsSpellReady(self.Spells[slot].slot)
end
function SpellHelper:InRange(slot, target)
return GetDistanceSqr(target) < self.Spells[slot].range * self.Spells[slot].range
end
function SpellHelper:ChangeRange(slot, range)
self.Spells[slot].range = range
if self.Spells[slot].skillShot then
if self.divineLoaded then
local SS = nil
if self.Spells[slot].typeSkill:find("line") then
local collision = 0
if self.Spells[slot].collision == false then
collision = math.huge
end
SS = LineSS(self.Spells[slot].speed, self.Spells[slot].range, self.Spells[slot].radius, (self.Spells[slot].delay * 1000), collision)
elseif self.Spells[slot].typeSkill:find("circ") then
local collision = 0
if self.Spells[slot].collision == false then
collision = math.huge
end
SS = CircleSS(self.Spells[slot].speed, self.Spells[slot].range, self.Spells[slot].radius, (self.Spells[slot].delay * 1000), collision)
end
self.Predict:ChangeDPred(slot, SS)
end
if self.HSLoaded then
self.HS:AddSpell(slotToString(slot), myHero.charName, {collisionM = self.Spells[slot].collision, collisionH = self.Spells[slot].collision, delay = self.Spells[slot].delay, range = self.Spells[slot].range, speed = self.Spells[slot].speed, type = "DelayCircle", radius = self.Spells[slot].radius})
self.Predict:ChangeHPred(self.HS)
end
end
end
function SpellHelper:GetRange(slot)
return self.Spells[slot].range
end
function SpellHelper:SetCharged(slot, spellname, minrange, maxRange, chargeduration, timeToMax, objectName)
self.Spells[slot].isChargeable = true
self.chargedSlot = slot
self.name = spellname
self.minRange = minrange
self.range = minrange
self.maxRange = maxRange
self.timeToMax = timeToMax
self.isCharged = false
self.chargeDuration = chargeduration
self.objectName = objectName
AddTickCallback(function() self:OnTick() end)
AddProcessSpellCallback(function(unit, spell) self:OnProcessSpell(unit, spell) end)
AddCreateObjCallback(function(obj) self:OnCreateObj(obj) end)
AddDeleteObjCallback(function(obj) self:OnDeleteObj(obj) end)
end
function SpellHelper:GetChargedRange()
return math.floor(self.range)
end
function SpellHelper:OnTick()
if not self.isCharged and self.range ~= self.minRange then
self.range = self.minRange
end
if self.isCharged and self.chargedTime + ((self.timeToMax + self.chargeDuration) + 1) < os.clock() then
self.isCharged = false
self.range = self.minRange
end
if self:IsCharging() then
self.range = (math.min(self.initialRange + (self.maxRange - self.initialRange) * ((os.clock() - self.chargedTime) / self.timeToMax), self.maxRange))
end
end
function SpellHelper:OnCreateObj(obj)
if obj and obj.name == self.objectName and GetDistance(obj, myHero) <= 50 then
self.isCharged = true
end
end
function SpellHelper:OnDeleteObj(obj)
if obj and obj.name == self.objectName and GetDistance(obj, myHero) <= 50 then
self.isCharged = false
end
end
function SpellHelper:OnProcessSpell(unit, spell)
if spell.name == self.name and not self.isCharged then
self.isCharged = true
self.initialRange = self.range
self.chargedTime = os.clock()
end
end
function SpellHelper:IsCharging()
return self.isCharged
end
function SpellHelper:ForceCharge(value)
self.isCharged = value
end
function SpellHelper:CastCharged(slot, target)
if self.Spells[slot].isChargeable then
if not self.isCharged then
CastSpell(slot, mousePos.x, mousePos.z)
else
if target and target.type and target.type == myHero.type then
local castPosition = self.Predict:PredictSpell(target, self.Spells[slot].delay, self.Spells[slot].width, self.range, self.Spells[slot].speed, self.Spells[slot].collision, self.Spells[slot].typeSkill, self.Spells[slot].slot)
if castPosition and not castPosition.y then
castPosition.y = 0
end
if castPosition then
CastSpell2(slot, D3DXVECTOR3(castPosition.x, castPosition.y, castPosition.z))
end
elseif target then
if target and not target.y then
target.y = 0
end
CastSpell2(slot, D3DXVECTOR3(target.x, target.y, target.z))
end
end
end
end
function SpellHelper:Cast(slot, target, value)
if self.Spells[slot].skillShot then
if target and value then
if self:Ready(self.Spells[slot].slot) and GetDistanceSqr(Point(target, value)) <= self.Spells[slot].range * self.Spells[slot].range then
CastSpell(self.Spells[slot].slot, target, value)
return true
end
elseif target and not value then
local castPosition = self.Predict:PredictSpell(target, self.Spells[slot].delay, self.Spells[slot].width, self.Spells[slot].range, self.Spells[slot].speed, self.Spells[slot].collision, self.Spells[slot].typeSkill, self.Spells[slot].slot)
if castPosition ~= nil and self:Ready(self.Spells[slot].slot) and self:InRange(self.Spells[slot].slot, target) then
CastSpell(self.Spells[slot].slot, castPosition.x, castPosition.z)
return true
end
end
else
if not value and target then
if self:Ready(self.Spells[slot].slot) and self:InRange(self.Spells[slot].slot, target) then
CastSpell(self.Spells[slot].slot, target)
return true
end
elseif value and target then
if self:Ready(self.Spells[slot].slot) and GetDistanceSqr(Point(target, value)) <= self.Spells[slot].range * self.Spells[slot].range then
CastSpell(self.Spells[slot].slot, target.x, value.z)
return true
end
end
end
return false
end
function SpellHelper:CastAll(target, value)
for i, info in ipairs(self.Spells) do
self:Cast(info.slot, target, value)
end
end
class 'PredictionHelper'
function PredictionHelper:__init(VP, menu)
self.VP = VP
self.divineLoaded = false
self.HSLoaded = false
if menu then
self:LoadToMenu(menu)
end
end
function PredictionHelper:DivinePred(DP)
self.divineLoaded = true
self.DP = DP
self.enemyDPTable = {}
for i, enemy in pairs(GetEnemyHeroes()) do
if enemy and enemy.type and enemy.type == myHero.type then
self.enemyDPTable[enemy.networkID] = DPTarget(enemy)
end
end
self.CircleSS = {}
self.LineSS = {}
end
function PredictionHelper:AddCircleSS(table)
self.CircleSS = table
end
function PredictionHelper:AddLineSS(table)
self.LineSS = table
end
function PredictionHelper:ChangeDPred(slot, SS)
if slot and SS then
if self.LineSS[slot] ~= nil then
self.LineSS[slot] = SS
elseif self.CircleSS[slot] ~= nil then
self.CircleSS[slot] = SS
end
end
end
function PredictionHelper:AddHPred(HS)
self.HS = HS
self.HSLoaded = true
end
function PredictionHelper:ChangeHPred(HS)
self.HS = HS
end
function PredictionHelper:LoadToMenu(Menu)
Menu:addSubMenu("Prediction Type", "prediction")
if self.VP and self.HSLoaded and self.divineLoaded then
Menu.prediction:addParam("type", "Prediction:", SCRIPT_PARAM_LIST, 2, {"Normal", "VPrediction", "DivinePrediction", "HPrediction"})
elseif self.VP and self.divineLoaded and not self.HSLoaded then
Menu.prediction:addParam("type", "Prediction:", SCRIPT_PARAM_LIST, 2, {"Normal", "VPrediction", "DivinePrediction"})
elseif self.VP and not self.divineLoaded and self.HSLoaded then
Menu.prediction:addParam("type", "Prediction:", SCRIPT_PARAM_LIST, 2, {"Normal", "VPrediction", "HPrediction"})
elseif self.VP and not self.divineLoaded and not self.HSLoaded then
Menu.prediction:addParam("type", "Prediction:", SCRIPT_PARAM_LIST, 2, {"Normal", "VPrediction"})
end
Menu.prediction:addParam("hitchance", "Hitchance", SCRIPT_PARAM_LIST, 2, {"Low hitchance", "High HitChance", "Slowed", "Immobile"})
self.menu = Menu
end
function PredictionHelper:DivineLoaded()
return self.divineLoaded and self.menu.prediction.type == 3
end
function PredictionHelper:HPredLoaded()
return (self.HSLoaded and self.divineLoaded and self.menu.prediction.type == 4) or (self.HSLoaded and not self.divineLoaded and self.menu.prediction.type == 3)
end
function PredictionHelper:PredictSpell(target, delay, radius, range, speed, collision, typeSkill, slot)
if self.menu.prediction.type == 1 then
local castPosition, coll = TargetPrediction(range, speed, delay, radius):GetPrediction(target)
if collision == true and not coll then
return castPosition
elseif not collision then
return castPosition
end
elseif self.menu.prediction.type == 2 then
if typeSkill == "circaoe" then
local castPosition, hitChance = self.VP:GetCircularAOECastPosition(target, delay, radius, range, speed, myHero, collision)
if hitChance >= self.menu.prediction.hitchance then
return castPosition
end
elseif typeSkill == "lineaoe" then
local castPosition, hitChance = self.VP:GetLineAOECastPosition(target, delay, radius, range, speed, myHero)
if hitChance >= self.menu.prediction.hitchance then
return castPosition
end
elseif typeSkill == "line" then
local castPosition, hitChance = self.VP:GetLineCastPosition(target, delay, radius, range, speed, myHero, collision)
if hitChance >= self.menu.prediction.hitchance then
return castPosition
end
elseif typeSkill == "circ" then
local castPosition, hitChance = self.VP:GetCircularCastPosition(target, delay, radius, range, speed, myHero, collision)
if hitChance >= self.menu.prediction.hitchance then
return castPosition
end
end
elseif self:DivineLoaded() then
local tempDivineTarget = nil
if self.enemyDPTable[target.networkID] ~= nil then
tempDivineTarget = self.enemyDPTable[target.networkID]
end
if tempDivineTarget then
local SS = nil
if typeSkill == "line" or typeSkill == "lineaoe" then
SS = self.LineSS[slot]
elseif typeSkill == "circ" or typeSkill == "circaoe" then
SS = self.CircleSS[slot]
end
if SS then
local state, hitPos, perc = self.DP:predict(tempDivineTarget, SS)
if state and state == SkillShot.STATUS.SUCCESS_HIT and hitPos ~= nil then
return hitPos
end
end
end
elseif self:HPredLoaded() then
local CastPos, HitChance = nil, 0
if myHero.charName == "Xerath" and slot == _Q then
CastPos, HitChance = self.HS:GetPredict(HPrediction.Presets['Xerath']["Q"], target, myHero)
else
CastPos, HitChance = self.HS:GetPredict(slotToString(slot), target, myHero)
end
if CastPos and HitChance and type(HitChance) >= "number" and HitChance >= 0 then
return CastPos
end
end
return nil
end
class 'ChargeSpell'
function ChargeSpell:__init(slot, spellname, minrange, maxRange, chargeduration, timeToMax, objectName)
self.slot = slot
self.name = spellname
self.minRange = minrange
self.range = minrange
self.maxRange = maxRange
self.timeToMax = timeToMax
self.isCharged = false
self.chargeDuration = chargeduration
self.objectName = objectName
AddTickCallback(function() self:OnTick() end)
AddProcessSpellCallback(function(unit, spell) self:OnProcessSpell(unit, spell) end)
AddCreateObjCallback(function(obj) self:OnCreateObj(obj) end)
AddDeleteObjCallback(function(obj) self:OnDeleteObj(obj) end)
end
function ChargeSpell:OnTick()
if not self.isCharged and self.range ~= self.minRange then
self.range = self.minRange
end
if self.isCharged and self.chargedTime + ((self.timeToMax + self.chargeDuration) + 1) < os.clock() then
self.isCharged = false
self.range = self.minRange
end
if self:IsCharging() then
self.range = (math.min(self.initialRange + (self.maxRange - self.initialRange) * ((os.clock() - self.chargedTime) / self.timeToMax), self.maxRange))
end
end
function ChargeSpell:OnCreateObj(obj)
if obj and obj.name == self.objectName and GetDistance(obj, myHero) <= 50 then
self.isCharged = true
end
end
function ChargeSpell:OnDeleteObj(obj)
if obj and obj.name == self.objectName and GetDistance(obj, myHero) <= 50 then
self.isCharged = false
end
end
function ChargeSpell:OnProcessSpell(unit, spell)
if spell.name == self.name and not self.isCharged then
self.isCharged = true
self.initialRange = self.range
self.chargedTime = os.clock()
end
end
function ChargeSpell:IsCharging()
return self.isCharged
end
function ChargeSpell:ForceCharge(value)
self.isCharged = value
end
function ChargeSpell:Cast(pos)
if not self.isCharged then
CastSpell(self.slot, mousePos.x, mousePos.z)
else
if not pos.y then
pos.y = 0
end
CastSpell2(self.slot, D3DXVECTOR3(pos.x, pos.y, pos.z))
end
end
itemlist = {
["Athene's Unholy Grail"] = 3174,
["Avarice Blade"] = 3093,
["Blade of The Ruined King"] = 3153,
["bortk"] = 3153,
["Crystalline Flask"] = 2041,
["Dervish Blade"] = 3137,
["Zhonya's Hourglass"] = 3157,
["zhonyas"] = 3003,
["zhonya's"] = 3003,
["Randuin's Omen"] = 3143,
["Hextech Gunblade"] = 3146,
["Bilgdewater Cutlass"] = 3144,
["Ravenous Hydra"] = 3074,
["hydra"] = 3074,
["Tiamat"] = 3077,
["Youmuu's Ghostblade"] = 3142,
["Blackfire Torch"] = 3188,
["Health Potion"] = 2003,
["Mana Potion"] = 2004,
["Ichor of Rage"] = "",
["Oracle's Extract"] = 2047,
["Stealth Ward"] = 2044,
["Vision Ward"] = 2043,
["Sightstone"] = 2049,
["Ruby Sightstone"] = 2045,
["Total Biscuit of Rejuvenation"] = 2009
}
class 'ItemHelper'
function ItemHelper:__init(name)
self.name = name
self.id = self.list[name]
end
function ItemHelper:GetId()
if self.id then
return self.id
end
end
function ItemHelper:IsCastable()
if self.id then
return GetInventoryItemIsCastable(self.id)
end
end
function ItemHelper:GetSlot()
if self.id then
return GetInventorySlotItem(self.id)
end
end
function slotToString(slot)
if slot == _Q then
return "Q"
elseif slot == _W then
return "W"
elseif slot == _E then
return "E"
elseif slot == _R then
return "R"
end
end
function IsSpellReady(spell)
return myHero:CanUseSpell(spell) == READY
end
function GetSummonerSlot(name)
return ((myHero:GetSpellData(SUMMONER_1).name:find(name) and SUMMONER_1) or (myHero:GetSpellData(SUMMONER_2).name:find(name) and SUMMONER_2))
end
-- Return number of Ally in range
function CountAllyHeroInRange(range, object)
assert(range and type(range) == "number", "TotallyLib: Invalid range. Range must be specified AND it must be a number")
object = object or myHero
range = range and range * range or myHero.range * myHero.range
local AllyHeroInRange = 0
for i = 1, heroManager.iCount, 1 do
local hero = heroManager:getHero(i)
if hero.team == object.team and GetDistanceSqr(object, hero) <= range then
AllyHeroInRange = AllyHeroInRange + 1
end
end
return AllyHeroInRange
end
--[[
Returns Vector object in a certain position (Useful for: Flash, Orbwalk within mouse range, Gapclosing...)
@param target --- Must be target or the largest position of what you are trying to achieve
@param range --- Must be range between you and possible newPosition (Not range between you & target)
@param Source --- Must be a source, either myHero or a different
--]]
function VectorHelper(target, range, source)
return (Vector(source.visionPos) + (Vector(target) - source.visionPos):normalized() * range)
end
--[[
Calculates the position to hit as many objects as possible within a recent radius limited between a range
Returns the position (of the object)
Returns the count (Of many objects it will hit)
--]]
function GetBestAOEPosition(objects, range, radius, source)
assert(objects and type(objects) == "table", "TotallyLib: Invalid Objects in function GetBestAOEPosition")
local pos = nil
local count2 = 0
local source = source or myHero
local range = (range and range * range) or myHero.range * myHero.range
for i, object in ipairs(objects) do
if GetDistanceSqr(object, source) < range then
local count = 0
for i, ob in ipairs(objects) do
if GetDistanceSqr(ob, object) <= radius * radius then
count = count + 1
end
end
if count > count2 then
count2 = count
pos = object.pos
end
end
end
return pos, count2
end
function CountEnemies(min_targets, range)
local min_targets = min_targets and min_targets or 0
assert(type(min_targets) == "number", "TotallyLib: First Parameter must be a number")
local count, enemies, pos = 0, {}, nil
local range = (range and range * range) or (myHero.range * myHero.range)
for i, enemy in ipairs(GetEnemyHeroes()) do
if GetDistanceSqr(enemy, myHero) <= range then
enemies = {}
table.insert(enemies, enemy.charName)
count = 0
for i, Tenemy in ipairs(GetEnemyHeroes()) do
if enemy ~= Tenemy then
if GetDistance(Tenemy, enemy) < Spells.W.radius then
count = count + 1
table.insert(enemies, Tenemy.charName)
end
end
end
if count >= min_targets then
pos = enemy.pos
break
end
end
end
return pos, enemies, count
end
--[[ Calculates all minions that can be killed through a spell
Damage is calculated through Spell Damage Library (Build-in)
Returns the minions as a table
-- ]]
function GetKillableMinions(minionTable, range, spell, source)
assert(spell == _Q or spell == _W or spell == _E, "TotallyLib: Correct spell not detected")
assert(minionTable and type(minionTable) == "table", "TotallyLib: Invalid table in: minionTable, first parameter")
assert(source and source.type and source.type == myHero.type "TotallyLib: Invalid Source. The type must be obj_AI_Hero")
local range = range and range * range or myHero
local minions = {}
local source = source or myHero
local dmg = 0
for i, minion in ipairs(minionTable) do
if GetDistanceSqr(minion) < range then
if spell == _AA then
dmg = CalcDamage(minion, myHero.damage)
elseif spell == _Q then
dmg = CalcMagicDamage(minion, getDmg("Q", minion, source))
elseif spell == _W then
dmg = CalcMagicDamage(minion, getDmg("W", minion, source))
elseif spell == _E then
dmg = CalcMagicDamage(minion, getDmg("E", minion, source))
end
if minion.health < dmg then
table.insert(minions, minion)
end
end
end
return minions
end
function GetBestLineFarmPosition(range, width, objects)
local BestPos
local BestHit = 0
for i, object in ipairs(objects) do
local EndPos = Vector(myHero) + range * (Vector(object) - Vector(myHero)):normalized()
local hit = CountObjectsOnLineSegment(myHero, EndPos, width, objects)
if hit > BestHit then
BestHit = hit
BestPos = Vector(object)
if BestHit == #objects then
break
end
end
end
return BestPos, BestHit
end
function CountObjectsOnLineSegment(StartPos, EndPos, width, objects)
local n = 0
for i, object in ipairs(objects) do
local pointSegment, pointLine, isOnSegment = VectorPointProjectionOnLineSegment(StartPos, EndPos, object)
if isOnSegment and GetDistanceSqr(pointSegment, object) < width * width then
n = n + 1
end
end
return n
end
function CountMinions(objectTable, range)
assert(objectTable and type(objectTable) == "table", "TotallyLib: Invalid table in: objectTable, first parameter")
local range = range and range * range or myHero.range * myHero.range
local count = 0
for i, object in ipairs(objectTable) do
if ValidTarget(object) and GetDistanceSqr(myHero, object) <= range then
count = count + 1
end
end
return count
end