--[[
.d8b. d8b db d888888b d888888b d8888b. .d8b. .d8888. d88888b db db db d888888b
d8' `8b 888o 88 `~~88~~' `88' 88 `8D d8' `8b 88' YP 88' 88 88 88 `~~88~~'
88ooo88 88V8o 88 88 88 88oooY' 88ooo88 `8bo. 88ooooo 88 88 88 88
88~~~88 88 V8o88 88 88 88~~~b. 88~~~88 `Y8b. 88~~~~~ 88 88 88 88
88 88 88 V888 88 .88. 88 8D 88 88 db 8D 88. 88b d88 88booo. 88
YP YP VP V8P YP Y888888P Y8888P' YP YP `8888Y' Y88888P ~Y8888P' Y88888P YP
Anti BaseUlt - Never fear a BaseUlt again!
Changelog:
April 19, 2016 [r1.5]:
- Added Bol-Tools Tracker.
April 16, 2016 [r1.4]:
- Fixed a bug with the Auto-Updater.
April 16, 2016 [r1.3]:
- Improved the performance of the Script.
April 07, 2016 [r1.2]:
- Fixed a bug that was causing the Debug option to create errors.
April 04, 2016 [r1.1]:
- Improved a bit the menu.
- Added a Debug Option.
April 04, 2016 [r1.0]:
- First Release.
]]--
local Script =
{
Name = "Anti BaseUlt",
Version = 1.5
}
local function Print(string)
print("" .. Script.Name .. ": " .. string .. "")
end
class "ABUpdater"
local random, round = math.random, math.round
function ABUpdater:__init(LocalVersion, Host, Path, LocalPath, CallbackUpdate, CallbackNoUpdate, CallbackNewVersion, CallbackError)
self.LocalVersion = LocalVersion
self.Host = Host
self.VersionPath = '/BoL/TCPUpdater/GetScript5.php?script=' .. self:Base64Encode(self.Host .. Path .. '.ver') .. '&rand=' .. random(99999999)
self.ScriptPath = '/BoL/TCPUpdater/GetScript5.php?script=' .. self:Base64Encode(self.Host .. Path .. '.lua') .. '&rand=' .. random(99999999)
self.LocalPath = LocalPath
self.CallbackUpdate = CallbackUpdate
self.CallbackNoUpdate = CallbackNoUpdate
self.CallbackNewVersion = CallbackNewVersion
self.CallbackError = CallbackError
self.OffsetY = _G.OffsetY and _G.OffsetY or 0
_G.OffsetY = _G.OffsetY and _G.OffsetY + round(0.08333333333 * WINDOW_H) or round(0.08333333333 * WINDOW_H)
AddDrawCallback(function()
self:OnDraw()
end)
self:CreateSocket(self.VersionPath)
self.DownloadStatus = 'Connecting to Server..'
self.Progress = 0
AddTickCallback(function()
self:GetOnlineVersion()
end)
end
function ABUpdater:OnDraw()
if (self.DownloadStatus == 'Downloading Script:' or self.DownloadStatus == 'Downloading Version:') and self.Progress == 100 then
return
end
local LoadingBar =
{
X = round(0.91 * WINDOW_W),
Y = round(0.73 * WINDOW_H) - self.OffsetY,
Height = round(0.01666666666 * WINDOW_H),
Width = round(0.171875 * WINDOW_W),
Border = 1,
HeaderFontSize = round(0.01666666666 * WINDOW_H),
ProgressFontSize = round(0.01125 * WINDOW_H),
BackgroundColor = 0xFFBFC0C2,
ForegroundColor = 0xFF5A87C8
}
DrawText(self.DownloadStatus, LoadingBar.HeaderFontSize, LoadingBar.X - 0.5 * LoadingBar.Width, LoadingBar.Y - LoadingBar.Height - LoadingBar.Border, LoadingBar.BackgroundColor)
DrawLine(LoadingBar.X, LoadingBar.Y, LoadingBar.X, LoadingBar.Y + LoadingBar.Height, LoadingBar.Width, LoadingBar.BackgroundColor)
if self.Progress > 0 then
local Width = 0.01 * ((LoadingBar.Width - 2 * LoadingBar.Border) * self.Progress)
local Offset = 0.5 * (LoadingBar.Width - Width)
DrawLine(LoadingBar.X - Offset + LoadingBar.Border, LoadingBar.Y + LoadingBar.Border, LoadingBar.X - Offset + LoadingBar.Border, LoadingBar.Y + LoadingBar.Height - LoadingBar.Border, Width, LoadingBar.ForegroundColor)
end
DrawText(self.Progress .. '%', LoadingBar.ProgressFontSize, LoadingBar.X - 2 * LoadingBar.Border, LoadingBar.Y + LoadingBar.Border, self.Progress < 50 and LoadingBar.ForegroundColor or LoadingBar.BackgroundColor)
end
function ABUpdater: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
local gsub, byte, sub = string.gsub, string.byte, string.sub
function ABUpdater:Base64Encode(data)
local b = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
return (gsub((gsub(data, '.', function(x)
local r, b = '', byte(x)
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'), '%d%d%d?%d?%d?%d?', function(x)
if (#x < 6) then
return ''
end
local c = 0
for i = 1, 6 do
c = c + (sub(x, i, i) == '1' and 2 ^ (6 - i) or 0)
end
return sub(b, 1 + c, 1 + c)
end) .. ({ '', '==', '=' })[#data % 3 + 1])
end
local find, len = string.find, string.len
function ABUpdater: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 Version:'
self.Progress = 0
end
self.File = self.File .. (self.Receive or self.Snipped)
if find(self.File, '') then
if not self.Size then
self.Size = tonumber(sub(self.File, 6 + find(self.File, ''), find(self.File, '') - 1))
end
if find(self.File, '')
if ScriptEnd then
ScriptEnd = ScriptEnd - 1
end
local DownloadedSize = len(sub(self.File, 1 + ScriptFind, ScriptEnd or -1))
self.Progress = round(100 / self.Size * DownloadedSize, 2)
end
end
if find(self.File, '') then
local a, b = find(self.File, '\r\n\r\n')
self.File = sub(self.File, a, -1)
self.NewFile = ''
for line, content in ipairs(self.File:split('\n')) do
if len(content) > 5 then
self.NewFile = self.NewFile .. content
end
end
local HeaderEnd, ContentStart = find(self.File, '')
if not ContentStart or not ContentEnd then
if self.CallbackError and type(self.CallbackError) == 'function' then
self.CallbackError()
end
else
self.OnlineVersion = (Base64Decode(sub(self.File, 1 + ContentStart, 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 = 'Connecting to Server..'
self.Progress = 0
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 ABUpdater: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:'
self.Progress = 0
end
self.File = self.File .. (self.Receive or self.Snipped)
if find(self.File, '') then
if not self.Size then
self.Size = tonumber(sub(self.File, 6 + find(self.File, ''), find(self.File, '') - 1))
end
if find(self.File, '')
if ScriptEnd then
ScriptEnd = ScriptEnd - 1
end
local DownloadedSize = len(sub(self.File, 1 + ScriptFind, ScriptEnd or -1))
self.Progress = round(100 / self.Size * DownloadedSize, 2)
end
end
if find(self.File, '') then
local a, b = find(self.File, '\r\n\r\n')
self.File = sub(self.File, a, -1)
self.NewFile = ''
for line, content in ipairs(self.File:split('\n')) do
if len(content) > 5 then
self.NewFile = self.NewFile .. content
end
end
local HeaderEnd, ContentStart = find(self.NewFile, '')
if not ContentStart or not ContentEnd then
if self.CallbackError and type(self.CallbackError) == 'function' then
self.CallbackError()
end
else
local newf = sub(self.NewFile, 1 + ContentStart, ContentEnd - 1)
local newf = gsub(newf, '\r','')
if len(newf) ~= 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.LocalPath,"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
local format = string.format
AddLoadCallback(function()
local UpdaterInfo =
{
Version = Script.Version,
Host = 'raw.githubusercontent.com',
Path = '/RoachxD/BoL_Scripts/master/' .. gsub(Script.Name, ' ', '%%20'),
LocalPath = SCRIPT_PATH .. '/' .. Script.Name .. '.lua',
CallbackUpdate = function(newVersion, oldVersion)
Print("Updated to r" .. format("%.1f", newVersion) .. ", please 2xF9 to reload!")
end,
CallbackNoUpdate = function(version)
Print("No updates found!")
AntiBaseUlt()
end,
CallbackNewVersion = function(version)
Print("New release found (r" .. format("%.1f", version) .. "), please wait until it's downloaded!")
end,
CallbackError = function(version)
Print("Download failed, please try again!")
Print("If the problem persists please contact script's author!")
AntiBaseUlt()
end
}
ABUpdater(UpdaterInfo.Version, UpdaterInfo.Host, UpdaterInfo.Path, UpdaterInfo.LocalPath, UpdaterInfo.CallbackUpdate, UpdaterInfo.CallbackNoUpdate, UpdaterInfo.CallbackNewVersion, UpdaterInfo.CallbackError)
end)
class "AntiBaseUlt"
function AntiBaseUlt:__init()
self.SpellData =
{
['Ashe'] =
{
MissileName = "EnchantedCrystalArrow",
Speed = 1600
},
['Draven'] =
{
MissileName = "DravenR",
Speed = 2000
},
['Ezreal'] =
{
MissileName = "EzrealTrueshotBarrage",
Speed = 2000
},
['Jinx'] =
{
MissileName = "JinxR",
Speed = 1700
}
}
self.RecallingTime = 0
self:OnLoad()
-- Bol-Tools Tracker
assert(load(Base64Decode("G0x1YVIAAQQEBAgAGZMNChoKAAAAAAAAAAAAAQMeAAAABAAAAEYAQAClAAAAXUAAAUZAQAClQAAAXUAAAWWAAAAIQACBZcAAAAhAgIFGAEEApQABAF1AAAFGQEEAgYABAF1AAAFGgEEApUABAEqAgINGgEEApYABAEqAAIRGgEEApcABAEqAgIRGgEEApQACAEqAAIUfAIAACwAAAAQSAAAAQWRkVW5sb2FkQ2FsbGJhY2sABBQAAABBZGRCdWdzcGxhdENhbGxiYWNrAAQMAAAAVHJhY2tlckxvYWQABA0AAABCb2xUb29sc1RpbWUABBQAAABBZGRHYW1lT3ZlckNhbGxiYWNrAAQGAAAAY2xhc3MABA4AAABTY3JpcHRUcmFja2VyAAQHAAAAX19pbml0AAQSAAAAU2VuZFZhbHVlVG9TZXJ2ZXIABAoAAABzZW5kRGF0YXMABAsAAABHZXRXZWJQYWdlAAkAAAACAAAAAwAAAAAAAwkAAAAFAAAAGABAABcAAIAfAIAABQAAAAxAQACBgAAAHUCAAR8AgAADAAAAAAQSAAAAU2VuZFZhbHVlVG9TZXJ2ZXIABAcAAAB1bmxvYWQAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAEAAAABQAAAAAAAwkAAAAFAAAAGABAABcAAIAfAIAABQAAAAxAQACBgAAAHUCAAR8AgAADAAAAAAQSAAAAU2VuZFZhbHVlVG9TZXJ2ZXIABAkAAABidWdzcGxhdAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAUAAAAHAAAAAQAEDQAAAEYAwACAAAAAXYAAAUkAAABFAAAATEDAAMGAAABdQIABRsDAAKUAAADBAAEAXUCAAR8AgAAFAAAABA4AAABTY3JpcHRUcmFja2VyAAQSAAAAU2VuZFZhbHVlVG9TZXJ2ZXIABAUAAABsb2FkAAQMAAAARGVsYXlBY3Rpb24AAwAAAAAAQHpAAQAAAAYAAAAHAAAAAAADBQAAAAUAAAAMAEAAgUAAAB1AgAEfAIAAAgAAAAQSAAAAU2VuZFZhbHVlVG9TZXJ2ZXIABAgAAAB3b3JraW5nAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAACAAAAA0AAAAAAAksAAAABgBAAB2AgAAaQEAAF4AAgEGAAABfAAABF8AIgEbAQABHAMEAgUABAMaAQQDHwMEBEAFCAN0AAAFdgAAAhsBAAIcAQQHBQAEABoFBAAfBQQJQQUIAj0HCAE6BgQIdAQABnYAAAMbAQADHAMEBAUEBAEaBQQBHwcECjwHCAI6BAQDPQUIBjsEBA10BAAHdgAAAAAGAAEGBAgCAAQABwYECAAACgAEWAQICHwEAAR8AgAALAAAABA8AAABHZXRJbkdhbWVUaW1lcgADAAAAAAAAAAAECQAAADAwOjAwOjAwAAQHAAAAc3RyaW5nAAQHAAAAZm9ybWF0AAQGAAAAJTAyLmYABAUAAABtYXRoAAQGAAAAZmxvb3IAAwAAAAAAIKxAAwAAAAAAAE5ABAIAAAA6AAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAABAAAAAAAAMUAAAABgBAAB2AgAAHQEAAGwAAABdAA4AGAEAAHYCAAAeAQAAbAAAAFwABgAUAgAAMwEAAgYAAAB1AgAEXwACABQCAAAzAQACBAAEAHUCAAR8AgAAFAAAABAgAAABHZXRHYW1lAAQHAAAAaXNPdmVyAAQEAAAAd2luAAQSAAAAU2VuZFZhbHVlVG9TZXJ2ZXIABAYAAABsb29zZQAAAAAAAgAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAEQAAABEAAAACAAICAAAACkAAgB8AgAABAAAABAoAAABzY3JpcHRLZXkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEQAAABIAAAACAAUKAAAAhgBAAMAAgACdgAABGEBAARfAAICFAIAAjIBAAQABgACdQIABHwCAAAMAAAAEBQAAAHR5cGUABAcAAABzdHJpbmcABAoAAABzZW5kRGF0YXMAAAAAAAIAAAAAAAEAAAAAAAAAAAAAAAAAAAAAABMAAAAiAAAAAgATPwAAAApAAICGgEAAnYCAAAqAgICGAEEAxkBBAAaBQQAHwUECQQECAB2BAAFGgUEAR8HBAoFBAgBdgQABhoFBAIfBQQPBgQIAnYEAAcaBQQDHwcEDAcICAN2BAAEGgkEAB8JBBEECAwAdggABFgECAt0AAAGdgAAACoCAgYaAQwCdgIAACoCAhgoAxIeGQEQAmwAAABdAAIAKgMSHFwAAgArAxIeGQEUAh4BFAQqAAIqFAIAAjMBFAQEBBgBBQQYAh4FGAMHBBgAAAoAAQQIHAIcCRQDBQgcAB0NAAEGDBwCHw0AAwcMHAAdEQwBBBAgAh8RDAFaBhAKdQAACHwCAACEAAAAEBwAAAGFjdGlvbgAECQAAAHVzZXJuYW1lAAQIAAAAR2V0VXNlcgAEBQAAAGh3aWQABA0AAABCYXNlNjRFbmNvZGUABAkAAAB0b3N0cmluZwAEAwAAAG9zAAQHAAAAZ2V0ZW52AAQVAAAAUFJPQ0VTU09SX0lERU5USUZJRVIABAkAAABVU0VSTkFNRQAEDQAAAENPTVBVVEVSTkFNRQAEEAAAAFBST0NFU1NPUl9MRVZFTAAEEwAAAFBST0NFU1NPUl9SRVZJU0lPTgAECwAAAGluZ2FtZVRpbWUABA0AAABCb2xUb29sc1RpbWUABAYAAABpc1ZpcAAEAQAAAAAECQAAAFZJUF9VU0VSAAMAAAAAAADwPwMAAAAAAAAAAAQJAAAAY2hhbXBpb24ABAcAAABteUhlcm8ABAkAAABjaGFyTmFtZQAECwAAAEdldFdlYlBhZ2UABA4AAABib2wtdG9vbHMuY29tAAQXAAAAL2FwaS9ldmVudHM/c2NyaXB0S2V5PQAECgAAAHNjcmlwdEtleQAECQAAACZhY3Rpb249AAQLAAAAJmNoYW1waW9uPQAEDgAAACZib2xVc2VybmFtZT0ABAcAAAAmaHdpZD0ABA0AAAAmaW5nYW1lVGltZT0ABAgAAAAmaXNWaXA9AAAAAAACAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAjAAAAJwAAAAMACiEAAADGQEAAAYEAAN2AAAHHwMAB3YCAAArAAIDHAEAAzADBAUABgACBQQEA3UAAAscAQADMgMEBQcEBAIABAAHBAQIAAAKAAEFCAgBWQYIC3UCAAccAQADMgMIBQcECAIEBAwDdQAACxwBAAMyAwgFBQQMAgYEDAN1AAAIKAMSHCgDEiB8AgAASAAAABAcAAABTb2NrZXQABAgAAAByZXF1aXJlAAQHAAAAc29ja2V0AAQEAAAAdGNwAAQIAAAAY29ubmVjdAADAAAAAAAAVEAEBQAAAHNlbmQABAUAAABHRVQgAAQSAAAAIEhUVFAvMS4wDQpIb3N0OiAABAUAAAANCg0KAAQLAAAAc2V0dGltZW91dAADAAAAAAAAAAAEAgAAAGIAAwAAAPyD15dBBAIAAAB0AAQKAAAATGFzdFByaW50AAQBAAAAAAQFAAAARmlsZQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAA="), nil, "bt", _ENV))()
TrackerLoad("7Fly2oC0Z6IWhPkU")
end
function AntiBaseUlt:OnLoad()
self.Config = scriptConfig(Script.Name, "ABU")
self.Config:addSubMenu("Champion Settings", "Champion")
for _, Hero in pairs(GetEnemyHeroes()) do
if self.SpellData[Hero.charName] ~= nil then
self.Config.Champion:addParam(Hero.charName, Hero.charName .. " - " .. self.SpellData[Hero.charName].MissileName, SCRIPT_PARAM_ONOFF, true)
end
end
Print("Successfully loaded r" .. format("%.1f", Script.Version) .. ", have fun!")
if next(self.Config.Champion._param) == nil then
self.Config.Champion:addParam("Info", "No champions supported!", SCRIPT_PARAM_INFO, "")
Print("No champions supported in the enemy team, the script will unload!")
end
self.Config:addSubMenu("Debug Settings", "Debug")
self.Config.Debug:addParam("Prints", "Debug Printing", SCRIPT_PARAM_ONOFF, false)
self.Config:addParam("Enable", "Enable Anti BaseUlt", SCRIPT_PARAM_ONOFF, true)
self.Config:addParam("ScriptVersion", "Script Version: ", SCRIPT_PARAM_INFO, "r" .. format("%.1f", Script.Version))
if self.Config.Champion.Info == nil then
AddProcessSpellCallback(function(unit, spell)
self:OnProcessSpell(unit, spell)
end)
AddCreateObjCallback(function(object)
self:OnCreateObj(object)
end)
end
end
local lower, clock = string.lower, os.clock
function AntiBaseUlt:OnProcessSpell(unit, spell)
if not self.Config.Enable then
return
end
if unit == myHero and find(spell.name, "recall") then
local RecallSpells =
{
['recall'] = 8.0,
['recallimproved'] = 7.0,
['odinrecall'] = 4.5,
['odinrecallimproved'] = 4.0,
['superrecall'] = 4.0,
['superrecallimproved'] = 4.0
}
self.RecallingTime = clock() + RecallSpells[lower(spell.name)]
self:Debug("Recall Detected! (Finish Time: " .. self.RecallingTime .. " | Actual Time" .. clock() .. ").")
end
end
function AntiBaseUlt:OnCreateObj(object)
if not self.Config.Enable then
return
end
if not object or not object.valid or object.type ~= "MissileClient" then
return
end
local SpellOwner = object.spellOwner
if not SpellOwner or not SpellOwner.valid then
return
end
if self.RecallingTime < clock() then
return
end
if SpellOwner.type ~= myHero.type or SpellOwner.team == myHero.team then
return
end
if self.SpellData[SpellOwner.charName] == nil or not self.Config.Champion[SpellOwner.charName] then
return
end
if self.SpellData[SpellOwner.charName].MissileName ~= object.spellName then
return
end
local FountainPos = GetFountain()
if not self:IsLineCircleIntersection(FountainPos, 500, object.pos, object.spellEnd) then
self:Debug("BaseUlt not in fountain (" .. SpellOwner.charName .. " - " .. object.spellName ..").")
return
end
local Time = clock() + (GetDistance(object.pos, FountainPos) / self.SpellData[SpellOwner.charName].Speed)
if 1 + self.RecallingTime < Time or self.RecallingTime - 1 > Time then
self:Debug("BaseUlt not correctly timed (" .. SpellOwner.charName .. " - " .. object.spellName ..").")
return
end
myHero:MoveTo(1 + myHero.x, 1 + myHero.z)
Print("BaseUlt Prevented (" .. SpellOwner.charName .. " - " .. object.spellName ..").")
end
function AntiBaseUlt:IsLineCircleIntersection(circle, radius, v1, v2)
local ToLineEnd = v2 - v1
local ToCircle = circle - v1
local Theta = (ToCircle.x * ToLineEnd.x + ToCircle.y * ToLineEnd.y) / (ToLineEnd.x * ToLineEnd.x + ToLineEnd.y * ToLineEnd.y)
Theta = Theta <= 0 and 0 or 1
local Closest = v1 + D3DXVECTOR3(ToLineEnd.x * Theta, ToLineEnd.y * Theta, ToLineEnd.z * Theta)
local D = circle - Closest
local Dist = (D.x * D.x) + (D.y * D.y)
return Dist <= radius * radius
end
function AntiBaseUlt:Debug(string)
if not self.Config.Debug.Prints then
return
end
Print(string)
end