Musti145

Untitled

Oct 6th, 2015
83
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 62.73 KB | None | 0 0
  1. _G.InspiredVersion = 30
  2.  
  3. function Set(list)
  4. local set = {}
  5. for _, l in ipairs(list) do
  6. set[l] = true
  7. end
  8. return set
  9. end
  10.  
  11. function ctype(t)
  12. local _type = type(t)
  13. if _type == "userdata" then
  14. local metatable = getmetatable(t)
  15. if not metatable or not metatable.__index then
  16. t, _type = "userdata", "string"
  17. end
  18. end
  19. if _type == "userdata" or _type == "table" then
  20. local _getType = t.type or t.Type or t.__type
  21. _type = type(_getType)=="function" and _getType(t) or type(_getType)=="string" and _getType or _type
  22. end
  23. return _type
  24. end
  25.  
  26. function ctostring(t)
  27. local _type = type(t)
  28. if _type == "userdata" then
  29. local metatable = getmetatable(t)
  30. if not metatable or not metatable.__index then
  31. t, _type = "userdata", "string"
  32. end
  33. end
  34. if _type == "userdata" or _type == "table" then
  35. local _tostring = t.tostring or t.toString or t.__tostring
  36. if type(_tostring)=="function" then
  37. local tstring = _tostring(t)
  38. t = _tostring(t)
  39. else
  40. local _ctype = ctype(t) or "Unknown"
  41. if _type == "table" then
  42. t = tostring(t):gsub(_type,_ctype) or tostring(t)
  43. else
  44. t = _ctype
  45. end
  46. end
  47. end
  48. return tostring(t)
  49. end
  50.  
  51. function table.clear(t)
  52. for i, v in pairs(t) do
  53. t[i] = nil
  54. end
  55. end
  56.  
  57. function table.copy(from, deepCopy)
  58. if type(from) == "table" then
  59. local to = {}
  60. for k, v in pairs(from) do
  61. if deepCopy and type(v) == "table" then to[k] = table.copy(v)
  62. else to[k] = v
  63. end
  64. end
  65. return to
  66. end
  67. end
  68.  
  69. function table.contains(t, what, member) --member is optional
  70. assert(type(t) == "table", "table.contains: wrong argument types (<table> expected for t)")
  71. for i, v in pairs(t) do
  72. if member and v[member] == what or v == what then return i, v end
  73. end
  74. end
  75.  
  76. function table.serialize(t, tab, functions)
  77. local s, len = {"{\n"}, 1
  78. for i, v in pairs(t) do
  79. local iType, vType = type(i), type(v)
  80. if vType~="userdata" and vType~="function" then
  81. if tab then
  82. s[len+1] = tab
  83. len = len + 1
  84. end
  85. s[len+1] = "\t"
  86. if iType == "number" then
  87. s[len+2], s[len+3], s[len+4] = "[", i, "]"
  88. elseif iType == "string" then
  89. s[len+2], s[len+3], s[len+4] = '["', i, '"]'
  90. end
  91. s[len+5] = " = "
  92. if vType == "number" then
  93. s[len+6], s[len+7], len = v, ",\n", len + 7
  94. elseif vType == "string" then
  95. s[len+6], s[len+7], s[len+8], len = '"', v, '",\n', len + 8
  96. elseif vType == "boolean" then
  97. s[len+6], s[len+7], len = tostring(v), ",\n", len + 7
  98. end
  99. end
  100. end
  101. if tab then
  102. s[len+1] = tab
  103. len = len + 1
  104. end
  105. s[len+1] = "}"
  106. return table.concat(s)
  107. end
  108.  
  109. function table.merge(base, t, deepMerge)
  110. for i, v in pairs(t) do
  111. if deepMerge and type(v) == "table" and type(base[i]) == "table" then
  112. base[i] = table.merge(base[i], v)
  113. else base[i] = v
  114. end
  115. end
  116. return base
  117. end
  118.  
  119. --from http://lua-users.org/wiki/SplitJoin
  120. function string.split(str, delim, maxNb)
  121. -- Eliminate bad cases...
  122. if not delim or delim == "" or string.find(str, delim) == nil then
  123. return { str }
  124. end
  125. maxNb = (maxNb and maxNb >= 1) and maxNb or 0
  126. local result = {}
  127. local pat = "(.-)" .. delim .. "()"
  128. local nb = 0
  129. local lastPos
  130. for part, pos in string.gmatch(str, pat) do
  131. nb = nb + 1
  132. if nb == maxNb then
  133. result[nb] = lastPos and string.sub(str, lastPos, #str) or str
  134. break
  135. end
  136. result[nb] = part
  137. lastPos = pos
  138. end
  139. -- Handle the last field
  140. if nb ~= maxNb then
  141. result[nb + 1] = string.sub(str, lastPos)
  142. end
  143. return result
  144. end
  145.  
  146. function string.join(arg, del)
  147. return table.concat(arg, del)
  148. end
  149.  
  150. function string.trim(s)
  151. return s:match'^%s*(.*%S)' or ''
  152. end
  153.  
  154. function string.unescape(s)
  155. return s:gsub(".",{
  156. ["\a"] = [[\a]],
  157. ["\b"] = [[\b]],
  158. ["\f"] = [[\f]],
  159. ["\n"] = [[\n]],
  160. ["\r"] = [[\r]],
  161. ["\t"] = [[\t]],
  162. ["\v"] = [[\v]],
  163. ["\\"] = [[\\]],
  164. ['"'] = [[\"]],
  165. ["'"] = [[\']],
  166. ["["] = "\\[",
  167. ["]"] = "\\]",
  168. })
  169. end
  170.  
  171. function math.isNaN(num)
  172. return num ~= num
  173. end
  174.  
  175. -- Round half away from zero
  176. function math.round(num, idp)
  177. assert(type(num) == "number", "math.round: wrong argument types (<number> expected for num)")
  178. assert(type(idp) == "number" or idp == nil, "math.round: wrong argument types (<integer> expected for idp)")
  179. local mult = 10 ^ (idp or 0)
  180. if num >= 0 then return math.floor(num * mult + 0.5) / mult
  181. else return math.ceil(num * mult - 0.5) / mult
  182. end
  183. end
  184.  
  185. function math.close(a, b, eps)
  186. assert(type(a) == "number" and type(b) == "number", "math.close: wrong argument types (at least 2 <number> expected)")
  187. eps = eps or 1e-9
  188. return math.abs(a - b) <= eps
  189. end
  190.  
  191. function math.limit(val, min, max)
  192. assert(type(val) == "number" and type(min) == "number" and type(max) == "number", "math.limit: wrong argument types (3 <number> expected)")
  193. return math.min(max, math.max(min, val))
  194. end
  195.  
  196. function print(...)
  197. local t, len = {}, select("#",...)
  198. for i=1, len do
  199. local v = select(i,...)
  200. local _type = type(v)
  201. if _type == "string" then t[i] = v
  202. elseif _type == "number" then t[i] = tostring(v)
  203. elseif _type == "table" then t[i] = table.serialize(v)
  204. elseif _type == "boolean" then t[i] = v and "true" or "false"
  205. elseif _type == "userdata" then t[i] = ctostring(v)
  206. else t[i] = _type
  207. end
  208. end
  209. if len>0 then PrintChat(table.concat(t)) end
  210. end
  211.  
  212. function Msg(msg, title)
  213. if not msg then return end
  214. PrintChat("<font color=\"#00FFFF\">["..(title or "GoS-Library").."]:</font> <font color=\"#FFFFFF\">"..tostring(msg).."</font>")
  215. end
  216.  
  217. local toPrint, toPrintCol = {}, {}
  218. function Print(str, time, col)
  219. local b = 0
  220. for _, k in pairs(toPrint) do
  221. b = _
  222. end
  223. local index = b + 1
  224. toPrint[index] = str
  225. toPrintCol[index] = col or 0xffffffff
  226. GoS:DelayAction(function() toPrint[index] = nil toPrintCol[index] = nil end, time or 2000)
  227. end
  228.  
  229. function Value()
  230. if self.__type == "key" and not self.__isToggle then
  231. return self.Value()
  232. end
  233. return self.__val
  234. end
  235.  
  236. local _SC = { menuKey = 16, width = 200, menuIndex = -1, instances = {}, keySwitch = nil, listSwitch = nil, sliderSwitch = nil, lastSwitch = 0 }
  237. local _SCP = {x = 15, y = -5}
  238.  
  239. function __Menu__Draw()
  240. if KeyIsDown(_SC.menuKey) or _SC.keySwitch or _SC.listSwitch or _SC.sliderSwitch or GoS.Menu.s.Value() then
  241. __Menu__Browse()
  242. __Menu__WndTick()
  243. FillRect(_SCP.x-2,_SCP.y+18,_SC.width+4,4+20*#_SC.instances,ARGB(55, 255, 255, 255))
  244. for _=1, #_SC.instances do
  245. local instance = _SC.instances[_]
  246. FillRect(_SCP.x,_SCP.y+20*_,_SC.width,20,ARGB(255, 0, 0, 0))
  247. DrawText(" "..instance.__name.." ",15,_SCP.x,_SCP.y+1+20*_,0xffffffff)
  248. DrawText(">",15,_SCP.x+_SC.width-15,_SCP.y+1+20*_,0xffffffff)
  249. end
  250. for _=1, #_SC.instances do
  251. local instance = _SC.instances[_]
  252. if instance.__active then
  253. if #instance.__subMenus > 0 then
  254. for i=1, #instance.__subMenus do
  255. local sub = instance.__subMenus[i]
  256. __Menu_DrawSubMenu(sub, i+_-1, 1)
  257. end
  258. end
  259. if #instance.__params > 0 then
  260. for j=1, #instance.__params do
  261. __Menu_DrawParam(instance.__params[j], 1, j+#instance.__subMenus+_-1)
  262. end
  263. end
  264. end
  265. end
  266. if _SC.keySwitch then
  267. for i=17, 128 do
  268. if KeyIsDown(i) then
  269. _SC.keySwitch.__key = i
  270. _SC.keySwitch = nil
  271. end
  272. end
  273. end
  274. if _SC.listSwitch then
  275. __Menu__DrawListSwitch(_SC.listSwitch, _SC.listSwitch.x, _SC.listSwitch.y)
  276. end
  277. if _SC.sliderSwitch then
  278. __Menu__DrawSliderSwitch(_SC.sliderSwitch, _SC.sliderSwitch.x, _SC.sliderSwitch.y)
  279. end
  280. end
  281. end
  282.  
  283. function __Menu_DrawSubMenu(instance, _, num)
  284. FillRect(_SCP.x-2+(_SC.width+5)*num,_SCP.y-2+20*_,_SC.width+4,4+20,ARGB(55, 255, 255, 255))
  285. FillRect(_SCP.x+(_SC.width+5)*num,_SCP.y+20*_,_SC.width,20,ARGB(255, 0, 0, 0))
  286. DrawText(" "..instance.__name.." ",15,_SCP.x+num*(_SC.width+5),_SCP.y+1+20*_,0xffffffff)
  287. DrawText(">",15,_SCP.x+_SC.width-15+_SC.width*num,_SCP.y+1+20*_,0xffffffff)
  288. if #instance.__subMenus > 0 and instance.__active then
  289. for i=1, #instance.__subMenus do
  290. local sub = instance.__subMenus[i]
  291. __Menu_DrawSubMenu(sub, i+_-1, num+1)
  292. end
  293. end
  294. if #instance.__params > 0 then
  295. for j=1, #instance.__params do
  296. __Menu_DrawParam(instance.__params[j], num+1, _-1+j+#instance.__subMenus)
  297. end
  298. end
  299. end
  300.  
  301. function __Menu_DrawParam(param, xoff, yoff)
  302. if param.__head.__active then
  303. FillRect(_SCP.x-2+(_SC.width+5)*xoff,_SCP.y-2+20*yoff,_SC.width+4,4+20,ARGB(55, 255, 255, 255))
  304. FillRect(_SCP.x+(_SC.width+5)*xoff,_SCP.y+20*yoff,_SC.width,20,ARGB(255, 0, 0, 0))
  305. if param.__type == "boolean" then
  306. DrawText(" "..param.__name.." ",15,_SCP.x+(_SC.width+5)*xoff,_SCP.y+1+20*yoff,0xffffffff)
  307. FillRect(_SCP.x+_SC.width-20+(_SC.width+5)*xoff,_SCP.y+20*yoff+2,15,15, param.__val and GoS.Green or GoS.Red)
  308. elseif param.__type == "key" then
  309. DrawText(" "..param.__name.." ",15,_SCP.x+(_SC.width+5)*xoff,_SCP.y+1+20*yoff,0xffffffff)
  310. FillRect(_SCP.x+_SC.width-21+(_SC.width+5)*xoff,_SCP.y+20*yoff+2,17,15, param.Value() and ARGB(150,0,255,0) or ARGB(150,255,0,0))
  311. DrawText("["..(param.__key == 32 and " " or string.char(param.__key)).."]",15,_SCP.x+_SC.width-22+(_SC.width+5)*xoff,_SCP.y+20*yoff+1,0xffffffff)
  312. elseif param.__type == "slider" then
  313. DrawText(" "..param.__name.." ",15,_SCP.x+(_SC.width+5)*xoff,_SCP.y+1+20*yoff,0xffffffff)
  314. DrawText("<|>",15,_SCP.x+_SC.width-25+(_SC.width+5)*xoff,_SCP.y+1+20*yoff,0xffffffff)
  315. elseif param.__type == "list" then
  316. DrawText(" "..param.__name.." ",15,_SCP.x+(_SC.width+5)*xoff,_SCP.y+1+20*yoff,0xffffffff)
  317. DrawText("v",15,_SCP.x+_SC.width-10+(_SC.width+5)*xoff,_SCP.y+1+20*yoff,0xffffffff)
  318. elseif param.__type == "info" then
  319. DrawText(" "..param.__name.." ",15,_SCP.x+(_SC.width+5)*xoff,_SCP.y+1+20*yoff,0xffffffff)
  320. end
  321. end
  322. end
  323.  
  324. function __Menu__DrawListSwitch(param, x, y)
  325. FillRect(x-2, y-2, _SC.width+4, 20*#param.__list+4, ARGB(55, 255, 255, 255))
  326. FillRect(x, y, _SC.width, 20*#param.__list,ARGB(255, 0, 0, 0))
  327. for i = 1, #param.__list do
  328. local entry = param.__list[i]
  329. if param.__val == i then
  330. DrawText("->",15,x+5,20*(i-1)+y,0xffffffff)
  331. end
  332. DrawText(tostring(entry),15,x+35,20*(i-1)+y,0xffffffff)
  333. end
  334. end
  335.  
  336. function __Menu__DrawSliderSwitch(param, x, y)
  337. FillRect(x-2, y-2, _SC.width+4, 44, ARGB(55, 255, 255, 255))
  338. FillRect(x, y, _SC.width, 40,ARGB(255, 0, 0, 0))
  339. DrawText("Value: "..math.ceil(math.floor(param.__val*param.__inc*1000)/param.__inc)/1000,15,x+5,y,0xffffffff)
  340. DrawText("[X]",15,x+_SC.width-20,y,0xffffffff)
  341. DrawText(tostring(""..param.__min),15,x+5,y+20,0xffffffff)
  342. DrawText(tostring(""..param.__max),15,x+_SC.width-25,y+20,0xffffffff)
  343. FillRect(x+15,y+20, _SC.width-45, 18, ARGB(55, 255, 255, 255))
  344. local off = (_SC.width-45) / math.abs(param.__min-param.__max) / param.__inc
  345. local v = x+15+(param.__val-param.__min)*off
  346. if param.__max == 0 then
  347. v = x+15+param.__val*off+math.abs(param.__min-param.__max)*off
  348. elseif param.__min < 0 then
  349. v = x+15+param.__val*off+math.abs(param.__min-param.__max)/2*off
  350. end
  351. FillRect(v, y+20, 5, 18, GoS.Blue)
  352. end
  353.  
  354. function __Menu__Browse()
  355. if _SC.listSwitch or _SC.sliderSwitch then return end
  356. local mmPos = GetCursorPos()
  357. for _=1, #_SC.instances do
  358. local instance = _SC.instances[_]
  359. local x = _SCP.x
  360. local y = _SCP.y+20*_
  361. local width = _SC.width
  362. local heigth = 20
  363. if mmPos.x >= x and mmPos.x <= x+_SC.width and mmPos.y >= y and mmPos.y <= y+heigth then
  364. __Menu__ResetActive()
  365. _SC.instances[_].__active = true
  366. return;
  367. end
  368. if #instance.__subMenus > 0 and instance.__active then
  369. for i=1, #instance.__subMenus do
  370. local sub = instance.__subMenus[i]
  371. __Menu__BrowseSubMenu(sub, i+_-1, 1)
  372. end
  373. end
  374. end
  375. end
  376.  
  377. function __Menu__BrowseSubMenu(instance, _, num)
  378. local mmPos = GetCursorPos()
  379. local x = _SCP.x+(_SC.width+5)*num
  380. local y = _SCP.y+20*_
  381. local width = _SC.width
  382. local heigth = 20
  383. if mmPos.x >= x and mmPos.x <= x+width and mmPos.y >= y and mmPos.y <= y+heigth then
  384. if instance.__head then
  385. for j=1, #instance.__head.__subMenus do
  386. local ins = instance.__head.__subMenus[j]
  387. __Menu__ResetSubMenu(ins)
  388. ins.__active = false
  389. end
  390. end
  391. instance.__active = true
  392. return;
  393. end
  394. if #instance.__subMenus > 0 and instance.__active then
  395. for i=1, #instance.__subMenus do
  396. local sub = instance.__subMenus[i]
  397. __Menu__BrowseSubMenu(sub, i+_-1, num+1)
  398. end
  399. end
  400. end
  401.  
  402. function __Menu__ResetActive()
  403. for _=1, #_SC.instances do
  404. _SC.instances[_].__active = false
  405. for i=1, #_SC.instances[_].__subMenus do
  406. __Menu__ResetSubMenu(_SC.instances[_].__subMenus[i])
  407. end
  408. end
  409. end
  410.  
  411. function __Menu__ResetSubMenu(sub)
  412. sub.__active = false
  413. if #sub.__subMenus > 0 then
  414. for i=1, #sub.__subMenus do
  415. __Menu__ResetSubMenu(sub.__subMenus[i])
  416. end
  417. end
  418. end
  419.  
  420. function __Menu__WndTick()
  421. local mmPos = GetCursorPos()
  422. if not KeyIsDown(1) then return end
  423. if _SC.listSwitch then
  424. local x = _SC.listSwitch.x
  425. local y = _SC.listSwitch.y
  426. if mmPos.x >= x and mmPos.x <= x+_SC.width then
  427. for i=1, #_SC.listSwitch.__list do
  428. if mmPos.y >= y-20+i*20 and mmPos.y <= y+i*20 then
  429. _SC.listSwitch.__val = i
  430. GoS:DelayAction(function() _SC.listSwitch = nil end, 125)
  431. _SC.lastSwitch = GetTickCount() + 125
  432. end
  433. end
  434. end
  435. elseif _SC.sliderSwitch then
  436. local x = _SC.sliderSwitch.x
  437. local y = _SC.sliderSwitch.y
  438. if mmPos.x >= x and mmPos.x <= x+_SC.width and mmPos.y >= y+20 and mmPos.y <= y+40 then
  439. if mmPos.x <= x+15 then
  440. _SC.sliderSwitch.__val = _SC.sliderSwitch.__min
  441. elseif mmPos.x >= x+_SC.width-30 then
  442. _SC.sliderSwitch.__val = _SC.sliderSwitch.__max
  443. else
  444. local off = (_SC.width-45) / math.abs(_SC.sliderSwitch.__min-_SC.sliderSwitch.__max) / _SC.sliderSwitch.__inc
  445. local v = (mmPos.x - x - 15) / off
  446. _SC.sliderSwitch.__val = math.floor(v+_SC.sliderSwitch.__min) * _SC.sliderSwitch.__inc
  447. end
  448. end
  449. if mmPos.x >= x+_SC.width-20 and mmPos.x <= x+_SC.width and mmPos.y >= y-5 and mmPos.y <= y+15 then
  450. GoS:DelayAction(function() _SC.sliderSwitch = nil end, 125)
  451. _SC.lastSwitch = GetTickCount() + 125
  452. end
  453. end
  454. end
  455.  
  456. function __Menu__WndMsg()
  457. local mmPos = GetCursorPos()
  458. if not _SC.listSwitch and not _SC.sliderSwitch then
  459. if mmPos.x >= 15 and mmPos.x <= 15+_SC.width and mmPos.y >= 15 and mmPos.y <= 15+20*#_SC.instances then
  460. return;
  461. end
  462. for _=1, #_SC.instances do
  463. if _SC.instances[_].__active then
  464. local yoff = #_SC.instances[_].__subMenus
  465. for i=1, yoff do
  466. local sub = _SC.instances[_].__subMenus[i]
  467. if sub.__active and __Menu__SubMenuWndMsg(sub, i+_-1, 1) then
  468. return;
  469. end
  470. end
  471. for i=1, #_SC.instances[_].__params do
  472. local x = _SCP.x+_SC.width+5
  473. local y = _SCP.y+20*(yoff+i+_-1)
  474. local heigth = 20
  475. if mmPos.x >= x and mmPos.x <= x+_SC.width and mmPos.y >= y and mmPos.y <= y+heigth then
  476. __Menu__SwitchParam(_SC.instances[_].__params[i], x, y)
  477. return;
  478. end
  479. end
  480. end
  481. end
  482. __Menu__ResetActive()
  483. end
  484. end
  485.  
  486. function __Menu__SubMenuWndMsg(instance, _, num)
  487. local mmPos = GetCursorPos()
  488. local yoff = #instance.__subMenus
  489. local xpos = _SCP.x+(_SC.width+5)*num+_SC.width+5
  490. local ypos = _SCP.y+_*20
  491. for i=1, #instance.__params do
  492. local x = xpos
  493. local y = ypos+(yoff+i-1)*20
  494. local heigth = 20
  495. if mmPos.x >= x and mmPos.x <= x+_SC.width and mmPos.y >= y and mmPos.y <= y+heigth then
  496. __Menu__SwitchParam(instance.__params[i], x, y)
  497. return true
  498. end
  499. end
  500. for i=1, #instance.__subMenus do
  501. local sub = instance.__subMenus[i]
  502. if sub.__active and __Menu__SubMenuWndMsg(sub, i+_-1, num+1) then
  503. return true
  504. end
  505. end
  506. end
  507.  
  508. function __Menu__SwitchParam(param, x, y)
  509. if param.__type == "boolean" then
  510. param.__val = not param.__val
  511. elseif param.__type == "key" then
  512. _SC.keySwitch = param
  513. elseif param.__type == "slider" then
  514. _SC.sliderSwitch = param
  515. _SC.sliderSwitch.x = x+_SC.width+5
  516. _SC.sliderSwitch.y = y
  517. elseif param.__type == "list" then
  518. _SC.listSwitch = param
  519. _SC.listSwitch.x = x+_SC.width+5
  520. _SC.listSwitch.y = y
  521. end
  522. end
  523.  
  524. class "Menu"
  525.  
  526. function Menu:__init(name, id, head)
  527. self.__name = name
  528. self.__id = id
  529. self.__subMenus = {}
  530. self.__params = {}
  531. self.__active = false
  532. self.__head = head
  533. if not head then
  534. table.insert(_SC.instances, self)
  535. end
  536. return self
  537. end
  538.  
  539. function Menu:SubMenu(id, name)
  540. local id2 = #self.__subMenus+1
  541. self.__subMenus[id2] = Menu(name, id, self)
  542. self[id] = self.__subMenus[id2]
  543. end
  544.  
  545. function Menu:Boolean(id, name, val)
  546. local id2 = #self.__params+1
  547. self.__params[id2] = {__id = id, __name = name, __type = "boolean", __val = val, __head = self, __lastSwitch = 0, Value = function() return self.__params[id2].__val end}
  548. self[id] = self.__params[id2]
  549. end
  550.  
  551. function Menu:Key(id, name, key, isToggle)
  552. local id2 = #self.__params+1
  553. if isToggle then
  554. OnLoop(function()
  555. if self.__params[id2].__lastSwitch < GetTickCount() and KeyIsDown(self.__params[id2].__key) then
  556. self.__params[id2].__lastSwitch = GetTickCount() + 125
  557. self.__params[id2].__val = not self.__params[id2].__val
  558. end
  559. end)
  560. self.__params[id2] = {__id = id, __name = name, __type = "key", __key = key, __isToggle = isToggle, __head = self, __lastSwitch = 0, Value = function() return self.__params[id2].__val end}
  561. else
  562. self.__params[id2] = {__id = id, __name = name, __type = "key", __key = key, __isToggle = isToggle, __head = self, Value = function() return KeyIsDown(self.__params[id2].__key) end}
  563. end
  564. self[id] = self.__params[id2]
  565. end
  566.  
  567. function Menu:Slider(id, name, starVal, minVal, maxVal, incrVal)
  568. local id2 = #self.__params+1
  569. self.__params[id2] = {__id = id, __name = name, __type = "slider", __head = self, __val = starVal, __min = minVal, __max = maxVal, __inc = incrVal, Value = function() return self.__params[id2].__val end}
  570. self[id] = self.__params[id2]
  571. end
  572.  
  573. function Menu:List(id, name, starVal, list)
  574. local id2 = #self.__params+1
  575. self.__params[id2] = {__id = id, __name = name, __type = "list", __head = self, __val = starVal, __list = list, Value = function() return self.__params[id2].__val end}
  576. self[id] = self.__params[id2]
  577. end
  578.  
  579. function Menu:Info(id, name)
  580. local id2 = #self.__params+1
  581. self.__params[id2] = {__id = id, __name = name, __type = "info", __head = self}
  582. self[id] = self.__params[id2]
  583. end
  584.  
  585. class "goslib"
  586.  
  587. function goslib:__init()
  588. self:SetupVars()
  589. self:SetupMenu()
  590. self:SetupLocalCallbacks()
  591. self:MakeObjectManager()
  592. end
  593.  
  594. function goslib:SetupMenu()
  595. self.Menu = Menu("GoS-Library", "gos")
  596. self.Menu:Boolean("s", "Show always", false)
  597. self.Menu:List("w", "Menu width", 2, {150, 200, 250, 300})
  598. self.Menu:List("l", "Language", 1, {"English", })
  599. OnLoop(function()
  600. __Menu__Draw()
  601. _SC.width = self.Menu.w:Value() * 50 + 100
  602. end)
  603. OnWndMsg(function(m,p)
  604. if (KeyIsDown(_SC.menuKey) or _SC.keySwitch or _SC.listSwitch or _SC.sliderSwitch or GoS.Menu.s.Value()) and m == WM_LBUTTONDOWN then
  605. __Menu__WndMsg()
  606. end
  607. end)
  608. end
  609.  
  610. function goslib:GetTextArea(str, size)
  611. local width = 0
  612. for i=1, str:len() do
  613. width = width + (self:IsUppercase(str:sub(i,i)) and 2 or 1)
  614. end
  615. return width * size * 0.2
  616. end
  617.  
  618. function goslib:IsUppercase(char)
  619. return char:lower() ~= char
  620. end
  621.  
  622. function goslib:SetupVars()
  623. _G.myHero = GetMyHero()
  624. _G.myHeroName = GetObjectName(myHero)
  625. _G.DAMAGE_MAGIC, _G.DAMAGE_PHYSICAL, _G.DAMAGE_MIXED = 1, 2, 3
  626. _G.MINION_ALLY, _G.MINION_ENEMY, _G.MINION_JUNGLE = GetTeam(myHero), 300-GetTeam(myHero), 300
  627. local summonerNameOne = GetCastName(myHero,SUMMONER_1)
  628. local summonerNameTwo = GetCastName(myHero,SUMMONER_2)
  629. mixed = Set {"Akali","Corki","Ekko","Evelynn","Ezreal","Kayle","Kennen","KogMaw","Malzahar","MissFortune","Mordekaiser","Pantheon","Poppy","Shaco","Skarner","Teemo","Tristana","TwistedFate","XinZhao","Yoric"}
  630. ad = Set {"Aatrox","Corki","Darius","Draven","Ezreal","Fiora","Gangplank","Garen","Gnar","Graves","Hecarim","Irelia","JarvanIV","Jax","Jayce","Jinx","Kalista","KhaZix","KogMaw","LeeSin","Lucian","MasterYi","MissFortune","Nasus","Nocturne","Olaf","Pantheon","Quinn","RekSai","Renekton","Rengar","Riven","Shaco","Shyvana","Sion","Sivir","Talon","Tristana","Trundle","Tryndamere","Twitch","Udyr","Urgot","Varus","Vayne","Vi","Warwick","Wukong","XinZhao","Yasuo","Yoric","Zed"}
  631. ap = Set {"Ahri","Akali","Alistar","Amumu","Anivia","Annie","Azir","Bard","Blitzcrank","Brand","Braum","Cassiopea","ChoGath","Diana","DrMundo","Ekko","Elise","Evelynn","Fiddlesticks","Fizz","Galio","Gragas","Heimerdinger","Janna","Karma","Karthus","Kassadin","Katarina","Kayle","Kennen","LeBlanc","Leona","Lissandra","Lulu","Lux","Malphite","Malzahar","Maokai","Mordekaiser","Morgana","Nami","Nautilus","Nidalee","Nunu","Orianna","Poppy","Rammus","Rumble","Ryze","Sejuani","Shen","Singed","Skarner","Sona","Soraka","Swain","Syndra","TahmKench","Taric","Teemo","Thresh","TwistedFate","Veigar","VelKoz","Viktor","Vladimir","Volibear","Xerath","Zac","Ziggz","Zilean","Zyra"}
  632. _G.Ignite = (summonerNameOne:lower():find("summonerdot") and SUMMONER_1 or (summonerNameTwo:lower():find("summonerdot") and SUMMONER_2 or nil))
  633. _G.Smite = (summonerNameOne:lower():find("summonersmite") and SUMMONER_1 or (summonerNameTwo:lower():find("summonersmite") and SUMMONER_2 or nil))
  634. _G.Exhaust = (summonerNameOne:lower():find("summonerexhaust") and SUMMONER_1 or (summonerNameTwo:lower():find("summonerexhaust") and SUMMONER_2 or nil))
  635. self.projectilespeeds = {["Velkoz"]= 2000,["TeemoMushroom"] = math.huge,["TestCubeRender"] = math.huge ,["Xerath"] = 2000.0000 ,["Kassadin"] = math.huge ,["Rengar"] = math.huge ,["Thresh"] = 1000.0000 ,["Ziggs"] = 1500.0000 ,["ZyraPassive"] = 1500.0000 ,["ZyraThornPlant"] = 1500.0000 ,["KogMaw"] = 1800.0000 ,["HeimerTBlue"] = 1599.3999 ,["EliseSpider"] = 500.0000 ,["Skarner"] = 500.0000 ,["ChaosNexus"] = 500.0000 ,["Katarina"] = 467.0000 ,["Riven"] = 347.79999 ,["SightWard"] = 347.79999 ,["HeimerTYellow"] = 1599.3999 ,["Ashe"] = 2000.0000 ,["VisionWard"] = 2000.0000 ,["TT_NGolem2"] = math.huge ,["ThreshLantern"] = math.huge ,["TT_Spiderboss"] = math.huge ,["OrderNexus"] = math.huge ,["Soraka"] = 1000.0000 ,["Jinx"] = 2750.0000 ,["TestCubeRenderwCollision"] = 2750.0000 ,["Red_Minion_Wizard"] = 650.0000 ,["JarvanIV"] = 20.0000 ,["Blue_Minion_Wizard"] = 650.0000 ,["TT_ChaosTurret2"] = 1200.0000 ,["TT_ChaosTurret3"] = 1200.0000 ,["TT_ChaosTurret1"] = 1200.0000 ,["ChaosTurretGiant"] = 1200.0000 ,["Dragon"] = 1200.0000 ,["LuluSnowman"] = 1200.0000 ,["Worm"] = 1200.0000 ,["ChaosTurretWorm"] = 1200.0000 ,["TT_ChaosInhibitor"] = 1200.0000 ,["ChaosTurretNormal"] = 1200.0000 ,["AncientGolem"] = 500.0000 ,["ZyraGraspingPlant"] = 500.0000 ,["HA_AP_OrderTurret3"] = 1200.0000 ,["HA_AP_OrderTurret2"] = 1200.0000 ,["Tryndamere"] = 347.79999 ,["OrderTurretNormal2"] = 1200.0000 ,["Singed"] = 700.0000 ,["OrderInhibitor"] = 700.0000 ,["Diana"] = 347.79999 ,["HA_FB_HealthRelic"] = 347.79999 ,["TT_OrderInhibitor"] = 347.79999 ,["GreatWraith"] = 750.0000 ,["Yasuo"] = 347.79999 ,["OrderTurretDragon"] = 1200.0000 ,["OrderTurretNormal"] = 1200.0000 ,["LizardElder"] = 500.0000 ,["HA_AP_ChaosTurret"] = 1200.0000 ,["Ahri"] = 1750.0000 ,["Lulu"] = 1450.0000 ,["ChaosInhibitor"] = 1450.0000 ,["HA_AP_ChaosTurret3"] = 1200.0000 ,["HA_AP_ChaosTurret2"] = 1200.0000 ,["ChaosTurretWorm2"] = 1200.0000 ,["TT_OrderTurret1"] = 1200.0000 ,["TT_OrderTurret2"] = 1200.0000 ,["TT_OrderTurret3"] = 1200.0000 ,["LuluFaerie"] = 1200.0000 ,["HA_AP_OrderTurret"] = 1200.0000 ,["OrderTurretAngel"] = 1200.0000 ,["YellowTrinketUpgrade"] = 1200.0000 ,["MasterYi"] = math.huge ,["Lissandra"] = 2000.0000 ,["ARAMOrderTurretNexus"] = 1200.0000 ,["Draven"] = 1700.0000 ,["FiddleSticks"] = 1750.0000 ,["SmallGolem"] = math.huge ,["ARAMOrderTurretFront"] = 1200.0000 ,["ChaosTurretTutorial"] = 1200.0000 ,["NasusUlt"] = 1200.0000 ,["Maokai"] = math.huge ,["Wraith"] = 750.0000 ,["Wolf"] = math.huge ,["Sivir"] = 1750.0000 ,["Corki"] = 2000.0000 ,["Janna"] = 1200.0000 ,["Nasus"] = math.huge ,["Golem"] = math.huge ,["ARAMChaosTurretFront"] = 1200.0000 ,["ARAMOrderTurretInhib"] = 1200.0000 ,["LeeSin"] = math.huge ,["HA_AP_ChaosTurretTutorial"] = 1200.0000 ,["GiantWolf"] = math.huge ,["HA_AP_OrderTurretTutorial"] = 1200.0000 ,["YoungLizard"] = 750.0000 ,["Jax"] = 400.0000 ,["LesserWraith"] = math.huge ,["Blitzcrank"] = math.huge ,["ARAMChaosTurretInhib"] = 1200.0000 ,["Shen"] = 400.0000 ,["Nocturne"] = math.huge ,["Sona"] = 1500.0000 ,["ARAMChaosTurretNexus"] = 1200.0000 ,["YellowTrinket"] = 1200.0000 ,["OrderTurretTutorial"] = 1200.0000 ,["Caitlyn"] = 2500.0000 ,["Trundle"] = 347.79999 ,["Malphite"] = 1000.0000 ,["Mordekaiser"] = math.huge ,["ZyraSeed"] = math.huge ,["Vi"] = 1000.0000 ,["Tutorial_Red_Minion_Wizard"] = 650.0000 ,["Renekton"] = math.huge ,["Anivia"] = 1400.0000 ,["Fizz"] = math.huge ,["Heimerdinger"] = 1500.0000 ,["Evelynn"] = 467.0000 ,["Rumble"] = 347.79999 ,["Leblanc"] = 1700.0000 ,["Darius"] = math.huge ,["OlafAxe"] = math.huge ,["Viktor"] = 2300.0000 ,["XinZhao"] = 20.0000 ,["Orianna"] = 1450.0000 ,["Vladimir"] = 1400.0000 ,["Nidalee"] = 1750.0000 ,["Tutorial_Red_Minion_Basic"] = math.huge ,["ZedShadow"] = 467.0000 ,["Syndra"] = 1800.0000 ,["Zac"] = 1000.0000 ,["Olaf"] = 347.79999 ,["Veigar"] = 1100.0000 ,["Twitch"] = 2500.0000 ,["Alistar"] = math.huge ,["Akali"] = 467.0000 ,["Urgot"] = 1300.0000 ,["Leona"] = 347.79999 ,["Talon"] = math.huge ,["Karma"] = 1500.0000 ,["Jayce"] = 347.79999 ,["Galio"] = 1000.0000 ,["Shaco"] = math.huge ,["Taric"] = math.huge ,["TwistedFate"] = 1500.0000 ,["Varus"] = 2000.0000 ,["Garen"] = 347.79999 ,["Swain"] = 1600.0000 ,["Vayne"] = 2000.0000 ,["Fiora"] = 467.0000 ,["Quinn"] = 2000.0000 ,["Kayle"] = math.huge ,["Blue_Minion_Basic"] = math.huge ,["Brand"] = 2000.0000 ,["Teemo"] = 1300.0000 ,["Amumu"] = 500.0000 ,["Annie"] = 1200.0000 ,["Odin_Blue_Minion_caster"] = 1200.0000 ,["Elise"] = 1600.0000 ,["Nami"] = 1500.0000 ,["Poppy"] = 500.0000 ,["AniviaEgg"] = 500.0000 ,["Tristana"] = 2250.0000 ,["Graves"] = 3000.0000 ,["Morgana"] = 1600.0000 ,["Gragas"] = math.huge ,["MissFortune"] = 2000.0000 ,["Warwick"] = math.huge ,["Cassiopeia"] = 1200.0000 ,["Tutorial_Blue_Minion_Wizard"] = 650.0000 ,["DrMundo"] = math.huge ,["Volibear"] = 467.0000 ,["Irelia"] = 467.0000 ,["Odin_Red_Minion_Caster"] = 650.0000 ,["Lucian"] = 2800.0000 ,["Yorick"] = math.huge ,["RammusPB"] = math.huge ,["Red_Minion_Basic"] = math.huge ,["Udyr"] = 467.0000 ,["MonkeyKing"] = 20.0000 ,["Tutorial_Blue_Minion_Basic"] = math.huge ,["Kennen"] = 1600.0000 ,["Nunu"] = 500.0000 ,["Ryze"] = 2400.0000 ,["Zed"] = 467.0000 ,["Nautilus"] = 1000.0000 ,["Gangplank"] = 1000.0000 ,["Lux"] = 1600.0000 ,["Sejuani"] = 500.0000 ,["Ezreal"] = 2000.0000 ,["OdinNeutralGuardian"] = 1800.0000 ,["Khazix"] = 500.0000 ,["Sion"] = math.huge ,["Aatrox"] = 347.79999 ,["Hecarim"] = 500.0000 ,["Pantheon"] = 20.0000 ,["Shyvana"] = 467.0000 ,["Zyra"] = 1700.0000 ,["Karthus"] = 1200.0000 ,["Rammus"] = math.huge ,["Zilean"] = 1200.0000 ,["Chogath"] = 500.0000 ,["Malzahar"] = 2000.0000 ,["YorickRavenousGhoul"] = 347.79999 ,["YorickSpectralGhoul"] = 347.79999 ,["JinxMine"] = 347.79999 ,["YorickDecayedGhoul"] = 347.79999 ,["XerathArcaneBarrageLauncher"] = 347.79999 ,["Odin_SOG_Order_Crystal"] = 347.79999 ,["TestCube"] = 347.79999 ,["ShyvanaDragon"] = math.huge ,["FizzBait"] = math.huge ,["Blue_Minion_MechMelee"] = math.huge ,["OdinQuestBuff"] = math.huge ,["TT_Buffplat_L"] = math.huge ,["TT_Buffplat_R"] = math.huge ,["KogMawDead"] = math.huge ,["TempMovableChar"] = math.huge ,["Lizard"] = 500.0000 ,["GolemOdin"] = math.huge ,["OdinOpeningBarrier"] = math.huge ,["TT_ChaosTurret4"] = 500.0000 ,["TT_Flytrap_A"] = 500.0000 ,["TT_NWolf"] = math.huge ,["OdinShieldRelic"] = math.huge ,["LuluSquill"] = math.huge ,["redDragon"] = math.huge ,["MonkeyKingClone"] = math.huge ,["Odin_skeleton"] = math.huge ,["OdinChaosTurretShrine"] = 500.0000 ,["Cassiopeia_Death"] = 500.0000 ,["OdinCenterRelic"] = 500.0000 ,["OdinRedSuperminion"] = math.huge ,["JarvanIVWall"] = math.huge ,["ARAMOrderNexus"] = math.huge ,["Red_Minion_MechCannon"] = 1200.0000 ,["OdinBlueSuperminion"] = math.huge ,["SyndraOrbs"] = math.huge ,["LuluKitty"] = math.huge ,["SwainNoBird"] = math.huge ,["LuluLadybug"] = math.huge ,["CaitlynTrap"] = math.huge ,["TT_Shroom_A"] = math.huge ,["ARAMChaosTurretShrine"] = 500.0000 ,["Odin_Windmill_Propellers"] = 500.0000 ,["TT_NWolf2"] = math.huge ,["OdinMinionGraveyardPortal"] = math.huge ,["SwainBeam"] = math.huge ,["Summoner_Rider_Order"] = math.huge ,["TT_Relic"] = math.huge ,["odin_lifts_crystal"] = math.huge ,["OdinOrderTurretShrine"] = 500.0000 ,["SpellBook1"] = 500.0000 ,["Blue_Minion_MechCannon"] = 1200.0000 ,["TT_ChaosInhibitor_D"] = 1200.0000 ,["Odin_SoG_Chaos"] = 1200.0000 ,["TrundleWall"] = 1200.0000 ,["HA_AP_HealthRelic"] = 1200.0000 ,["OrderTurretShrine"] = 500.0000 ,["OriannaBall"] = 500.0000 ,["ChaosTurretShrine"] = 500.0000 ,["LuluCupcake"] = 500.0000 ,["HA_AP_ChaosTurretShrine"] = 500.0000 ,["TT_NWraith2"] = 750.0000 ,["TT_Tree_A"] = 750.0000 ,["SummonerBeacon"] = 750.0000 ,["Odin_Drill"] = 750.0000 ,["TT_NGolem"] = math.huge ,["AramSpeedShrine"] = math.huge ,["OriannaNoBall"] = math.huge ,["Odin_Minecart"] = math.huge ,["Summoner_Rider_Chaos"] = math.huge ,["OdinSpeedShrine"] = math.huge ,["TT_SpeedShrine"] = math.huge ,["odin_lifts_buckets"] = math.huge ,["OdinRockSaw"] = math.huge ,["OdinMinionSpawnPortal"] = math.huge ,["SyndraSphere"] = math.huge ,["Red_Minion_MechMelee"] = math.huge ,["SwainRaven"] = math.huge ,["crystal_platform"] = math.huge ,["MaokaiSproutling"] = math.huge ,["Urf"] = math.huge ,["TestCubeRender10Vision"] = math.huge ,["MalzaharVoidling"] = 500.0000 ,["GhostWard"] = 500.0000 ,["MonkeyKingFlying"] = 500.0000 ,["LuluPig"] = 500.0000 ,["AniviaIceBlock"] = 500.0000 ,["TT_OrderInhibitor_D"] = 500.0000 ,["Odin_SoG_Order"] = 500.0000 ,["RammusDBC"] = 500.0000 ,["FizzShark"] = 500.0000 ,["LuluDragon"] = 500.0000 ,["OdinTestCubeRender"] = 500.0000 ,["TT_Tree1"] = 500.0000 ,["ARAMOrderTurretShrine"] = 500.0000 ,["Odin_Windmill_Gears"] = 500.0000 ,["ARAMChaosNexus"] = 500.0000 ,["TT_NWraith"] = 750.0000 ,["TT_OrderTurret4"] = 500.0000 ,["Odin_SOG_Chaos_Crystal"] = 500.0000 ,["OdinQuestIndicator"] = 500.0000 ,["JarvanIVStandard"] = 500.0000 ,["TT_DummyPusher"] = 500.0000 ,["OdinClaw"] = 500.0000 ,["EliseSpiderling"] = 2000.0000 ,["QuinnValor"] = math.huge ,["UdyrTigerUlt"] = math.huge ,["UdyrTurtleUlt"] = math.huge ,["UdyrUlt"] = math.huge ,["UdyrPhoenixUlt"] = math.huge ,["ShacoBox"] = 1500.0000 ,["HA_AP_Poro"] = 1500.0000 ,["AnnieTibbers"] = math.huge ,["UdyrPhoenix"] = math.huge ,["UdyrTurtle"] = math.huge ,["UdyrTiger"] = math.huge ,["HA_AP_OrderShrineTurret"] = 500.0000 ,["HA_AP_Chains_Long"] = 500.0000 ,["HA_AP_BridgeLaneStatue"] = 500.0000 ,["HA_AP_ChaosTurretRubble"] = 500.0000 ,["HA_AP_PoroSpawner"] = 500.0000 ,["HA_AP_Cutaway"] = 500.0000 ,["HA_AP_Chains"] = 500.0000 ,["ChaosInhibitor_D"] = 500.0000 ,["ZacRebirthBloblet"] = 500.0000 ,["OrderInhibitor_D"] = 500.0000 ,["Nidalee_Spear"] = 500.0000 ,["Nidalee_Cougar"] = 500.0000 ,["TT_Buffplat_Chain"] = 500.0000 ,["WriggleLantern"] = 500.0000 ,["TwistedLizardElder"] = 500.0000 ,["RabidWolf"] = math.huge ,["HeimerTGreen"] = 1599.3999 ,["HeimerTRed"] = 1599.3999 ,["ViktorFF"] = 1599.3999 ,["TwistedGolem"] = math.huge ,["TwistedSmallWolf"] = math.huge ,["TwistedGiantWolf"] = math.huge ,["TwistedTinyWraith"] = 750.0000 ,["TwistedBlueWraith"] = 750.0000 ,["TwistedYoungLizard"] = 750.0000 ,["Red_Minion_Melee"] = math.huge ,["Blue_Minion_Melee"] = math.huge ,["Blue_Minion_Healer"] = 1000.0000 ,["Ghast"] = 750.0000 ,["blueDragon"] = 800.0000 ,["Red_Minion_MechRange"] = 3000, ["SRU_OrderMinionRanged"] = 650, ["SRU_ChaosMinionRanged"] = 650, ["SRU_OrderMinionSiege"] = 1200, ["SRU_ChaosMinionSiege"] = 1200, ["SRUAP_Turret_Chaos1"] = 1200, ["SRUAP_Turret_Chaos2"] = 1200, ["SRUAP_Turret_Chaos3"] = 1200, ["SRUAP_Turret_Order1"] = 1200, ["SRUAP_Turret_Order2"] = 1200, ["SRUAP_Turret_Order3"] = 1200, ["SRUAP_Turret_Chaos4"] = 1200, ["SRUAP_Turret_Chaos5"] = 500, ["SRUAP_Turret_Order4"] = 1200, ["SRUAP_Turret_Order5"] = 500, ["HA_ChaosMinionRanged"] = 650, ["HA_OrderMinionRanged"] = 650, ["HA_ChaosMinionSiege"] = 1200, ["HA_OrderMinionSiege"] = 1200 }
  636. self.White = ARGB(255,255,255,255)
  637. self.Red = ARGB(255,255,0,0)
  638. self.Blue = ARGB(255,0,0,255)
  639. self.Green = ARGB(255,0,255,0)
  640. self.Pink = ARGB(255,255,0,255)
  641. self.Black = ARGB(255,0,0,0)
  642. self.Yellow = ARGB(255,255,255,0)
  643. self.Cyan = ARGB(255,0,255,255)
  644. self.objectLoopEvents = {}
  645. self.afterObjectLoopEvents = {function()local c=0;for _,k in pairs(toPrint)do c=c+1;DrawText(k,30,50,25+30*c,toPrintCol[_])end;end}
  646. self.delayedActions = {}
  647. self.delayedActionsExecuter = nil
  648. self.tableForHPPrediction = {}
  649. self.gapcloserTable = {
  650. ["Aatrox"] = _Q, ["Akali"] = _R, ["Alistar"] = _W, ["Ahri"] = _R, ["Amumu"] = _Q, ["Corki"] = _W,
  651. ["Diana"] = _R, ["Elise"] = _Q, ["Elise"] = _E, ["Fiddlesticks"] = _R, ["Fiora"] = _Q,
  652. ["Fizz"] = _Q, ["Gnar"] = _E, ["Grags"] = _E, ["Graves"] = _E, ["Hecarim"] = _R,
  653. ["Irelia"] = _Q, ["JarvanIV"] = _Q, ["Jax"] = _Q, ["Jayce"] = "JayceToTheSkies", ["Katarina"] = _E,
  654. ["Kassadin"] = _R, ["Kennen"] = _E, ["KhaZix"] = _E, ["Lissandra"] = _E, ["LeBlanc"] = _W,
  655. ["LeeSin"] = "blindmonkqtwo", ["Leona"] = _E, ["Lucian"] = _E, ["Malphite"] = _R, ["MasterYi"] = _Q,
  656. ["MonkeyKing"] = _E, ["Nautilus"] = _Q, ["Nocturne"] = _R, ["Olaf"] = _R, ["Pantheon"] = _W,
  657. ["Poppy"] = _E, ["RekSai"] = _E, ["Renekton"] = _E, ["Riven"] = _E, ["Sejuani"] = _Q,
  658. ["Sion"] = _R, ["Shen"] = _E, ["Shyvana"] = _R, ["Talon"] = _E, ["Thresh"] = _Q,
  659. ["Tristana"] = _W, ["Tryndamere"] = "Slash", ["Udyr"] = _E, ["Volibear"] = _Q, ["Vi"] = _Q,
  660. ["XinZhao"] = _E, ["Yasuo"] = _E, ["Zac"] = _E, ["Ziggs"] = _W
  661. }
  662. self.GapcloseSpell, self.GapcloseTime, self.GapcloseUnit, self.GapcloseTargeted, self.GapcloseRange = 2, 0, nil, true, 450
  663. end
  664.  
  665. function goslib:SetupLocalCallbacks()
  666. OnObjectLoop(function(object) self:ObjectLoop(object) end)
  667. OnLoop(function() self:Loop() end)
  668. OnProcessSpell(function(x, y) self:ProcessSpell(x, y) end)
  669. end
  670.  
  671. function goslib:ObjectLoop(object)
  672. if self.objectLoopEvents then
  673. for _, func in pairs(self.objectLoopEvents) do
  674. if func then
  675. func(object)
  676. end
  677. end
  678. end
  679. end
  680.  
  681. function goslib:Loop()
  682. if self.afterObjectLoopEvents then
  683. for _, func in pairs(self.afterObjectLoopEvents) do
  684. if func then
  685. func()
  686. end
  687. end
  688. end
  689. end
  690.  
  691. function goslib:ProcessSpell(unit, spell)
  692. local target = spell.target
  693. if target and IsObjectAlive(target) and GetOrigin(target) then
  694. if spell.name:lower():find("attack") then
  695. local timer = self:GetDistance(target,unit)/self:GetProjectileSpeed(unit)+spell.windUpTime
  696. if not self.tableForHPPrediction[GetNetworkID(target)] then self.tableForHPPrediction[GetNetworkID(target)] = {} end
  697. table.insert(self.tableForHPPrediction[GetNetworkID(target)], {source = unit, dmg = self:GetDmg(unit, target), time = GetTickCount() + 1000*timer, pos = Vector(unit)})
  698. end
  699. end
  700. end
  701.  
  702. function goslib:GetProjectileSpeed(unit)
  703. return self.projectilespeeds[GetObjectName(unit)] and self.projectilespeeds[GetObjectName(unit)] or math.huge
  704. end
  705.  
  706. function goslib:PredictHealth(unit, delta)
  707. if self.tableForHPPrediction[GetNetworkID(unit)] then
  708. local dmg = 0
  709. delta = delta + GetLatency()
  710. for _, attack in pairs(self.tableForHPPrediction[GetNetworkID(unit)]) do
  711. if IsObjectAlive(attack.source) and GetTickCount() < attack.time and attack.pos == Vector(attack.source) then
  712. if GetTickCount() + delta > attack.time then
  713. dmg = dmg + attack.dmg
  714. end
  715. else
  716. self.tableForHPPrediction[GetNetworkID(unit)][_] = nil
  717. end
  718. end
  719. return GetCurrentHP(unit) - dmg
  720. else
  721. return GetCurrentHP(unit)
  722. end
  723. end
  724.  
  725. function goslib:GetDmg(from, to)
  726. return self:CalcDamage(from, to, GetBonusDmg(from)+GetBaseDamage(from))
  727. end
  728.  
  729. function goslib:MakeObjectManager()
  730. _G.objectManager = {}
  731. objectManager.objects = {}
  732. objectManager.objectLCallbackId = 1
  733. objectManager.objectACallbackId = 1
  734. objectManager.tick = 0
  735. local done = false
  736. self.objectLoopEvents[objectManager.objectLCallbackId] = function(object)
  737. done = true
  738. objectManager.objects[object] = object
  739. end
  740. self.afterObjectLoopEvents[objectManager.objectACallbackId] = function()
  741. if done and self.objectLoopEvents[objectManager.objectLCallbackId] then
  742. self.objectLoopEvents[objectManager.objectLCallbackId] = nil
  743. end
  744. if not self.objectLoopEvents[objectManager.objectLCallbackId] then
  745. self:FindHeroes()
  746. self:MakeMinionManager()
  747. self.afterObjectLoopEvents[objectManager.objectACallbackId] = nil
  748. end
  749. end
  750. OnCreateObj(function(object)
  751. objectManager.objects[object] = object
  752. end)
  753. OnDeleteObj(function(object)
  754. objectManager.objects[object] = nil
  755. end)
  756. local function CleanUp()
  757. collectgarbage()
  758. self:DelayAction(CleanUp, 10)
  759. end
  760. CleanUp()
  761. end
  762.  
  763. function goslib:FindHeroes()
  764. self.heroes = {myHero}
  765. for i, object in pairs(objectManager.objects) do
  766. if GetObjectType(object) == Obj_AI_Hero then
  767. self.heroes[#self.heroes+1] = object
  768. end
  769. end
  770. end
  771.  
  772. function goslib:MakeMinionManager()
  773. _G.minionManager = {}
  774. minionManager.maxObjects = 0
  775. minionManager.objects = {}
  776. minionManager.unsorted = {}
  777. minionManager.tick = 0
  778. for i, object in pairs(objectManager.objects) do
  779. if GetObjectType(object) == Obj_AI_Minion and IsObjectAlive(object) then
  780. local objName = GetObjectName(object)
  781. if objName == "Barrel" or (GetTeam(object) == 300 and GetCurrentHP(object) < 100000 or objName:find('_')) then
  782. minionManager.maxObjects = minionManager.maxObjects + 1
  783. minionManager.objects[minionManager.maxObjects] = object
  784. end
  785. end
  786. end
  787. local function findDeadPlace()
  788. for i = 1, minionManager.maxObjects do
  789. local object = minionManager.objects[i]
  790. if not object or IsDead(object) then
  791. return i
  792. end
  793. end
  794. end
  795. OnLoop(function()
  796. if minionManager.tick > GetTickCount() then return end
  797. minionManager.tick = GetTickCount() + 125
  798. for i, object in pairs(minionManager.unsorted) do
  799. local object = minionManager.unsorted[i]
  800. local objName = GetObjectName(object)
  801. if objName == "Barrel" or (GetTeam(object) == 300 and GetCurrentHP(object) < 100000 or objName:find('_')) then
  802. local spot = findDeadPlace()
  803. if spot then
  804. minionManager.objects[spot] = object
  805. table.remove(minionManager.unsorted, i)
  806. else
  807. minionManager.maxObjects = minionManager.maxObjects + 1
  808. minionManager.objects[minionManager.maxObjects] = object
  809. table.remove(minionManager.unsorted, i)
  810. end
  811. end
  812. end
  813. end)
  814. OnCreateObj(function(object)
  815. if GetObjectType(object) == Obj_AI_Minion then
  816. table.insert(minionManager.unsorted, object)
  817. end
  818. end)
  819. end
  820.  
  821. function goslib:AddGapcloseEvent(spell, range, targeted)
  822. self.GapcloseSpell = spell
  823. self.GapcloseTime = 0
  824. self.GapcloseUnit = nil
  825. self.GapcloseTargeted = targeted
  826. self.GapcloseRange = range
  827. self.str = {[_Q] = "Q", [_W] = "W", [_E] = "E", [_R] = "R"}
  828. GapcloseConfig = Menu("Anti-Gapclose ("..self.str[spell]..")", "gapclose")
  829. self:DelayAction(function()
  830. for _,k in pairs(self:GetEnemyHeroes()) do
  831. if self.gapcloserTable[GetObjectName(k)] then
  832. GapcloseConfig:Boolean(GetObjectName(k).."agap", "On "..GetObjectName(k).." "..(type(self.gapcloserTable[GetObjectName(k)]) == 'number' and self.str[self.gapcloserTable[GetObjectName(k)]] or (GetObjectName(k) == "LeeSin" and "Q" or "E")), true)
  833. end
  834. end
  835. end, 1)
  836. OnProcessSpell(function(unit, spell)
  837. if not unit or not self.gapcloserTable[GetObjectName(unit)] or GapcloseConfig[GetObjectName(unit).."agap"] == nil or not GapcloseConfig[GetObjectName(unit).."agap"]:Value() then return end
  838. local unitName = GetObjectName(unit)
  839. if spell.name == (type(self.gapcloserTable[unitName]) == 'number' and GetCastName(unit, self.gapcloserTable[unitName]) or self.gapcloserTable[unitName]) and (spell.target == myHero or self:GetDistanceSqr(spell.endPos) < self.GapcloseRange*self.GapcloseRange*4) then
  840. self.GapcloseTime = GetTickCount() + 2000
  841. self.GapcloseUnit = unit
  842. end
  843. end)
  844. OnLoop(function(myHero)
  845. if CanUseSpell(myHero, self.GapcloseSpell) == READY and self.GapcloseTime and self.GapcloseUnit and self.GapcloseTime >GetTickCount() then
  846. local pos = GetOrigin(self.GapcloseUnit)
  847. if self.GapcloseTargeted then
  848. if self:GetDistanceSqr(pos,self:myHeroPos()) < self.GapcloseRange*self.GapcloseRange then
  849. CastTargetSpell(self.GapcloseUnit, self.GapcloseSpell)
  850. end
  851. else
  852. if self:GetDistanceSqr(pos,self:myHeroPos()) < self.GapcloseRange*self.GapcloseRange*4 then
  853. CastSkillShot(self.GapcloseSpell, pos.x, pos.y, pos.z)
  854. end
  855. end
  856. else
  857. self.GapcloseTime = 0
  858. self.GapcloseUnit = nil
  859. end
  860. end)
  861. end
  862.  
  863. function goslib:CountMinions()
  864. return #GetAllMinions()
  865. end
  866.  
  867. function goslib:GetAllMinions(team)
  868. local result = {}
  869. for i = 1, minionManager.maxObjects do
  870. local object = minionManager.objects[i]
  871. if object and not IsDead(object) then
  872. if not team or GetTeam(object) == team then
  873. result[#result+1] = object
  874. end
  875. end
  876. end
  877. return result
  878. end
  879.  
  880. function goslib:ClosestMinion(pos, team)
  881. local minion = nil
  882. local minions = GetAllMinions()
  883. for k=1, #minions do
  884. local v = minions[k]
  885. local objTeam = GetTeam(v)
  886. if not minion and v and objTeam == team then minion = v end
  887. if minion and v and objTeam == team and self:GetDistanceSqr(GetOrigin(minion),pos) > self:GetDistanceSqr(GetOrigin(v),pos) then
  888. minion = v
  889. end
  890. end
  891. return minion
  892. end
  893.  
  894. function goslib:GetLowestMinion(pos, range, team)
  895. local minion = nil
  896. local minions = GetAllMinions()
  897. for k=1, #minions do
  898. local v = minions[k]
  899. local objTeam = GetTeam(v)
  900. if not minion and v and objTeam == team and self:GetDistanceSqr(GetOrigin(v),pos) < range*range then minion = v end
  901. if minion and v and objTeam == team and self:GetDistanceSqr(GetOrigin(v),pos) < range*range and GetCurrentHP(v) < GetCurrentHP(minion) then
  902. minion = v
  903. end
  904. end
  905. return minion
  906. end
  907.  
  908. function goslib:GetHighestMinion(pos, range, team)
  909. local minion = nil
  910. local minions = GetAllMinions()
  911. for k=1, #minions do
  912. local v = minions[k]
  913. local objTeam = GetTeam(v)
  914. if not minion and v and objTeam == team and self:GetDistanceSqr(GetOrigin(v),pos) < range*range then minion = v end
  915. if minion and v and objTeam == team and self:GetDistanceSqr(GetOrigin(v),pos) < range*range and GetCurrentHP(v) > GetCurrentHP(minion) then
  916. minion = v
  917. end
  918. end
  919. return minion
  920. end
  921.  
  922. function goslib:GenerateMovePos()
  923. local mPos = GetMousePos()
  924. local hPos = self:myHeroPos()
  925. local tV = {x = (mPos.x-hPos.x), z = (mPos.z-hPos.z)}
  926. local len = math.sqrt(tV.x * tV.x + tV.z * tV.z)
  927. return {x = hPos.x + 250 * tV.x / len, y = hPos.y, z = hPos.z + 250 * tV.z / len}
  928. end
  929.  
  930. function goslib:IsInDistance(p1,r)
  931. return self:GetDistanceSqr(GetOrigin(p1)) < r*r
  932. end
  933.  
  934. function goslib:GetDistance(p1,p2)
  935. p1 = GetOrigin(p1) or p1
  936. p2 = GetOrigin(p2) or p2 or self:myHeroPos()
  937. return math.sqrt(self:GetDistanceSqr(p1,p2))
  938. end
  939.  
  940. function goslib:GetDistanceSqr(p1,p2)
  941. p2 = p2 or self:myHeroPos()
  942. local dx = p1.x - p2.x
  943. local dz = (p1.z or p1.y) - (p2.z or p2.y)
  944. return dx*dx + dz*dz
  945. end
  946.  
  947. function goslib:GetYDistance(p1, p2)
  948. p1 = GetOrigin(p1) or p1
  949. p2 = GetOrigin(p2) or p2 or self:myHeroPos()
  950. return math.sqrt((p1.x - p2.x) ^ 2 + (p1.y - p2.y) ^ 2 + (p1.z - p2.z) ^ 2)
  951. end
  952.  
  953. function goslib:ValidTarget(unit, range)
  954. range = range or 25000
  955. if unit == nil or GetOrigin(unit) == nil or not IsTargetable(unit) or IsImmune(unit,myHero) or IsDead(unit) or not IsVisible(unit) or GetTeam(unit) == GetTeam(myHero) or not self:IsInDistance(unit, range) then return false end
  956. return true
  957. end
  958.  
  959. function goslib:myHeroPos()
  960. return GetOrigin(myHero)
  961. end
  962.  
  963. function goslib:GetEnemyHeroes()
  964. local result = {}
  965. for _=1, #(self.heroes or {}) do
  966. local obj = self.heroes[_]
  967. if GetTeam(obj) ~= GetTeam(GetMyHero()) then
  968. table.insert(result, obj)
  969. end
  970. end
  971. return result
  972. end
  973.  
  974. function goslib:GetAllyHeroes()
  975. local result = {}
  976. for _=1, #(self.heroes or {}) do
  977. local obj = self.heroes[_]
  978. if GetTeam(obj) == GetTeam(GetMyHero()) then
  979. table.insert(result, obj)
  980. end
  981. end
  982. return result
  983. end
  984.  
  985. function goslib:DelayAction(func, delay, args)
  986. if not self.delayedActionsExecuter then
  987. function goslib:delayedActionsExecuter()
  988. for t, funcs in pairs(self.delayedActions) do
  989. if t <= GetTickCount() then
  990. for _, f in ipairs(funcs) do f.func(unpack(f.args or {})) end
  991. self.delayedActions[t] = nil
  992. end
  993. end
  994. end
  995. OnLoop(function() self:delayedActionsExecuter() end)
  996. end
  997. local t = GetTickCount() + (delay or 0)
  998. if self.delayedActions[t] then
  999. table.insert(self.delayedActions[t], { func = func, args = args })
  1000. else
  1001. self.delayedActions[t] = { { func = func, args = args } }
  1002. end
  1003. end
  1004.  
  1005. function goslib:CalcDamage(source, target, addmg, apdmg)
  1006. local ADDmg = addmg or 0
  1007. local APDmg = apdmg or 0
  1008. local ArmorPen = GetObjectType(source) == Obj_AI_Minion and 0 or math.floor(GetArmorPenFlat(source))
  1009. local ArmorPenPercent = GetObjectType(source) == Obj_AI_Minion and 1 or math.floor(GetArmorPenPercent(source)*100)/100
  1010. local Armor = GetArmor(target)*ArmorPenPercent-ArmorPen
  1011. 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
  1012. local MagicPen = math.floor(GetMagicPenFlat(source))
  1013. local MagicPenPercent = math.floor(GetMagicPenPercent(source)*100)/100
  1014. local MagicArmor = GetMagicResist(target)*MagicPenPercent-MagicPen
  1015. local MagicArmorPercent = MagicArmor > 0 and math.floor(MagicArmor*100/(100+MagicArmor))/100 or math.ceil(MagicArmor*100/(100-MagicArmor))/100
  1016. return (GotBuff(source,"exhausted") > 0 and 0.4 or 1) * math.floor(ADDmg*(1-ArmorPercent))+math.floor(APDmg*(1-MagicArmorPercent))
  1017. end
  1018.  
  1019. function goslib:GetTarget(range, damageType)
  1020. damageType = damageType or ad[myHeroName] and 2 or ap[myHeroName] and 1 or mixed[myHeroName] and 3 or 0
  1021. if damageType == 0 then print("Champion "..myHeroName.." not supported by the target selector. Please inform inspired.") end
  1022. local target, steps = nil, 10000
  1023. for _, k in pairs(self:GetEnemyHeroes()) do
  1024. local step = GetCurrentHP(k) / self:CalcDamage(GetMyHero(), k, DAMAGE_MAGIC ~= damageType and 25 or 0, DAMAGE_PHYSICAL ~= damageType and 25 or 0)
  1025. if k and self:ValidTarget(k, range) and step < steps then
  1026. target = k
  1027. steps = step
  1028. end
  1029. end
  1030. return target
  1031. end
  1032.  
  1033. function goslib:CastOffensiveItems(unit)
  1034. i = {3074, 3077, 3142, 3184}
  1035. u = {3153, 3146, 3144}
  1036. for _,k in pairs(i) do
  1037. slot = GetItemSlot(myHero,k)
  1038. if slot ~= nil and slot ~= 0 and CanUseSpell(myHero, slot) == READY then
  1039. CastTargetSpell(GetMyHero(), slot)
  1040. return true
  1041. end
  1042. end
  1043. if self:ValidTarget(unit) then
  1044. for _,k in pairs(u) do
  1045. slot = GetItemSlot(myHero,k)
  1046. if slot ~= nil and slot ~= 0 and CanUseSpell(myHero, slot) == READY then
  1047. CastTargetSpell(unit, slot)
  1048. return true
  1049. end
  1050. end
  1051. end
  1052. return false
  1053. end
  1054.  
  1055. function goslib:Circle(col)
  1056. local circle = {}
  1057. circle.object = nil
  1058. circle.color = col or 0xffffffff
  1059. circle.objectACallbackId = #self.afterObjectLoopEvents+1
  1060. circle.contains = function(pos)
  1061. return GoS.GetDistanceSqr(Vector(circle.x, circle.y, circle.z), pos) < circle.r * circle.r
  1062. end
  1063. circle.Color = function(col)
  1064. circle.color = color or 0xffffffff
  1065. return circle
  1066. end
  1067. circle.SetPos = function(x, y, z, r)
  1068. local pos = GetOrigin(x) or type(x) ~= "number" and x or nil
  1069. circle.x = pos and pos.x or x
  1070. circle.y = pos and pos.y or y
  1071. circle.z = pos and pos.z or z
  1072. circle.r = pos and y or r
  1073. return circle
  1074. end
  1075. circle.Attach = function(object, r)
  1076. circle.object = object
  1077. circle.r = r
  1078. return circle
  1079. end
  1080. circle.Draw = function(boolean)
  1081. if boolean then
  1082. self.afterObjectLoopEvents[circle.objectACallbackId] = function()
  1083. if circle.object then local pos = GetOrigin(circle.object) circle.x=pos.x circle.y=pos.y circle.z=pos.z end
  1084. DrawCircle(circle.x, circle.y, circle.z, circle.r, 1, 128, circle.color)
  1085. end
  1086. else
  1087. self.afterObjectLoopEvents[circle.objectACallbackId] = nil
  1088. end
  1089. end
  1090. return circle
  1091. end
  1092.  
  1093. function goslib:EnemiesAround(pos, range)
  1094. local c = 0
  1095. if pos == nil then return 0 end
  1096. for k,v in pairs(self:GetEnemyHeroes()) do
  1097. if v and self:ValidTarget(v) and self:GetDistanceSqr(pos,GetOrigin(v)) < range*range then
  1098. c = c + 1
  1099. end
  1100. end
  1101. return c
  1102. end
  1103.  
  1104. function goslib:ClosestEnemy(pos)
  1105. local enemy = nil
  1106. for k,v in pairs(self:GetEnemyHeroes()) do
  1107. if not enemy and v then enemy = v end
  1108. if enemy and v and self:GetDistanceSqr(GetOrigin(enemy),pos) > self:GetDistanceSqr(GetOrigin(v),pos) then
  1109. enemy = v
  1110. end
  1111. end
  1112. return enemy
  1113. end
  1114.  
  1115. function goslib:AlliesAround(pos, range)
  1116. local c = 0
  1117. if pos == nil then return 0 end
  1118. for k,v in pairs(self:GetAllyHeroes()) do
  1119. if v and GetOrigin(v) ~= nil and not IsDead(v) and v ~= myHero and self:GetDistanceSqr(pos,GetOrigin(v)) < range*range then
  1120. c = c + 1
  1121. end
  1122. end
  1123. return c
  1124. end
  1125.  
  1126. function goslib:ClosestAlly(pos)
  1127. local ally = nil
  1128. for k,v in pairs(self:GetAllyHeroes()) do
  1129. if not ally and v then ally = v end
  1130. if ally and v and self:GetDistanceSqr(GetOrigin(ally),pos) > self:GetDistanceSqr(GetOrigin(v),pos) then
  1131. ally = v
  1132. end
  1133. end
  1134. return ally
  1135. end
  1136.  
  1137. _G.GoS = goslib()
  1138. _G.gos = _G.GoS
  1139. _G.Gos = _G.GoS
  1140. _G.GOS = _G.GoS
  1141. _G.gOS = _G.GoS
  1142. _G.goS = _G.GoS
  1143. _G.gOs = _G.GoS
  1144. _G.GOs = _G.GoS
  1145.  
  1146. function VectorType(v)
  1147. v = GetOrigin(v) or v
  1148. 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"))
  1149. end
  1150.  
  1151. local function IsClockWise(A,B,C)
  1152. return VectorDirection(A,B,C)<=0
  1153. end
  1154.  
  1155. local function IsCounterClockWise(A,B,C)
  1156. return not IsClockWise(A,B,C)
  1157. end
  1158.  
  1159. function IsLineSegmentIntersection(A,B,C,D)
  1160. return IsClockWise(A, C, D) ~= IsClockWise(B, C, D) and IsClockWise(A, B, C) ~= IsClockWise(A, B, D)
  1161. end
  1162.  
  1163. function VectorIntersection(a1, b1, a2, b2) --returns a 2D point where to lines intersect (assuming they have an infinite length)
  1164. assert(VectorType(a1) and VectorType(b1) and VectorType(a2) and VectorType(b2), "VectorIntersection: wrong argument types (4 <Vector> expected)")
  1165. local x1, y1, x2, y2, x3, y3, x4, y4 = a1.x, a1.z or a1.y, b1.x, b1.z or b1.y, a2.x, a2.z or a2.y, b2.x, b2.z or b2.y
  1166. local r, s, u, v, k, l = x1 * y2 - y1 * x2, x3 * y4 - y3 * x4, x3 - x4, x1 - x2, y3 - y4, y1 - y2
  1167. local px, py, divisor = r * u - v * s, r * k - l * s, v * k - l * u
  1168. return divisor ~= 0 and Vector(px / divisor, py / divisor)
  1169. end
  1170.  
  1171. function LineSegmentIntersection(A,B,C,D)
  1172. return IsLineSegmentIntersection(A,B,C,D) and VectorIntersection(A,B,C,D)
  1173. end
  1174.  
  1175. function VectorDirection(v1, v2, v)
  1176. return ((v.z or v.y) - (v1.z or v1.y)) * (v2.x - v1.x) - ((v2.z or v2.y) - (v1.z or v1.y)) * (v.x - v1.x)
  1177. end
  1178.  
  1179. function VectorPointProjectionOnLine(v1, v2, v)
  1180. assert(VectorType(v1) and VectorType(v2) and VectorType(v), "VectorPointProjectionOnLine: wrong argument types (3 <Vector> expected)")
  1181. local line = Vector(v2) - v1
  1182. local t = ((-(v1.x * line.x - line.x * v.x + (v1.z - v.z) * line.z)) / line:len2())
  1183. return (line * t) + v1
  1184. end
  1185.  
  1186. --[[
  1187. VectorPointProjectionOnLineSegment: Extended VectorPointProjectionOnLine in 2D Space
  1188. v1 and v2 are the start and end point of the linesegment
  1189. v is the point next to the line
  1190. return:
  1191. pointSegment = the point closest to the line segment (table with x and y member)
  1192. pointLine = the point closest to the line (assuming infinite extent in both directions) (table with x and y member), same as VectorPointProjectionOnLine
  1193. isOnSegment = if the point closest to the line is on the segment
  1194. ]]
  1195. function VectorPointProjectionOnLineSegment(v1, v2, v)
  1196. assert(v1 and v2 and v, "VectorPointProjectionOnLineSegment: wrong argument types (3 <Vector> expected)")
  1197. local cx, cy, ax, ay, bx, by = v.x, (v.z or v.y), v1.x, (v1.z or v1.y), v2.x, (v2.z or v2.y)
  1198. local rL = ((cx - ax) * (bx - ax) + (cy - ay) * (by - ay)) / ((bx - ax) ^ 2 + (by - ay) ^ 2)
  1199. local pointLine = { x = ax + rL * (bx - ax), y = ay + rL * (by - ay) }
  1200. local rS = rL < 0 and 0 or (rL > 1 and 1 or rL)
  1201. local isOnSegment = rS == rL
  1202. local pointSegment = isOnSegment and pointLine or { x = ax + rS * (bx - ax), y = ay + rS * (by - ay) }
  1203. return pointSegment, pointLine, isOnSegment
  1204. end
  1205.  
  1206. class 'Vector'
  1207.  
  1208. function Vector:__init(a, b, c)
  1209. if a == nil then
  1210. self.x, self.y, self.z = 0.0, 0.0, 0.0
  1211. elseif b == nil then
  1212. a = GetOrigin(a) or a
  1213. assert(VectorType(a), "Vector: wrong argument types (expected nil or <Vector> or 2 <number> or 3 <number>)")
  1214. self.x, self.y, self.z = a.x, a.y, a.z
  1215. else
  1216. assert(type(a) == "number" and (type(b) == "number" or type(c) == "number"), "Vector: wrong argument types (<Vector> or 2 <number> or 3 <number>)")
  1217. self.x = a
  1218. if b and type(b) == "number" then self.y = b end
  1219. if c and type(c) == "number" then self.z = c end
  1220. end
  1221. end
  1222.  
  1223. function Vector:__type()
  1224. return "Vector"
  1225. end
  1226.  
  1227. function Vector:__add(v)
  1228. assert(VectorType(v) and VectorType(self), "add: wrong argument types (<Vector> expected)")
  1229. 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)
  1230. end
  1231.  
  1232. function Vector:__sub(v)
  1233. assert(VectorType(v) and VectorType(self), "Sub: wrong argument types (<Vector> expected)")
  1234. 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)
  1235. end
  1236.  
  1237. function Vector.__mul(a, b)
  1238. if type(a) == "number" and VectorType(b) then
  1239. return Vector({ x = b.x * a, y = b.y and b.y * a, z = b.z and b.z * a })
  1240. elseif type(b) == "number" and VectorType(a) then
  1241. return Vector({ x = a.x * b, y = a.y and a.y * b, z = a.z and a.z * b })
  1242. else
  1243. assert(VectorType(a) and VectorType(b), "Mul: wrong argument types (<Vector> or <number> expected)")
  1244. return a:dotP(b)
  1245. end
  1246. end
  1247.  
  1248. function Vector.__div(a, b)
  1249. if type(a) == "number" and VectorType(b) then
  1250. return Vector({ x = a / b.x, y = b.y and a / b.y, z = b.z and a / b.z })
  1251. else
  1252. assert(VectorType(a) and type(b) == "number", "Div: wrong argument types (<number> expected)")
  1253. return Vector({ x = a.x / b, y = a.y and a.y / b, z = a.z and a.z / b })
  1254. end
  1255. end
  1256.  
  1257. function Vector.__lt(a, b)
  1258. assert(VectorType(a) and VectorType(b), "__lt: wrong argument types (<Vector> expected)")
  1259. return a:len() < b:len()
  1260. end
  1261.  
  1262. function Vector.__le(a, b)
  1263. assert(VectorType(a) and VectorType(b), "__le: wrong argument types (<Vector> expected)")
  1264. return a:len() <= b:len()
  1265. end
  1266.  
  1267. function Vector:__eq(v)
  1268. assert(VectorType(v), "__eq: wrong argument types (<Vector> expected)")
  1269. return self.x == v.x and self.y == v.y and self.z == v.z
  1270. end
  1271.  
  1272. function Vector:__unm()
  1273. return Vector(-self.x, self.y and -self.y, self.z and -self.z)
  1274. end
  1275.  
  1276. function Vector:__vector(v)
  1277. assert(VectorType(v), "__vector: wrong argument types (<Vector> expected)")
  1278. return self:crossP(v)
  1279. end
  1280.  
  1281. function Vector:__tostring()
  1282. if self.y and self.z then
  1283. return "(" .. tostring(self.x) .. "," .. tostring(self.y) .. "," .. tostring(self.z) .. ")"
  1284. else
  1285. return "(" .. tostring(self.x) .. "," .. self.y and tostring(self.y) or tostring(self.z) .. ")"
  1286. end
  1287. end
  1288.  
  1289. function Vector:clone()
  1290. return Vector(self)
  1291. end
  1292.  
  1293. function Vector:unpack()
  1294. return self.x, self.y, self.z
  1295. end
  1296.  
  1297. function Vector:len2(v)
  1298. assert(v == nil or VectorType(v), "dist: wrong argument types (<Vector> expected)")
  1299. local v = v and Vector(v) or self
  1300. return self.x * v.x + (self.y and self.y * v.y or 0) + (self.z and self.z * v.z or 0)
  1301. end
  1302.  
  1303. function Vector:len()
  1304. return math.sqrt(self:len2())
  1305. end
  1306.  
  1307. function Vector:dist(v)
  1308. assert(VectorType(v), "dist: wrong argument types (<Vector> expected)")
  1309. local a = self - v
  1310. return a:len()
  1311. end
  1312.  
  1313. function Vector:normalize()
  1314. local a = self:len()
  1315. self.x = self.x / a
  1316. if self.y then self.y = self.y / a end
  1317. if self.z then self.z = self.z / a end
  1318. end
  1319.  
  1320. function Vector:normalized()
  1321. local a = self:clone()
  1322. a:normalize()
  1323. return a
  1324. end
  1325.  
  1326. function Vector:center(v)
  1327. assert(VectorType(v), "center: wrong argument types (<Vector> expected)")
  1328. return Vector((self + v) / 2)
  1329. end
  1330.  
  1331. function Vector:crossP(other)
  1332. assert(self.y and self.z and other.y and other.z, "crossP: wrong argument types (3 Dimensional <Vector> expected)")
  1333. return Vector({
  1334. x = other.z * self.y - other.y * self.z,
  1335. y = other.x * self.z - other.z * self.x,
  1336. z = other.y * self.x - other.x * self.y
  1337. })
  1338. end
  1339.  
  1340. function Vector:dotP(other)
  1341. assert(VectorType(other), "dotP: wrong argument types (<Vector> expected)")
  1342. return self.x * other.x + (self.y and (self.y * other.y) or 0) + (self.z and (self.z * other.z) or 0)
  1343. end
  1344.  
  1345. function Vector:projectOn(v)
  1346. assert(VectorType(v), "projectOn: invalid argument: cannot project Vector on " .. type(v))
  1347. if type(v) ~= "Vector" then v = Vector(v) end
  1348. local s = self:len2(v) / v:len2()
  1349. return Vector(v * s)
  1350. end
  1351.  
  1352. function Vector:mirrorOn(v)
  1353. assert(VectorType(v), "mirrorOn: invalid argument: cannot mirror Vector on " .. type(v))
  1354. return self:projectOn(v) * 2
  1355. end
  1356.  
  1357. function Vector:sin(v)
  1358. assert(VectorType(v), "sin: wrong argument types (<Vector> expected)")
  1359. if type(v) ~= "Vector" then v = Vector(v) end
  1360. local a = self:__vector(v)
  1361. return math.sqrt(a:len2() / (self:len2() * v:len2()))
  1362. end
  1363.  
  1364. function Vector:cos(v)
  1365. assert(VectorType(v), "cos: wrong argument types (<Vector> expected)")
  1366. if type(v) ~= "Vector" then v = Vector(v) end
  1367. return self:len2(v) / math.sqrt(self:len2() * v:len2())
  1368. end
  1369.  
  1370. function Vector:angle(v)
  1371. assert(VectorType(v), "angle: wrong argument types (<Vector> expected)")
  1372. return math.acos(self:cos(v))
  1373. end
  1374.  
  1375. function Vector:affineArea(v)
  1376. assert(VectorType(v), "affineArea: wrong argument types (<Vector> expected)")
  1377. if type(v) ~= "Vector" then v = Vector(v) end
  1378. local a = self:__vector(v)
  1379. return math.sqrt(a:len2())
  1380. end
  1381.  
  1382. function Vector:triangleArea(v)
  1383. assert(VectorType(v), "triangleArea: wrong argument types (<Vector> expected)")
  1384. return self:affineArea(v) / 2
  1385. end
  1386.  
  1387. function Vector:rotateXaxis(phi)
  1388. assert(type(phi) == "number", "Rotate: wrong argument types (expected <number> for phi)")
  1389. local c, s = math.cos(phi), math.sin(phi)
  1390. self.y, self.z = self.y * c - self.z * s, self.z * c + self.y * s
  1391. end
  1392.  
  1393. function Vector:rotateYaxis(phi)
  1394. assert(type(phi) == "number", "Rotate: wrong argument types (expected <number> for phi)")
  1395. local c, s = math.cos(phi), math.sin(phi)
  1396. self.x, self.z = self.x * c + self.z * s, self.z * c - self.x * s
  1397. end
  1398.  
  1399. function Vector:rotateZaxis(phi)
  1400. assert(type(phi) == "number", "Rotate: wrong argument types (expected <number> for phi)")
  1401. local c, s = math.cos(phi), math.sin(phi)
  1402. self.x, self.y = self.x * c - self.z * s, self.y * c + self.x * s
  1403. end
  1404.  
  1405. function Vector:rotate(phiX, phiY, phiZ)
  1406. assert(type(phiX) == "number" and type(phiY) == "number" and type(phiZ) == "number", "Rotate: wrong argument types (expected <number> for phi)")
  1407. if phiX ~= 0 then self:rotateXaxis(phiX) end
  1408. if phiY ~= 0 then self:rotateYaxis(phiY) end
  1409. if phiZ ~= 0 then self:rotateZaxis(phiZ) end
  1410. end
  1411.  
  1412. function Vector:rotated(phiX, phiY, phiZ)
  1413. assert(type(phiX) == "number" and type(phiY) == "number" and type(phiZ) == "number", "Rotated: wrong argument types (expected <number> for phi)")
  1414. local a = self:clone()
  1415. a:rotate(phiX, phiY, phiZ)
  1416. return a
  1417. end
  1418.  
  1419. -- not yet full 3D functions
  1420. function Vector:polar()
  1421. if math.close(self.x, 0) then
  1422. if (self.z or self.y) > 0 then return 90
  1423. elseif (self.z or self.y) < 0 then return 270
  1424. else return 0
  1425. end
  1426. else
  1427. local theta = math.deg(math.atan((self.z or self.y) / self.x))
  1428. if self.x < 0 then theta = theta + 180 end
  1429. if theta < 0 then theta = theta + 360 end
  1430. return theta
  1431. end
  1432. end
  1433.  
  1434. function Vector:angleBetween(v1, v2)
  1435. assert(VectorType(v1) and VectorType(v2), "angleBetween: wrong argument types (2 <Vector> expected)")
  1436. local p1, p2 = (-self + v1), (-self + v2)
  1437. local theta = p1:polar() - p2:polar()
  1438. if theta < 0 then theta = theta + 360 end
  1439. if theta > 180 then theta = 360 - theta end
  1440. return theta
  1441. end
  1442.  
  1443. function Vector:compare(v)
  1444. assert(VectorType(v), "compare: wrong argument types (<Vector> expected)")
  1445. local ret = self.x - v.x
  1446. if ret == 0 then ret = self.z - v.z end
  1447. return ret
  1448. end
  1449.  
  1450. function Vector:perpendicular()
  1451. return Vector(-self.z, self.y, self.x)
  1452. end
  1453.  
  1454. function Vector:perpendicular2()
  1455. return Vector(self.z, self.y, -self.x)
  1456. end
  1457.  
  1458. -- }
  1459.  
  1460. Msg("Loaded.")
Add Comment
Please, Sign In to add comment