local version = 34
local require2 = _G.require
local DrawText = _G.DrawText
local DrawCircle = _G.DrawCircle
local FillRect = _G.FillRect
libTable = {
-- ["DLib"] = "iLoveSona/GOS/master/Common/DLib.lua",
["simple ward jump"] = "iLoveSona/GOS/master/simple%20ward%20jump.lua",
["simple auto level spell"] = "iLoveSona/GOS/master/simple%20auto%20level%20spell.lua",
["simple orbwalk"] = "iLoveSona/GOS/master/simple%20orbwalk.lua",
["antiCC"] = "iLoveSona/GOS/master/antiCC.lua",
["Interrupter"] = "iLoveSona/GOS/master/Common/Interrupter.lua",
["Inspired"] = "Inspired-gos/scripts/master/Common/Inspired.lua",
["MapPosition"] = "Maxxxel/GOS/master/Common/Utility/MapPosition.lua",
["MapPositionGOS"] = "Maxxxel/GOS/master/Common/Utility/MapPositionGOS.lua",
["MapPosition_bushes_1"] = "Maxxxel/GOS/master/Common/Utility/MapPosition_bushes_1.lua",
["MapPosition_walls_1_1"] = "Maxxxel/GOS/master/Common/Utility/MapPosition_walls_1_1.lua",
["2DGeometry"] = "Maxxxel/GOS/master/Common/Utility/2DGeometry.lua",
["IsFacing"] = "Maxxxel/GOS/master/Common/Utility/IsFacing.lua"
}
local function mousePos()
local pos
if g then
pos=g.mousePos()
return Vector2.new(pos[1], pos[2])
else
pos=GetMousePos()
pos=WorldToScreen(1, pos.x, pos.y, pos.z)
return Vector2.new(pos)
end
end
-- better handle require error
function require( m, hideErr )
local hideErr = hideErr or false
local PrintChat = _G.PrintChat
if hideErr then PrintChat = function ( ... ) end end
ok, err = pcall(require2, m)
if not ok then
local url = libTable[m]
if url then
-- print(err)
PrintChat("LOAD \""..m..".lua\" FAIL, auto fix mode: try redownload the script, plz waiting...")
saveScript("Common\\"..m, webRequest("github", url.."?rand="..math.random(1,10000)))
PrintChat(" auto fix mode: \""..m..".lua\" updated, press F6-F6 to reload.")
-- detect noob require a webpage error
elseif string.find(err, "unexpected symbol near '<'") then PrintChat("LOAD \""..m..".lua\" SCRIPT ERROR: make sure you download the script code instead webpage")
else
PrintChat(err)
end
return nil, err
end
return err
end
function prequire(m, hideErr)
-- local ok, err = pcall(require, m)
-- if not ok then return nil, err end
-- return err
return require(m, hideErr)
end
function requireDL(script, address, retry)
local retry = retry or 0
local status, module = pcall(require, script)
if not status and retry<4 then
retry=retry+1
response=webRequest("github", address.."?rand="..math.random(1,10000))
if response~=nil then
saveScript("Common\\"..script, response) end
requireDL(script, address, retry)
else
if retry==4 then
MessageBox(0,"Unable to download library "..script,"Error!",0) end
end
if retry>0 then
s, module = pcall(require, script) end
return module
end
function codeToString(code)
if code >=48 and code<=90 then
return string.char(code)
elseif code==1 then
return "mouseLeft"
elseif code==2 then
return "mouseRight"
elseif code==4 then
return "mouseMiddle"
elseif code==5 then
return "mouseX1"
elseif code==6 then
return "mouseX2"
elseif code==6 then
return "mouseMiddle"
elseif code==13 then
return "enter"
elseif code==16 then
return "shift"
elseif code==8 then
return "backspace"
elseif code==9 then
return "tab"
elseif code==13 then
return "enter"
elseif code==16 then
return "shift"
elseif code==17 then
return "ctrl"
elseif code==18 then
return "alt"
elseif code==19 then
return "pause"
elseif code==20 then
return "caps lock"
elseif code==27 then
return "escape"
elseif code==32 then
return "spacebar"
elseif code==33 then
return "pgUp"
elseif code==34 then
return "pgDn"
elseif code==35 then
return "end"
elseif code==36 then
return "home"
elseif code==37 then
return "left"
elseif code==38 then
return "up"
elseif code==39 then
return "right"
elseif code==40 then
return "down"
elseif code==44 then
return "printSc"
elseif code==45 then
return "insert"
elseif code==46 then
return "del"
elseif code==47 then
return "help"
elseif code==91 then
return "lWindow"
elseif code==92 then
return "rWindow"
elseif code==93 then
return "select"
elseif code==96 then
return "Num 0"
elseif code==97 then
return "Num 1"
elseif code==98 then
return "Num 2"
elseif code==99 then
return "Num 3"
elseif code==100 then
return "Num 4"
elseif code==101 then
return "Num 5"
elseif code==102 then
return "Num 6"
elseif code==103 then
return "Num 7"
elseif code==104 then
return "Num 8"
elseif code==105 then
return "Num 9"
elseif code==106 then
return "Num *"
elseif code==107 then
return "Num +"
elseif code==109 then
return "Num -"
elseif code==111 then
return "Num /"
elseif code==112 then
return "F1"
elseif code==113 then
return "F2"
elseif code==114 then
return "F3"
elseif code==115 then
return "F4"
elseif code==116 then
return "F5"
elseif code==117 then
return "F6"
elseif code==118 then
return "F7"
elseif code==119 then
return "F8"
elseif code==120 then
return "F9"
elseif code==121 then
return "F10"
elseif code==122 then
return "F11"
elseif code==123 then
return "F12"
else return tostring(code) end
end
function getTextWidth(text, offset)
local ret=offset or 0
for c in text:gmatch"." do
if c==" " then ret=ret+4
elseif tonumber(c)~=nil then ret=ret+6
elseif c==string.upper(c) then ret=ret+8
elseif c==string.lower(c) then ret=ret+7
else ret=ret+5 end
end
return ret
end
function getLongestString(textList)
local mx=0
for i, str in ipairs(textList) do
local l=getTextWidth(str)
if l>mx then
mx=l
end
end
return mx
end
function round(num, idp)
local mult = 10^(idp or 0)
return math.floor(num * mult + 0.5) / mult
end
function roundStep(num, step)
return round(num/step)*step
end
function stripchars(str, chrs)
return str:gsub("["..chrs.."]", ''):gsub("%[%]", "")
end
function stripchars2(str, chrs)
return str:gsub("%[%]")
end
function calcRounding(num)
num=num+0.00000000000001
local t=1
local places=t
while true do
if num >= t then return places-1 end
places=places + 1
t=t/10
end
end
function percentToRGB(percent)
local r, g
if percent == 100 then
percent = 99 end
if percent < 50 then
r = math.floor(255 * (percent / 50))
g = 255
else
r = 255
g = math.floor(255 * ((50 - percent % 50) / 50))
end
return 0x90000000+g*0xFFFF+r*0xFF
end
--REGION notifications---------------------------------------------------------
--{
Notification={}
local notifications={}
local notificationsActive=false
function Notification.new(message, duration, drawcolor, textcolor, animationscale, fontsize, y)
local this = {}
this.message = message
this.duration = duration or 2000
this.drawcolor=drawcolor or 0x70000000
this.textcolor=textcolor or 0xFF71D450
this.animationscale=animationscale or 1
this.x=-1000
this.y=y
this.toremove=false
this.creationTime=GetTickCount()+300*animationscale
this.fontsize = fontsize or 14
function this.updateX(tickcount)
if tickcount>this.creationTime and tickcountthis.creationTime+this.duration) then
local z=(tickcount-(this.creationTime+this.duration))/animationscale
this.x=math.ceil(7+0.0018*z*z - 1.23*z)
if tickcount>this.creationTime+this.duration+300*animationscale then this.toremove=true end
return
end
local z=(this.creationTime-tickcount)/animationscale
this.x=math.ceil(7+0.0018*z*z - 1.23*z)
end
function this.onLoop(tickcount)
this.updateX(tickcount)
FillRect(this.x, this.y, 0.4 * #this.message * this.fontsize, 1.5 * this.fontsize, this.drawcolor)
DrawText(this.message,this.fontsize,this.x+3, this.y+5, this.textcolor)
end
return this
end
function notification(message, duration, animationscale, fontsize, textcolor, drawcolor)
if message==nil then PrintChat("Notification: message not set, ignored.") end
drawcolor=drawcolor or 0x70000000
textcolor=textcolor or 0xFF71D450
animationscale=animationscale or 1
for slot = 0, 15, 1 do
if notifications[slot]==nil then
notifications[slot]=Notification.new(message, duration, drawcolor, textcolor, animationscale, fontsize, slot*60+5)
notificationsActive=true
return
end
end
end
function notificationsOnLoop(tickcount)
if not notificationsActive then return end
for k, value in pairs(notifications) do
value.onLoop(tickcount)
if value.toremove==true then notifications[k]=nil end
end
if next(notifications) == nil then
notificationsActive=false
end
end
--ENDREGION notifications------------------------------------------------------}
--REGION delay-----------------------------------------------------------------
--{
local delayed={}
local delayedActive=false
function delay(func, t)
if(t==nil) then PrintChat("Delay: time not set") return end
delayedActive=true
table.insert(delayed, {t+GetTickCount(), func})
end
function delayedOnLoop(tickcount)
if not delayedActive then return end
for i, item in pairs(delayed) do
if item[1] <= tickcount then
item[2]()
delayed[i] = nil
end
end
if next(delayed) == nil then
delayedActive=false
end
end
--ENDREGION delay--------------------------------------------------------------}
--REGION Menu------------------------------------------------------------------
--{
local ITEMHEIGHT=30
local ITEMWIDTH=200
local TEXTYOFFSET=-7
local TOGGLEWIDTH=30
local MENUTEXTCOLOR=0xFFFFFFFF
local MENUBGCOLOR=0xC8000000
local MENUBGACTIVE=4285098345
local MENUBORDERCOLOR=0xFF000000
MainMenu={}
function MainMenu.new()
local this = {}
if c.config.menu==nil then
c.config.menu={}
end
this.conf=c.config.menu
if c.config.menuX==nil then
c.config.menuX=300
end
if c.config.menuY==nil then
c.config.menuY=300
end
this.children = {}
this.pos=Vector2.new(c.config.menuX, c.config.menuY)
this.setpos=Vector2.new(c.config.menuX, c.config.menuY)
this.width = width or ITEMWIDTH
this.fullHeight= 0
this.active=false
function this.inputProcessor(key, pressed)
if key == 160 then
if pressed then
this.show()
else
this.hide()
end
end
if not this.active then return end
local mousevec=mousePos()
for num, item in ipairs(this.children) do
item.processInput(key, pressed, mousevec)
end
end
this.proc=registerInputListener(this.inputProcessor)
function this.show()
this.active=true
for num, item in ipairs(this.children) do
item.show()
end
end
function this.hide()
this.active=false
for num, item in pairs(this.children) do
item.hide()
this.conf[item.name]=item.getValue(true)
end
c.config.menuX=this.pos.x
c.config.menuY=this.pos.y
c.save()
end
function this.addItem(MenuItem)
local free=1
for num, item in ipairs(this.children) do
free=free+1
end
MenuItem.name=stripchars(MenuItem.name, "\n\a\b\f\r\t\v\"%[%]" )
this.expandMain(MenuItem.textlengthAdd+getTextWidth(MenuItem.name, 0))
MenuItem.setPosition(this.pos)
MenuItem.setWidthInternal(this.width)
MenuItem.parent=this
MenuItem.mainMenu=this
this.children[free]=MenuItem
this.calculateY()
if this.conf[MenuItem.name]~=nil then
MenuItem.setValue(this.conf[MenuItem.name])
end
return MenuItem
end
function this.deactivateAll()
for num, item in ipairs(this.children) do
item.active=false
end
end
function this.setMenuPosition(pos)
this.setpos=Vector2.new(pos)
end
function this.calculateY()
local yOffset=0
for i, item in ipairs(this.children) do
item.setYoffset(yOffset)
yOffset=yOffset+(item.rectangle.height or 0)
end
this.fullHeight=yOffset
return MenuItem
end
function this.expandMain(newWidth)
if newWidth>this.width then
this.width=newWidth
for i, item in ipairs(this.children) do
item.setWidthInternal(newWidth)
end
end
end
function this.onLoop()
if not this.active then return end
if not this.pos.equals(this.setpos) then
this.pos=this.setpos
for num, item in ipairs(this.children) do
item.setPosition(this.setpos)
end
end
for i, item in pairs(this.children) do
item.onLoop()
end
FillRect(this.pos.x,this.pos.y,1,this.fullHeight+2, MENUBORDERCOLOR)
FillRect(this.pos.x+this.width,this.pos.y,1,this.fullHeight+2, MENUBORDERCOLOR)
FillRect(this.pos.x,this.pos.y+this.fullHeight,this.width,2, MENUBORDERCOLOR)
end
return this
end
SubMenu={}
function SubMenu.new(name)
--item fields
local this = {}
this.conf = {}
this.name = name or "Unnamed"
this.parent=parent
this.mainMenu=nil
this.textY=0
this.pos=Vector2.new()
this.rectangle = Rectangle.new(0, 0, ITEMWIDTH, ITEMHEIGHT)
this.active=false
--drag specific fields
this.allowDrag=true
this.dragPos=Vector2.new()
this.dragging=false
this.dragUnlocked=false
--submenu specific fields
this.fullHeight = 0
this.yOffset=0
this.childWidth= ITEMWIDTH
this.children = {}
this.textlengthAdd=55
function this.getValue()
for num, item in pairs(this.children) do
this.conf[item.name]=item.getValue(true)
end
return this.conf
end
function this.setValue(val)
this.conf=val
end
function this.processInput(key, pressed, mouseVector)
if key==1 and not pressed then
this.dragging=false
end
if key==1 and this.rectangle.contains(mouseVector) and pressed then
this.dragging=true
this.dragUnlocked=false
this.dragPos=Vector2.new(mouseVector)
this.parent.deactivateAll()
this.deactivateAll()
this.active=true
end
if not this.active then return end
for num, item in ipairs(this.children) do
item.processInput(key, pressed, mouseVector)
end
end
function this.show()
for num, item in ipairs(this.children) do
item.show()
end
end
function this.hide()
this.dragging=false
for num, item in ipairs(this.children) do
item.hide()
end
end
function this.addItem(MenuItem)
local free=1
for num, item in ipairs(this.children) do
free=free+1
end
MenuItem.name=stripchars(MenuItem.name, "\n\a\b\f\r\t\v\"%[%]" )
MenuItem.parent=this
MenuItem.mainMenu=this.mainMenu
this.expandChild(MenuItem.textlengthAdd+getTextWidth(MenuItem.name, 0))
MenuItem.setWidthInternal(this.childWidth)
MenuItem.setPosition(Vector2.new(this.pos.x+this.rectangle.width, this.pos.y+this.yOffset))
this.children[free]=MenuItem
this.calculateY()
if this.conf[MenuItem.name]~=nil then
MenuItem.setValue(this.conf[MenuItem.name])
end
return MenuItem
end
function this.setYoffset(newoff)
this.yOffset=newoff
this.rectangle.y=this.yOffset+this.pos.y
this.textY=this.rectangle.y+this.rectangle.height/2+TEXTYOFFSET
end
function this.setPosition(v)
this.pos=v
this.rectangle.x=v.x
this.rectangle.y=this.yOffset+this.pos.y
this.textY=this.rectangle.y+this.rectangle.height/2+TEXTYOFFSET
this.setChildPos(Vector2.new(this.pos.x+this.rectangle.width, this.pos.y+this.yOffset))
end
function this.setWidth(newWidth)
if this.parent.setChildWidth~=nil then
this.parent.setChildWidth(newWidth)
else
this.parent.expandMain(newWidth)
end
end
function this.expand(newWidth)
if this.parent.expandChild~=nil then
this.parent.expandChild(newWidth)
else
this.parent.expandMain(newWidth)
end
end
function this.expandChild(newWidth)
if newWidth>this.childWidth then
this.childWidth=newWidth
for i, item in ipairs(this.children) do
item.setWidthInternal(newWidth)
end
end
end
function this.setWidthInternal(newWidth)
this.rectangle.width=newWidth
this.setChildPos(Vector2.new(this.pos.x+this.rectangle.width, this.pos.y+this.yOffset))
end
function this.setHeight(newHeight)
this.rectangle.height=newHeight
this.textY=this.rectangle.y+this.rectangle.height/2+TEXTYOFFSET
this.setChildPos(Vector2.new(this.pos.x+this.rectangle.width, this.rectangle.y))
this.parent.calculateY()
end
function this.setChildWidth(newWidth)
this.childWidth=(newWidth)
this.setChildPos(Vector2.new(this.pos.x+this.rectangle.width, this.rectangle.y))
for i, item in ipairs(this.children) do
item.setWidthInternal(newWidth)
end
end
function this.setChildPos(v)
for num, item in ipairs(this.children) do
item.setPosition(v)
end
end
function this.deactivateAll()
for num, item in ipairs(this.children) do
item.active=false
end
end
function this.calculateY()
local yOffset=0
for i, item in ipairs(this.children) do
item.setYoffset(yOffset)
yOffset=yOffset+(item.rectangle.height or 0)
end
this.fullHeight=yOffset
return MenuItem
end
function this.onLoop()
if this.active then
if this.dragging then
tempVec=mousePos().sub(this.dragPos)
if this.dragUnlocked then
this.dragPos=mousePos()
this.mainMenu.setMenuPosition(tempVec.add(this.mainMenu.pos))
elseif not this.dragUnlocked and tempVec.len2()>100 then
this.dragUnlocked=true
this.dragPos=mousePos()
end
end
this.rectangle.draw(MENUBGACTIVE)
else
this.rectangle.draw(MENUBGCOLOR)
end
DrawText(">", 16, this.pos.x+this.rectangle.width-15, this.textY, MENUTEXTCOLOR)
DrawText(this.name, 15, this.pos.x+5, this.textY, MENUTEXTCOLOR)
FillRect(this.rectangle.x,this.rectangle.y,this.rectangle.width,2,MENUBORDERCOLOR)
if not this.active then return end
if next(this.children) == nil then return end
for i, item in pairs(this.children) do
item.onLoop()
end
FillRect(this.pos.x+this.rectangle.width,this.rectangle.y,1,this.fullHeight+2, MENUBORDERCOLOR)
FillRect(this.pos.x+this.rectangle.width+this.childWidth,this.rectangle.y,1,this.fullHeight+2, MENUBORDERCOLOR)
FillRect(this.pos.x+this.rectangle.width,this.rectangle.y+this.fullHeight,this.childWidth,2, MENUBORDERCOLOR)
end
return this
end
MenuSeparator={}
function MenuSeparator.new(name)
--item fields
local this = {}
this.name = name or "Unnamed"
this.parent=parent
this.mainMenu=nil
this.textY=0
this.yOffset=0
this.pos=Vector2.new()
this.rectangle = Rectangle.new(0, 0, ITEMWIDTH, ITEMHEIGHT)
this.textlengthAdd=20
this.allowDrag=true
this.dragPos=Vector2.new()
this.dragging=false
this.dragUnlocked=false
function this.processInput(key, pressed, mouseVector)
if key==1 and not pressed then
this.dragging=false
end
if key==1 and this.rectangle.contains(mouseVector) and pressed then
this.dragging=true
this.dragUnlocked=false
this.dragPos=Vector2.new(mouseVector)
this.active=true
end
end
function this.getValue()
return this.name
end
function this.setValue(val)
end
function this.expand(newWidth)
this.parent.expandChild(newWidth)
end
function this.setYoffset(newoff)
this.yOffset=newoff
this.rectangle.y=this.pos.y+this.yOffset
this.textY=this.rectangle.y+this.rectangle.height/2+TEXTYOFFSET
end
function this.setPosition(v)
this.rectangle.x=v.x
this.pos=v
this.rectangle.y=this.pos.y+this.yOffset
this.textY=this.rectangle.y+this.rectangle.height/2+TEXTYOFFSET
end
function this.setWidth(newWidth)
if this.parent.setChildWidth~=nil then
this.parent.setChildWidth(newWidth)
else
this.parent.expandMain(newWidth)
end
end
function this.setWidthInternal(newWidth)
this.rectangle.width=newWidth
end
function this.setHeight(newHeight)
this.rectangle.height=newHeight
this.textY=this.rectangle.y+this.height/2+TEXTYOFFSET
this.parent.calculateY()
end
function this.onLoop()
if this.active then
if this.dragging then
tempVec=mousePos().sub(this.dragPos)
if this.dragUnlocked then
this.dragPos=mousePos()
this.mainMenu.setMenuPosition(tempVec.add(this.mainMenu.pos))
elseif not this.dragUnlocked and tempVec.len2()>100 then
this.dragUnlocked=true
this.dragPos=mousePos()
end
end
end
this.rectangle.draw(MENUBGCOLOR)
DrawText(this.name, 15, this.pos.x+5, this.textY, MENUTEXTCOLOR)
FillRect(this.rectangle.x,this.rectangle.y,this.rectangle.width,2,MENUBORDERCOLOR)
end
function this.show()
end
function this.hide()
this.dragging=false
end
return this
end
MenuKeyBind={}
function MenuKeyBind.new(name, keycode)
--item fields
local this = {}
this.name = name or "Unnamed"
this.keycode = keycode or 0
this.parent=parent
this.mainMenu=nil
this.textY=0
this.yOffset=0
this.pos=Vector2.new()
this.rectangle = Rectangle.new(0, 0, ITEMWIDTH, ITEMHEIGHT)
this.activeRectangle = Rectangle.new(0, 0, TOGGLEWIDTH, ITEMHEIGHT)
this.waitingForKey=false
this.keycodeString=codeToString(this.keycode)
this.textlengthAdd=90
function this.processInput(key, pressed, mouseVector)
if this.waitingForKey and pressed and (key~=1 or this.rectangle.contains(mouseVector)) then
this.keycode = key
this.keycodeString=codeToString(this.keycode)
this.waitingForKey=false
end
if key==1 and pressed then
if this.rectangle.contains(mouseVector) then
this.waitingForKey=true
this.keycodeString="..."
else
this.waitingForKey=false
this.keycodeString=codeToString(this.keycode)
end
end
end
function this.getValue(a)
if a==nil then return KeyIsDown(this.keycode) end
return this.keycode
end
function this.setValue(va)
if type(va)~="number" then return end
this.keycode = math.abs(round(va))
this.keycodeString=codeToString(this.keycode)
end
function this.setWidth(newWidth)
if this.parent.setChildWidth~=nil then
this.parent.setChildWidth(newWidth)
else
this.parent.expandMain(newWidth)
end
end
function this.setYoffset(newoff)
this.yOffset=newoff
this.rectangle.y=this.pos.y+this.yOffset
this.activeRectangle.y=this.rectangle.y
this.textY=this.rectangle.y+this.rectangle.height/2+TEXTYOFFSET
end
function this.setPosition(v)
this.rectangle.x=v.x
this.activeRectangle.x=this.rectangle.x+this.rectangle.width-TOGGLEWIDTH
this.pos=v
this.rectangle.y=this.pos.y+this.yOffset
this.activeRectangle.y=this.rectangle.y
this.textY=this.rectangle.y+this.rectangle.height/2+TEXTYOFFSET
end
function this.setWidth(newWidth)
if this.parent.expand~=nil then this.parent.expand(newWidth) end
if this.parent.setChildWidth~=nil then this.parent.setChildWidth(newWidth) end
end
function this.setWidthInternal(newWidth)
this.rectangle.width=newWidth
this.activeRectangle.x=this.rectangle.x+newWidth-TOGGLEWIDTH
end
function this.setHeight(newHeight)
this.rectangle.height=newHeight
this.activeRectangle.height=this.rectangle.height
this.textY=this.rectangle.y+this.height/2+TEXTYOFFSET
this.parent.calculateY()
end
function this.onLoop()
this.rectangle.draw(MENUBGCOLOR)
if this.getValue() then
this.activeRectangle.draw(0xFF008000)
DrawText("On", 15, this.pos.x+this.rectangle.width-24, this.textY, MENUTEXTCOLOR)
else
this.activeRectangle.draw(0xFFFF0000)
DrawText("Off", 15, this.pos.x+this.rectangle.width-24, this.textY, MENUTEXTCOLOR)
end
FillRect(this.activeRectangle.x-2,this.activeRectangle.y,1,this.activeRectangle.height,MENUBORDERCOLOR)
DrawText(string.format("%s (%s)",this.name, this.keycodeString), 15, this.pos.x+5, this.textY, MENUTEXTCOLOR)
FillRect(this.rectangle.x,this.rectangle.y,this.rectangle.width,2,MENUBORDERCOLOR)
end
function this.show()
end
function this.hide()
if this.waitingForKey then
this.waitingForKey=false
this.keycodeString=tostring(this.keycode)
end
end
return this
end
MenuBool={}
function MenuBool.new(name, active)
--item fields
local this = {}
this.name = name or "Unnamed"
this.valueActive=active or false
this.parent=parent
this.mainMenu=nil
this.textY=0
this.yOffset=0
this.pos=Vector2.new()
this.rectangle = Rectangle.new(0, 0, ITEMWIDTH, ITEMHEIGHT)
this.activeRectangle = Rectangle.new(0, 0, TOGGLEWIDTH, ITEMHEIGHT)
this.textlengthAdd=60
this.allowDrag=true
this.dragPos=Vector2.new()
this.dragging=false
this.dragUnlocked=false
function this.processInput(key, pressed, mouseVector)
if key==1 and pressed and this.activeRectangle.contains(mouseVector) then
this.valueActive = not this.valueActive
end
if key==1 and not pressed then
this.dragging=false
end
if key==1 and this.rectangle.contains(mouseVector) and pressed then
this.dragging=true
this.dragUnlocked=false
this.dragPos=Vector2.new(mouseVector)
this.active=true
end
end
function this.getValue()
return this.valueActive
end
function this.setValue(va)
if type(va)~="boolean" then return end
this.valueActive=va
end
function this.expand(newWidth)
this.parent.expandChild(newWidth)
end
function this.setYoffset(newoff)
this.yOffset=newoff
this.rectangle.y=this.pos.y+this.yOffset
this.activeRectangle.y=this.rectangle.y
this.textY=this.rectangle.y+this.rectangle.height/2+TEXTYOFFSET
end
function this.setPosition(v)
this.rectangle.x=v.x
this.activeRectangle.x=this.rectangle.x+this.rectangle.width-TOGGLEWIDTH
this.pos=v
this.rectangle.y=this.pos.y+this.yOffset
this.activeRectangle.y=this.rectangle.y
this.textY=this.rectangle.y+this.rectangle.height/2+TEXTYOFFSET
end
function this.setWidth(newWidth)
if this.parent.setChildWidth~=nil then
this.parent.setChildWidth(newWidth)
else
this.parent.expandMain(newWidth)
end
end
function this.setWidthInternal(newWidth)
this.rectangle.width=newWidth
this.activeRectangle.x=this.rectangle.x+newWidth-TOGGLEWIDTH
end
function this.setHeight(newHeight)
this.rectangle.height=newHeight
this.activeRectangle.height=this.rectangle.height
this.textY=this.rectangle.y+this.height/2+TEXTYOFFSET
this.parent.calculateY()
end
function this.onLoop()
if this.active then
if this.dragging then
tempVec=mousePos().sub(this.dragPos)
if this.dragUnlocked then
this.dragPos=mousePos()
this.mainMenu.setMenuPosition(tempVec.add(this.mainMenu.pos))
elseif not this.dragUnlocked and tempVec.len2()>100 then
this.dragUnlocked=true
this.dragPos=mousePos()
end
end
end
this.rectangle.draw(MENUBGCOLOR)
if this.valueActive then
this.activeRectangle.draw(0xFF008000)
DrawText("On", 15, this.pos.x+this.rectangle.width-25, this.textY, MENUTEXTCOLOR)
else
this.activeRectangle.draw(0xFFFF0000)
DrawText("Off", 15, this.pos.x+this.rectangle.width-25, this.textY, MENUTEXTCOLOR)
end
FillRect(this.activeRectangle.x-2,this.activeRectangle.y,1,this.activeRectangle.height,MENUBORDERCOLOR)
DrawText(this.name, 15, this.pos.x+5, this.textY, MENUTEXTCOLOR)
FillRect(this.rectangle.x,this.rectangle.y,this.rectangle.width,2,MENUBORDERCOLOR)
end
function this.show()
end
function this.hide()
end
return this
end
MenuStringList={}
function MenuStringList.new(name, stringlist, index)
--item fields
local this = {}
this.name = name or "Unnamed"
this.stringlist=stringlist or {"Empty"}
this.selectedIndex=index or 1
this.parent=parent
this.mainMenu=nil
this.textY=0
this.yOffset=0
this.pos=Vector2.new()
this.rectangle = Rectangle.new(0, 0, ITEMWIDTH, ITEMHEIGHT)
this.leftRectangle = Rectangle.new(0, 0, TOGGLEWIDTH, ITEMHEIGHT)
this.rightRectangle = Rectangle.new(0, 0, TOGGLEWIDTH, ITEMHEIGHT)
this.textlengthAdd=80+getLongestString(this.stringlist)
this.isShow = false
function this.processInput(key, pressed, mouseVector)
if isShow and key==1 and pressed then
if this.leftRectangle.contains(mouseVector) then
if this.selectedIndex==1 then
this.selectedIndex=#this.stringlist
else
this.selectedIndex=this.selectedIndex-1
end
elseif this.rightRectangle.contains(mouseVector) then
if this.selectedIndex==#this.stringlist then
this.selectedIndex=1
else
this.selectedIndex=this.selectedIndex+1
end
end
end
end
function this.getValue()
return this.selectedIndex
end
function this.setValue(va)
this.selectedIndex=(math.abs(round(va-1))%#this.stringlist)+1
end
function this.expand(newWidth)
this.parent.expandChild(newWidth)
end
function this.setYoffset(newoff)
this.yOffset=newoff
this.rectangle.y=this.pos.y+this.yOffset
this.leftRectangle.y=this.rectangle.y
this.rightRectangle.y=this.rectangle.y
this.textY=this.rectangle.y+this.rectangle.height/2+TEXTYOFFSET
end
function this.setPosition(v)
this.rectangle.x=v.x
this.leftRectangle.x=this.rectangle.x+this.rectangle.width-TOGGLEWIDTH*2-2
this.rightRectangle.x=this.rectangle.x+this.rectangle.width-TOGGLEWIDTH
this.pos=v
this.rectangle.y=this.pos.y+this.yOffset
this.leftRectangle.y=this.rectangle.y
this.rightRectangle.y=this.rectangle.y
this.textY=this.rectangle.y+this.rectangle.height/2+TEXTYOFFSET
end
function this.setWidth(newWidth)
if this.parent.setChildWidth~=nil then
this.parent.setChildWidth(newWidth)
else
this.parent.expandMain(newWidth)
end
end
function this.setWidthInternal(newWidth)
this.rectangle.width=newWidth
this.leftRectangle.x=this.rectangle.x+newWidth-TOGGLEWIDTH*2-2
this.rightRectangle.x=this.rectangle.x+newWidth-TOGGLEWIDTH
end
function this.setHeight(newHeight)
this.rectangle.height=newHeight
this.leftRectangle.height=this.rectangle.height
this.rightRectangle.height=this.rectangle.height
this.textY=this.rectangle.y+this.height/2+TEXTYOFFSET
this.parent.calculateY()
end
function this.onLoop()
this.rectangle.draw(MENUBGCOLOR)
this.leftRectangle.draw(4278190335)
this.rightRectangle.draw(4278190335)
FillRect(this.leftRectangle.x-2,this.leftRectangle.y,1,this.leftRectangle.height,MENUBORDERCOLOR)
FillRect(this.rightRectangle.x-2,this.rightRectangle.y,1,this.rightRectangle.height,MENUBORDERCOLOR)
DrawText(">", 15, this.rightRectangle.x+10, this.textY, MENUTEXTCOLOR)
DrawText("<", 15, this.leftRectangle.x+10, this.textY, MENUTEXTCOLOR)
DrawText(this.name, 15, this.pos.x+5, this.textY, MENUTEXTCOLOR)
DrawText(this.stringlist[this.selectedIndex], 15, this.leftRectangle.x-getTextWidth(this.stringlist[this.selectedIndex], 5), this.textY, MENUTEXTCOLOR)
FillRect(this.rectangle.x,this.rectangle.y,this.rectangle.width,2,MENUBORDERCOLOR)
end
function this.show()
isShow = true
end
function this.hide()
isShow = false
end
return this
end
MenuSlider={}
function MenuSlider.new(name, value, mi, ma, step)
--item fields
local this = {}
this.name = name or "Unnamed"
this.min = mi or 0
this.max = ma or 10
if value==nil or valuethis.max then val=this.max end
this.value=val
this.updateSlider()
end
function this.expand(newWidth)
this.parent.expandChild(newWidth)
end
function this.updateSlider()
this.sliderRectangle.x=2+this.rectangle.x+(this.rectangle.width-5)*(this.value-this.min)/(this.max-this.min)
this.sliderRectangle.y=this.rectangle.y
end
function this.setYoffset(newoff)
this.yOffset=newoff
this.rectangle.y=this.pos.y+this.yOffset
this.sliderRectangle.y=this.rectangle.y
this.updateSlider()
this.textY=this.rectangle.y+this.rectangle.height/2+TEXTYOFFSET
end
function this.setPosition(v)
this.rectangle.x=v.x
this.pos=v
this.rectangle.y=this.pos.y+this.yOffset
this.sliderRectangle.y=this.rectangle.y
this.updateSlider()
this.textY=this.rectangle.y+this.rectangle.height/2+TEXTYOFFSET
end
function this.setWidth(newWidth)
if this.parent.setChildWidth~=nil then
this.parent.setChildWidth(newWidth)
else
this.parent.expandMain(newWidth)
end
end
function this.setWidthInternal(newWidth)
this.rectangle.width=newWidth
this.updateSlider()
end
function this.setHeight(newHeight)
this.rectangle.height=newHeight
this.sliderRectangle.height=this.rectangle.height
this.updateSlider()
this.textY=this.rectangle.y+this.height/2+TEXTYOFFSET
this.parent.calculateY()
end
function this.onLoop()
if this.sliderActive then
local val = roundStep(mousePos().sub(this.rectangle).x/this.rectangle.width*(this.max-this.min)+this.min, this.step)
if valthis.max then val=this.max end
this.value=val
this.updateSlider()
end
this.rectangle.draw(MENUBGCOLOR)
this.sliderRectangle.draw(0xFFFFFF00)
DrawText(this.name, 15, this.pos.x+5, this.textY, MENUTEXTCOLOR)
local textval=string.format("%."..this.places.."f", this.value)
DrawText(textval, 15, this.pos.x+this.rectangle.width-getTextWidth(textval, 10), this.textY, MENUTEXTCOLOR)
FillRect(this.rectangle.x,this.rectangle.y,this.rectangle.width,2,MENUBORDERCOLOR)
end
function this.show()
end
function this.hide()
this.sliderActive=false
end
return this
end
--ENDREGION Menu---------------------------------------------------------------}
--REGION GOSUTILITY------------------------------------------------------------
--{
local GOSUactive=false
function extensionsActive()
return GOSUActive
end
function listScripts()
local ret={}
for k, v in pairs(g.listScripts()) do
table.insert(ret, v)
end
return ret
end
function print(text)
return g.print(text) end
function printn(text)
return g.printn(text) end
function closeConsole()
return g.closeConsole() end
function saveScript(name, script)
g.saveScript(name, script) end
function webRequest(server, address)
local result=g.request(server, address)
if result=="" or result=="Not found" then return nil end
return result end
-- function mousePos()
-- local pos
-- if g then
-- pos=g.mousePos()
-- return Vector2.new(pos[1], pos[2])
-- else
-- pos=GetMousePos()
-- pos=WorldToScreen(1, pos.x, pos.y, pos.z)
-- return Vector2.new(pos)
-- end
-- end
function getResolution()
local res = g.resolution()
return Vector2.new(res[1], res[2])
end
function gVersion()
return g.version()
end
function lolVersion()
return g.getLolVersion()
end
--ENDREGION GOSUTILITY---------------------------------------------------------}
--REGION key and mouse events--------------------------------------------------
--{
local keys={}
local subscribers={}
local inputEventsActive=false
for i=1, 255, 1 do
keys[i]=false
end
function pollKeysOnLoop()
if not inputEventsActive then return end
for i=1, 255, 1 do
if i~=117 and i~=118 then
local state=KeyIsDown(i)
if keys[i]~=state then
broadcastEvent(i, state)
end
keys[i]=state
end
end
end
function broadcastEvent(keyCode, pressed)
for i, subs in ipairs(subscribers) do
subs(keyCode, pressed)
end
end
function registerInputListener(listener)
if type(listener)=="function" then
inputEventsActive=true
subscribers[#subscribers+1]=listener
return #subscribers
else
PrintChat("Script tried to register non function as an event listener!")
end
end
function unregisterInputListener(num)
subscribers[num]=nil
if next(subscribers) == nil then inputEventsActive=false end
end
--ENDREGION key and mouse events-----------------------------------------------}
--REGION Geometry--------------------------------------------------------------
--{
Vector2={}
function Vector2.new(x, y)
local this = {}
if type(x)=="table" then
this.x=x.x or 0
this.y=x.y or 0
else
this.x=x or 0
this.y=y or 0
end
function this.cpy()
return Vector2.new(this)
end
function this.len()
return math.sqrt(this.x * this.x + this.y * this.y)
end
function this.len2()
return this.x * this.x + this.y * this.y
end
function this.set(x, y)
if type(x)=="table" then
this.x=x.x
this.y=x.y
else
this.x=x
this.y=y
end
return this
end
function this.sub(x, y)
if type(x)=="table" then
this.x=this.x-x.x
this.y=this.y-x.y
else
this.x=this.x-x
this.y=this.y-y
end
return this
end
function this.add(x, y)
if type(x)=="table" then
this.x=this.x+x.x
this.y=this.y+x.y
else
this.x=this.x+x
this.y=this.y+y
end
return this
end
function this.nor(x, y)
l = this.len()
if l ~= 0 then
this.x =x/l
this.y =y/l
end
return this
end
function this.dot(x, y)
if type(x)=="table" then
return this.x * x.x + this.y * x.y
else
return this.x * x + this.y * y
end
end
function this.scl(scalar)
this.x=this.x*scalar
this.y=this.y*scalar
return this
end
function this.scl2(x, y)
if type(x)=="table" then
this.x=this.x*x.x
this.y=this.y*x.y
else
this.x=this.x*x
this.y=this.y*y
end
return this
end
function this.dst(x, y)
local x_d, y_d
if type(x)=="table" then
x_d = x.x-this.x
y_d = x.y-this.y
else
x_d = x-this.x
y_d = y-this.y
end
return math.sqrt(x_d * x_d + y_d * y_d)
end
function this.limit(limit)
return this.limit2(limit * limit)
end
function this.limit2(limit2)
local len2=this.len2()
if len2 > limit2 then
return this.scl(math.sqrt(limit2 / len2)) end
return this
end
function this.clamp (mi, ma)
local len2 = this.len2()
if (len2 == 0) then
return this end
local max2 = ma * ma
if (len2 > max2) then
return this.scl(math.sqrt(max2 / len2)) end
local min2 = mi * mi
if (len2 < min2) then
return this.scl(math.sqrt(min2 / len2)) end
return this
end
function this.setLength (l)
return this.setLength2( l * l )
end
function this.setLength2 (len2)
local oldLen2 = len2()
if oldLen2 == 0 or oldLen2 == len2 then
return this
else
return this.scl(math.sqrt( len2 / oldLen2 ))
end
end
function this.toString()
return "[" .. this.x .. ":" .. this.y .. "]"
end
function this.crs(x, y)
if type(x)=="table" then
return this.x * x.y - this.y * x.x
else
return this.x * y - this.y * x
end
end
function this.angle (reference)
if reference==nil then
local angle = math.atan2(this.y, this.x) * radiansToDegrees
if angle < 0 then angle=angle+360 end
return angle
else
return math.atan2(this.crs(reference), this.dot(reference)) *radiansToDegrees
end
end
function this.angleRad (reference)
if reference==nil then
return math.atan2(this.y, this.x)
else
return math.atan2(this.crs(reference), this.dot(reference))
end
end
function this.setAngle (degrees)
return this.setAngleRad(degrees * degreesToRadians)
end
function this.setAngleRad (radians)
this.set(this.len(), 0)
this.rotateRad(radians)
return this
end
function this.rotate (degrees)
return rotateRad(degrees * degreesToRadians)
end
function this.rotateRad (radians)
local co = math.cos(radians)
local si = math.sin(radians)
local newX = this.x * co - this.y * si
local newY = this.x * si + this.y * co
this.x = newX
this.y = newY
return this
end
function this.rotate90 (dir)
local x = this.x
if (dir >= 0) then
this.x = -this.y
this.y = x
else
this.x = this.y
this.y = -x
end
return this
end
function this.lerp (target, alpha)
local invAlpha = 1 - alpha
this.x = (this.x * invAlpha) + (target.x * alpha)
this.y = (this.y * invAlpha) + (target.y * alpha)
return this
end
function this.equals (obj)
if this == obj then return true end
if obj == nil or obj.x~=this.x or obj.y~=this.y then return false end
return true
end
function this.epsilonEquals (other, epsilon)
if other == nil then return false end
if math.abs(other.x - this.x) > epsilon then return false end
if math.abs(other.y - this.y) > epsilon then return false end
return true
end
function this.isUnit (margin)
local margin=margin or 0.000000001
return math.abs(this.len2() - 1) < margin
end
function this.isZero (margin)
local margin=margin or 0.000000001
return math.abs(this.len2()) < margin
end
function this.isOnLine (other, epsilon)
local epsilon=epsilon or 0.000001
return isZero(this.x * other.y - this.y * other.x, epsilon)
end
function this.isCollinear (other, epsilon)
local epsilon=epsilon or 0.000001
return this.isOnLine(other, epsilon) and this.dot(other) > 0
end
function this.isCollinearOpposite (other, epsilon)
local epsilon=epsilon or 0.000001
return this.isOnLine(other, epsilon) and this.dot(other) < 0
end
function this.isPerpendicular (other, epsilon)
local epsilon=epsilon or 0.000001
return isZero(this.dot(other), epsilon)
end
function this.hasSameDirection (other)
return dot(other) > 0
end
function this.hasOppositeDirection (other)
return dot(other) < 0
end
function this.setZero (other)
this.x = 0
this.y = 0
return this
end
return this
end
Rectangle={}
function Rectangle.new(x, y, width, height)
local this = {}
if type(x)=="table" then
this.x = x.x
this.y = x.y
this.width = x.width
this.height = x.height
else
this.x = x or 0
this.y = y or 0
this.width = width or 0
this.height = height or 0
end
function this.set(x, y, width, height)
if type(x)=="table" then
this.x = x.x
this.y = x.y
this.width = x.width
this.height = x.height
else
this.x = x or 0
this.y = y or 0
this.width = width or 0
this.height = height or 0
end
return this
end
function this.setPosition(x, y)
if type(x)=="table" then
this.x = x.x
this.y = x.y
else
this.x = x or 0
this.y = y or 0
end
return this
end
function this.setSize(width, height)
if type(x)=="table" then
this.width = x.width
this.height = x.height
else
this.width = width or 0
this.height = height or 0
end
return this
end
function this.contains(x, y)
if type(x)=="table" then
if width == nil then
local xmin = x.x
local xmax = xmin + x.width
local ymin = x.y
local ymax = ymin + x.height
return ((xmin > this.x and xmin < this.x + width) and (xmax > this.x and xmax < this.x + width))
and ((ymin > this.y and ymin < this.y + height) and (ymax > this.y and ymax < this.y + height))
else
return this.x <= x.x and this.x + this.width >= x.x and this.y <= x.y and this.y + this.height >= x.y
end
else
return this.x <= x and this.x + this.width >= x and this.y <= y and this.y + this.height >= y
end
end
function overlaps(r)
return this.x < r.x + r.width and this.x + this.width > r.x and y < r.y + r.height and this.y + this.height > r.y
end
function this.merge(x, y)
if type(x)=="table" then
if x.x==nil then --Vector2 array
local minX = this.x
local maxX = this.x + this.width
local minY = this.y
local maxY = this.y + this.height
for i, v in ipairs(x) do
minX = math.min(minX, v.x)
maxX = math.max(maxX, v.x)
minY = math.min(minY, v.y)
maxY = math.max(maxY, v.y)
end
this.x = minX
this.width = maxX - minX
this.y = minY
this.height = maxY - minY
elseif x.width==nil then --Vector2
return merge(x.x, x.y)
else --Rectangle
local minX = math.min(this.x, rect.x)
local maxX = math.max(this.x + this.width, rect.x + rect.width)
this.x = minX;
this.width = maxX - minX
local minY = math.min(this.y, rect.y)
local maxY = math.max(this.y + this.height, rect.y + rect.height)
this.y = minY
this.height = maxY - minY
end
else --2 numbers
local minX = math.min(this.x, x)
local maxX = math.max(this.x + width, x)
this.x = minX
this.width = maxX - minX
local minY = math.min(this.y, y)
local maxY = math.max(this.y + this.height, y)
this.y = minY
this.height = maxY - minY
end
return this
end
function this.getAspectRatio()
if this.height == 0 then
return math.huge
else
return this.width / this.height
end
end
function this.setCenter(x, y)
if type(x)=="table" then
this.setPosition(x.x - this.width / 2, x.y - this.height / 2)
else
this.setPosition(x - this.width / 2, y - this.height / 2)
end
return this
end
function this.area()
return this.width*this.height
end
function this.perimeter()
return 2 * (this.width + this.height)
end
function this.toString()
return this.x .. "," .. this.y .. "," .. this.width .. "," .. this.height
end
function this.equals (obj)
if this == obj then return true end
if obj == nil or obj.x~=this.x or obj.y~=this.y or obj.width~=this.width or obj.height~=this.height then return false end
return true
end
function this.draw (color)
FillRect(this.x,this.y,this.width, this.height, color or 0x90000000)
end
return this
end
DCircle={}
function DCircle.new(x, y, radius)
local this = {}
if type(x)=="table" then
if type(y)=="table" then--center and edge
this.x = center.x
this.y = center.y
this.radius = Vector2.new(x.x - y.x, x.y - y.y).len()
else
this.x = x.x
this.y = x.y
this.radius = x.radius
end
else
this.x = x or 0
this.y = y or 0
this.radius = radius or 0
end
function this.set(x, y, radius)
if type(x)=="table" then
if type(y)=="table" then--center and edge
this.x = center.x
this.y = center.y
this.radius = Vector2.new(x.x - y.x, x.y - y.y).len()
else
this.x = x.x
this.y = x.y
this.radius = x.radius
end
else
this.x = x or 0
this.y = y or 0
this.radius = radius or 0
end
return this
end
function this.setPosition(x, y)
if type(x)=="table" then
this.x = x.x
this.y = x.y
else
this.x = x or 0
this.y = y or 0
end
return this
end
function this.contains(x, y)
if type(x)=="table" then
if x.radius==nil then
local dx = this.x - x.x
local dy = this.y - x.y
return dx * dx + dy * dy <= this.radius * this.radius
else
local radiusDiff = radius - x.radius
if radiusDiff < 0 then return false end
local dx = this.x - x.x
local dy = this.y - x.y
local dst = dx * dx + dy * dy
local radiusSum = this.radius + x.radius
return (not(radiusDiff * radiusDiff < dst) and (dst < radiusSum * radiusSum))
end
else
local x = this.x - x
local y = this.y - y
return x * x + y * y <= this.radius * this.radius
end
end
function this.overlaps(c)
local dx = this.x - c.x
local dy = this.y - c.y
local distance = dx * dx + dy * dy
local radiusSum = this.radius + c.radius
return distance < radiusSum * radiusSum
end
function this.area()
return this.radius * this.radius * math.pi
end
function this.circumference()
return 2 * this.radius * math.pi
end
function this.toString()
return this.x .. "," .. this.y .. "," .. this.radius;
end
function this.equals (obj)
if this == obj then return true end
if obj == nil or obj.x~=this.x or obj.y~=this.y or obj.radius~=this.radius then return false end
return true
end
function this.draw (color)
FillRect(this.x,this.y,this.width, this.height, color or 0x90000000)
end
return this
end
radiansToDegrees=180/math.pi
degreesToRadians = math.pi / 180
function isZero(value, epsilon)
local tolerance=tolerance or 0.000001
return math.abs(value) <= tolerance
end
--ENDREGION Geometry---------------------------------------------------------------}
--REGION Config, serializer--------------------------------------------------------------
--{
Config={}
function Config.new()
this={}
this.name="Config"
this.newline="\n"
this.config={}
function this.load()
local c=prequire(this.name, true)
if c~=nil and type(c)=="table" then
this.config=c
end
end
function this.save()
if not g then return end
local index=1
local buf = {[[local c={}]]}
index=index+1
buf[index]=this.serializeTable(this.config, "c")
index=index+1
buf[index]=[[return c]]
index=index+1
buf[index]=this.newline
index=index+1
saveScript("Common\\"..this.name, table.concat( buf ))
end
function this.serializeTable(tab, prefix)
local index=1
local buf = {}
buf[index]=this.newline
index=index+1
for key, value in pairs(tab) do
if type(key)=="number" then
buf[index]=prefix.."["..key.."]="
else
buf[index]=prefix..'["'..stripchars(key, "\n\a\b\f\r\t\v\"%[%]" )..'"]='
end
index=index+1
local valtype=type(value)
if valtype=="number" then
buf[index]=value
index=index+1
elseif valtype=="table" then
buf[index]="{}"
index=index+1
if type(key)=="number" then
buf[index]=this.serializeTable(value, prefix.."["..key.."]")
else
buf[index]=this.serializeTable(value, prefix..'["'..stripchars(key, "\n\a\b\f\r\t\v\"%[%]" )..'"]')
end
index=index+1
elseif valtype=="string" then
buf[index]="[["..stripchars(value, "\n\a\b\f\r\t\v\"%[%]" ).."]]"
index=index+1
elseif valtype=="boolean" then
buf[index]=tostring(value)
index=index+1
else
buf[index]="type not supported :("
index=index+1
end
buf[index]=this.newline
index=index+1
end
return table.concat( buf )
end
return this
end
--ENDREGION Config, serializer-----------------------------------------------------------}
--REGION Updater--------------------------------------------------------------
--{
Updater={}
function Updater.new(address, name, version)
local this = {}
this.address=address
this.version=version
this.name=name
function this.newVersion()
if not updaterActive.getValue() or not g then return false end
this.response=webRequest("github", this.address.."?rand="..math.random(1,10000))
if this.response==nil then return false end
this.remoteVersion = string.match(this.response, "local version = %d+")
if this.remoteVersion==nil then
this.response=nil
return false
end
this.remoteVersion = tonumber(string.match(this.remoteVersion, "%d+"))
return this.remoteVersion>this.version
end
function this.update()
if this.response==nil then end
saveScript(this.name, this.response)
delay(function() notification(this.name.." updated.\n F6-F6 to reload.", 5000) end, 5000)
end
return this
end
--ENDREGION Updater-----------------------------------------------------------}
package.cpath=string.gsub(package.path, ".lua", ".dll")
c=Config.new()
c.load()
menu=MainMenu.new()
updaterActive=menu.addItem(MenuBool.new("Updater active", true))
local streammode=menu.addItem(MenuBool.new("stream mode(press F6F6 after change this settings)", false))
if streammode.getValue() then
_G.DrawText = function ( ... ) end
_G.DrawCircle = function ( ... ) end
_G.FillRect = function ( ... ) end
end
local fixOnRemoveBuff = menu.addItem(MenuBool.new("fix OnRemoveBuff api(press F6F6 after change this settings)", false))
local OnRemoveBuffCallbackList = {}
local trackBuffList = {}
if fixOnRemoveBuff.getValue() then
_G.OnRemoveBuff = function (callback)
table.insert(OnRemoveBuffCallbackList, callback)
end
OnUpdateBuff(function(object,buffProc)
if trackBuffList[object] then
trackBuffList[object][buffProc.Name] = buffProc
else
trackBuffList[object] = {}
trackBuffList[object][buffProc.Name] = buffProc
end
end)
OnTick(function(myHero)
for object,buffProcList in pairs(trackBuffList) do
for buffName,buffProc in pairs(buffProcList) do
if GotBuff(myHero, buffName) == 0 then
for _,callback in pairs(OnRemoveBuffCallbackList) do
callback(object, buffProc)
end
trackBuffList[object][buffName] = nil
end
end
end
end)
end
g=prequire("GOSUtility")
if g then
local UP=Updater.new("iLoveSona/GOS/master/Common/DLib.lua", "Common\\DLib", version)
if UP.newVersion() then UP.update() end
if gVersion()<8 then
notification("plz Redownload GOSUtility", 10000)
else
local versionCode = lolVersion()
if versionCode then
PrintChat("lol version : "..versionCode)
closeConsole()
else
PrintChat("lol version : not found")
end
end
else
PrintChat("GOSUtility.dll not found. Functions using GOSUtility won't work.")
end
OnTick(function()
local tickcount=GetTickCount()
pollKeysOnLoop()
delayedOnLoop(tickcount)
end)
OnDraw(function()
local tickcount=GetTickCount()
notificationsOnLoop(tickcount)
menu.onLoop()
end)
PrintChat("[DLib] v"..version.." : loaded")
--Inspired lib----------------------------------------------------------------
-- copy paste some useful api coz too lazy to require two lib....
-- function VectorType(v)
-- v = GetOrigin(v) or v
-- return v and v.x and type(v.x) == "number" and ((v.y and type(v.y) == "number") or (v.z and type(v.z) == "number"))
-- end
-- class 'Vector'
-- function Vector:__init(a, b, c)
-- if a == nil then
-- self.x, self.y, self.z = 0.0, 0.0, 0.0
-- elseif b == nil then
-- a = GetOrigin(a) or a
-- assert(VectorType(a), "Vector: wrong argument types (expected nil or or 2 or 3 )")
-- self.x, self.y, self.z = a.x, a.y, a.z
-- else
-- assert(type(a) == "number" and (type(b) == "number" or type(c) == "number"), "Vector: wrong argument types ( or 2 or 3 )")
-- self.x = a
-- if b and type(b) == "number" then self.y = b end
-- if c and type(c) == "number" then self.z = c end
-- end
-- end
-- function Vector:__type()
-- return "Vector"
-- end
-- function Vector:__add(v)
-- assert(VectorType(v) and VectorType(self), "add: wrong argument types ( expected)")
-- return Vector(self.x + v.x, (v.y and self.y) and self.y + v.y, (v.z and self.z) and self.z + v.z)
-- end
-- function Vector:__sub(v)
-- assert(VectorType(v) and VectorType(self), "Sub: wrong argument types ( expected)")
-- return Vector(self.x - v.x, (v.y and self.y) and self.y - v.y, (v.z and self.z) and self.z - v.z)
-- end
-- function Vector.__mul(a, b)
-- if type(a) == "number" and VectorType(b) then
-- return Vector({ x = b.x * a, y = b.y and b.y * a, z = b.z and b.z * a })
-- elseif type(b) == "number" and VectorType(a) then
-- return Vector({ x = a.x * b, y = a.y and a.y * b, z = a.z and a.z * b })
-- else
-- assert(VectorType(a) and VectorType(b), "Mul: wrong argument types ( or expected)")
-- return a:dotP(b)
-- end
-- end
-- function Vector.__div(a, b)
-- if type(a) == "number" and VectorType(b) then
-- return Vector({ x = a / b.x, y = b.y and a / b.y, z = b.z and a / b.z })
-- else
-- assert(VectorType(a) and type(b) == "number", "Div: wrong argument types ( expected)")
-- return Vector({ x = a.x / b, y = a.y and a.y / b, z = a.z and a.z / b })
-- end
-- end
-- function Vector.__lt(a, b)
-- assert(VectorType(a) and VectorType(b), "__lt: wrong argument types ( expected)")
-- return a:len() < b:len()
-- end
-- function Vector.__le(a, b)
-- assert(VectorType(a) and VectorType(b), "__le: wrong argument types ( expected)")
-- return a:len() <= b:len()
-- end
-- function Vector:__eq(v)
-- assert(VectorType(v), "__eq: wrong argument types ( expected)")
-- return self.x == v.x and self.y == v.y and self.z == v.z
-- end
-- function Vector:__unm()
-- return Vector(-self.x, self.y and -self.y, self.z and -self.z)
-- end
-- function Vector:__vector(v)
-- assert(VectorType(v), "__vector: wrong argument types ( expected)")
-- return self:crossP(v)
-- end
-- function Vector:__tostring()
-- if self.y and self.z then
-- return "(" .. tostring(self.x) .. "," .. tostring(self.y) .. "," .. tostring(self.z) .. ")"
-- else
-- return "(" .. tostring(self.x) .. "," .. self.y and tostring(self.y) or tostring(self.z) .. ")"
-- end
-- end
-- function Vector:clone()
-- return Vector(self)
-- end
-- function Vector:unpack()
-- return self.x, self.y, self.z
-- end
-- function Vector:len2(v)
-- assert(v == nil or VectorType(v), "dist: wrong argument types ( expected)")
-- local v = v and Vector(v) or self
-- return self.x * v.x + (self.y and self.y * v.y or 0) + (self.z and self.z * v.z or 0)
-- end
-- function Vector:len()
-- return math.sqrt(self:len2())
-- end
-- function Vector:dist(v)
-- assert(VectorType(v), "dist: wrong argument types ( expected)")
-- local a = self - v
-- return a:len()
-- end
-- function Vector:normalize()
-- local a = self:len()
-- self.x = self.x / a
-- if self.y then self.y = self.y / a end
-- if self.z then self.z = self.z / a end
-- end
-- function Vector:normalized()
-- local a = self:clone()
-- a:normalize()
-- return a
-- end
-- function Vector:center(v)
-- assert(VectorType(v), "center: wrong argument types ( expected)")
-- return Vector((self + v) / 2)
-- end
-- function Vector:crossP(other)
-- assert(self.y and self.z and other.y and other.z, "crossP: wrong argument types (3 Dimensional expected)")
-- return Vector({
-- x = other.z * self.y - other.y * self.z,
-- y = other.x * self.z - other.z * self.x,
-- z = other.y * self.x - other.x * self.y
-- })
-- end
-- function Vector:dotP(other)
-- assert(VectorType(other), "dotP: wrong argument types ( expected)")
-- return self.x * other.x + (self.y and (self.y * other.y) or 0) + (self.z and (self.z * other.z) or 0)
-- end
-- function Vector:projectOn(v)
-- assert(VectorType(v), "projectOn: invalid argument: cannot project Vector on " .. type(v))
-- if type(v) ~= "Vector" then v = Vector(v) end
-- local s = self:len2(v) / v:len2()
-- return Vector(v * s)
-- end
-- function Vector:mirrorOn(v)
-- assert(VectorType(v), "mirrorOn: invalid argument: cannot mirror Vector on " .. type(v))
-- return self:projectOn(v) * 2
-- end
-- function Vector:sin(v)
-- assert(VectorType(v), "sin: wrong argument types ( expected)")
-- if type(v) ~= "Vector" then v = Vector(v) end
-- local a = self:__vector(v)
-- return math.sqrt(a:len2() / (self:len2() * v:len2()))
-- end
-- function Vector:cos(v)
-- assert(VectorType(v), "cos: wrong argument types ( expected)")
-- if type(v) ~= "Vector" then v = Vector(v) end
-- return self:len2(v) / math.sqrt(self:len2() * v:len2())
-- end
-- function Vector:angle(v)
-- assert(VectorType(v), "angle: wrong argument types ( expected)")
-- return math.acos(self:cos(v))
-- end
-- function Vector:affineArea(v)
-- assert(VectorType(v), "affineArea: wrong argument types ( expected)")
-- if type(v) ~= "Vector" then v = Vector(v) end
-- local a = self:__vector(v)
-- return math.sqrt(a:len2())
-- end
-- function Vector:triangleArea(v)
-- assert(VectorType(v), "triangleArea: wrong argument types ( expected)")
-- return self:affineArea(v) / 2
-- end
-- function Vector:rotateXaxis(phi)
-- assert(type(phi) == "number", "Rotate: wrong argument types (expected for phi)")
-- local c, s = math.cos(phi), math.sin(phi)
-- self.y, self.z = self.y * c - self.z * s, self.z * c + self.y * s
-- end
-- function Vector:rotateYaxis(phi)
-- assert(type(phi) == "number", "Rotate: wrong argument types (expected for phi)")
-- local c, s = math.cos(phi), math.sin(phi)
-- self.x, self.z = self.x * c + self.z * s, self.z * c - self.x * s
-- end
-- function Vector:rotateZaxis(phi)
-- assert(type(phi) == "number", "Rotate: wrong argument types (expected for phi)")
-- local c, s = math.cos(phi), math.sin(phi)
-- self.x, self.y = self.x * c - self.z * s, self.y * c + self.x * s
-- end
-- function Vector:rotate(phiX, phiY, phiZ)
-- assert(type(phiX) == "number" and type(phiY) == "number" and type(phiZ) == "number", "Rotate: wrong argument types (expected for phi)")
-- if phiX ~= 0 then self:rotateXaxis(phiX) end
-- if phiY ~= 0 then self:rotateYaxis(phiY) end
-- if phiZ ~= 0 then self:rotateZaxis(phiZ) end
-- end
-- function Vector:rotated(phiX, phiY, phiZ)
-- assert(type(phiX) == "number" and type(phiY) == "number" and type(phiZ) == "number", "Rotated: wrong argument types (expected for phi)")
-- local a = self:clone()
-- a:rotate(phiX, phiY, phiZ)
-- return a
-- end
-- -- not yet full 3D functions
-- function Vector:polar()
-- if math.close(self.x, 0) then
-- if (self.z or self.y) > 0 then return 90
-- elseif (self.z or self.y) < 0 then return 270
-- else return 0
-- end
-- else
-- local theta = math.deg(math.atan((self.z or self.y) / self.x))
-- if self.x < 0 then theta = theta + 180 end
-- if theta < 0 then theta = theta + 360 end
-- return theta
-- end
-- end
-- function Vector:angleBetween(v1, v2)
-- assert(VectorType(v1) and VectorType(v2), "angleBetween: wrong argument types (2 expected)")
-- local p1, p2 = (-self + v1), (-self + v2)
-- local theta = p1:polar() - p2:polar()
-- if theta < 0 then theta = theta + 360 end
-- if theta > 180 then theta = 360 - theta end
-- return theta
-- end
-- function Vector:compare(v)
-- assert(VectorType(v), "compare: wrong argument types ( expected)")
-- local ret = self.x - v.x
-- if ret == 0 then ret = self.z - v.z end
-- return ret
-- end
-- function Vector:perpendicular()
-- return Vector(-self.z, self.y, self.x)
-- end
-- function Vector:perpendicular2()
-- return Vector(self.z, self.y, -self.x)
-- end
local myHero = GetMyHero()
local myTeam = GetTeam(myHero)
local summonerNameOne = GetCastName(myHero,SUMMONER_1)
local summonerNameTwo = GetCastName(myHero,SUMMONER_2)
_G.Ignite = (summonerNameOne:lower():find("summonerdot") and SUMMONER_1 or (summonerNameTwo:lower():find("summonerdot") and SUMMONER_2 or nil))
_G.Smite = (summonerNameOne:lower():find("summonersmite") and SUMMONER_1 or (summonerNameTwo:lower():find("summonersmite") and SUMMONER_2 or nil))
_G.Exhaust = (summonerNameOne:lower():find("summonerexhaust") and SUMMONER_1 or (summonerNameTwo:lower():find("summonerexhaust") and SUMMONER_2 or nil))
local ilib = {}
function ilib.IsInDistance(p1,r)
return ilib.GetDistanceSqr(GetOrigin(p1)) < r*r
end
function ilib.GetDistance(p1,p2)
if not p1 then
PrintChat("GetDistance failed : "..debug.getinfo(2).name)
return
end
if p1.x and p1.y and p1.z then
-- do nothing
else
-- p1 = GetOrigin(p1) or p1
p1 = GetOrigin(p1)
end
p2 = (p2 and GetOrigin(p2)) or GetOrigin(myHero)
return math.sqrt(ilib.GetDistanceSqr(p1,p2))
end
function ilib.GetDistanceSqr(p1,p2)
if not p1 then
PrintChat("GetDistanceSqr failed : "..debug.getinfo(2).name)
return
end
p2 = p2 or GetOrigin(myHero)
local dx = p1.x - p2.x
local dz = (p1.z or p1.y) - (p2.z or p2.y)
return dx*dx + dz*dz
end
local bufflist = {
"sionpassivezombie"
}
function ilib.ValidTarget(unit, range)
range = range or 25000
if not unit or not GetOrigin(unit) or not IsTargetable(unit) or IsImmune(unit, myHero) or IsDead(unit) or not IsVisible(unit) or GetTeam(unit) == myTeam or not ilib.IsInDistance(unit, range) then return false end
for _,buff in ipairs(bufflist) do
if GotBuff(unit, buff) > 0 then return false end
end
return true
end
function ilib.CalcDamage(source, target, addmg, apdmg)
local ADDmg = addmg or 0
local APDmg = apdmg or 0
local ArmorPen = GetObjectType(source) == Obj_AI_Minion and 0 or math.floor(GetArmorPenFlat(source))
local ArmorPenPercent = GetObjectType(source) == Obj_AI_Minion and 1 or math.floor(GetArmorPenPercent(source)*100)/100
local Armor = GetArmor(target)*ArmorPenPercent-ArmorPen
local ArmorPercent = (GetObjectType(source) == Obj_AI_Minion and Armor < 0) and 0 or Armor > 0 and math.floor(Armor*100/(100+Armor))/100 or math.ceil(Armor*100/(100-Armor))/100
local MagicPen = math.floor(GetMagicPenFlat(source))
local MagicPenPercent = math.floor(GetMagicPenPercent(source)*100)/100
local MagicArmor = GetMagicResist(target)*MagicPenPercent-MagicPen
local MagicArmorPercent = MagicArmor > 0 and math.floor(MagicArmor*100/(100+MagicArmor))/100 or math.ceil(MagicArmor*100/(100-MagicArmor))/100
return (GotBuff(source,"exhausted") > 0 and 0.4 or 1) * math.floor(ADDmg*(1-ArmorPercent))+math.floor(APDmg*(1-MagicArmorPercent))
end
-- only hero
local objManager = {
uncheck = {},
enemyHeroes = {},
allyHeroes = {},
}
-- you need use callback by initCallback when you want use this api in load time
function ilib.GetEnemyHeroes()
return objManager.enemyHeroes
end
function ilib.GetAllyHeroes()
return objManager.allyHeroes
end
DAMAGE_MAGIC, DAMAGE_PHYSICAL = 1, 2
function ilib.GetTarget(range, damageType)
damageType = damageType or 2
local target, steps = nil, 10000
for _, k in pairs(ilib.GetEnemyHeroes()) do
local step = GetCurrentHP(k) / ilib.CalcDamage(GetMyHero(), k, DAMAGE_PHYSICAL == damageType and 100 or 0, DAMAGE_MAGIC == damageType and 100 or 0)
if k and ilib.ValidTarget(k, range+GetHitBox(k)) and step < steps then
target = k
steps = step
end
end
return target
end
local callbackList = {}
function ilib.initCallback(callback)
table.insert(callbackList, callback)
end
function ilib.init()
-- local done = false
-- OnLoop(function()
-- for _,object in pairs(objManager.uncheck) do
-- local objType = GetObjectType(object)
-- local objTeam = GetTeam(object)
-- if objType == Obj_AI_Hero and objTeam ~= myTeam then
-- objManager.enemyHeroes[object] = object
-- objManager.uncheck[object] = nil
-- end
-- end
-- done = true
-- end)
-- OnCreateObj(function(object)
-- local objType = GetObjectType(object)
-- local objTeam = GetTeam(object)
-- objManager.uncheck[object] = object
-- end)
-- OnDeleteObj(function(object)
-- local objType = GetObjectType(object)
-- local objTeam = GetTeam(object)
-- objManager.enemyHeroes[object] = nil
-- end)
local initHeroCounter = 0
-- local print = print
-- PrintChat not work here...don't know why(will miss print something)
OnObjectLoad(function(object)
if initHeroCounter >= 9 then return end
-- if done then return end
if GetObjectType(object) == Obj_AI_Hero then
local slot = GetNetworkID(object)
-- if objManager.allyHeroes[slot] or objManager.enemyHeroes[slot] then return end
if GetTeam(object) == GetTeam(myHero) then
objManager.allyHeroes[slot] = object
-- print(initHeroCounter.." allyHeroes : "..GetObjectName(object))
else
objManager.enemyHeroes[slot] = object
-- print(initHeroCounter.." enemyHeroes : "..GetObjectName(object))
end
initHeroCounter = initHeroCounter + 1
-- print(initHeroCounter)
if initHeroCounter >= 9 then
for _,callback in pairs(callbackList) do
callback(true)
end
end
end
end)
end
local function ExcludeFurthest(point, listOfEntities)
local removalId
for id,entity in pairs(listOfEntities) do
if not removalId or ilib.GetDistance(point, entity) > ilib.GetDistance(point, listOfEntities[removalId]) then
removalId = id
end
end
listOfEntities[removalId] = nil
return listOfEntities
end
-- minimum enclosing circle(MEC)
local function GetMEC(aoe_radius, listOfEntities)
local average = {x=0, y=0, z=0, count = 0}
for _,entity in pairs(listOfEntities) do
local ori = GetOrigin(entity)
average.x = average.x + ori.x
average.y = average.y + ori.y
average.z = average.z + ori.z
average.count = average.count + 1
end
-- list is empty
if average.count == 0 then return average end
average.x = average.x / average.count
average.y = average.y / average.count
average.z = average.z / average.count
local targetsInRange = 0
for _,entity in pairs(listOfEntities) do
if ilib.GetDistance(average, entity) <= aoe_radius then
targetsInRange = targetsInRange + 1
end
end
if targetsInRange == average.count then
return average
else
return GetMEC(aoe_radius, ExcludeFurthest(average, listOfEntities))
end
end
function ilib.GetPosForAoeSpell(startPos, castRange, spellRadius)
local list = ilib.GetEnemyHeroes()
local range = castRange + spellRadius
local tempList = {}
for key,enemy in pairs(list) do
if ilib.ValidTarget(enemy) and ilib.GetDistance(startPos, GetOrigin(enemy)) < range then
tempList[key] = list[key]
end
end
return GetMEC(spellRadius, tempList)
end
ilib.init()
return ilib
--------------------------------------------------------------------------------