Guest User

Untitled

a guest
Nov 25th, 2015
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 156.89 KB | None | 0 0
  1. Version = 3
  2. _G.GoodEvade = true
  3. _G.GoodEvadeVersion = Version
  4.  
  5. class 'CollisionPE'
  6. HERO_ALL = 1
  7. HERO_ENEMY = 2
  8. HERO_ALLY = 3
  9.  
  10. function CollisionPE:__init(sRange, projSpeed, sDelay, sWidth)
  11. uniqueId = uniqueId + 1
  12. self.uniqueId = uniqueId
  13.  
  14. self.sRange = sRange
  15. self.projSpeed = projSpeed
  16. self.sDelay = sDelay
  17. self.sWidth = sWidth/2
  18.  
  19. self.enemyMinions = minionManager(MINION_ALLY, 2000, myHero, MINION_SORT_HEALTH_ASC)
  20. self.minionupdate = 0
  21. end
  22.  
  23. function CollisionPE:GetMinionCollision(pStart, pEnd)
  24. self.enemyMinions:update()
  25.  
  26. local distance = GetDistance(pStart, pEnd)
  27. local prediction = TargetPredictionVIP(self.sRange, self.projSpeed, self.sDelay, self.sWidth)
  28. local mCollision = {}
  29.  
  30. if distance > self.sRange then
  31. distance = self.sRange
  32. end
  33.  
  34. local V = Vector(pEnd) - Vector(pStart)
  35. local k = V:normalized()
  36. local P = V:perpendicular2():normalized()
  37.  
  38. local t,i,u = k:unpack()
  39. local x,y,z = P:unpack()
  40.  
  41. local startLeftX = pStart.x + (x *self.sWidth)
  42. local startLeftY = pStart.y + (y *self.sWidth)
  43. local startLeftZ = pStart.z + (z *self.sWidth)
  44. local endLeftX = pStart.x + (x * self.sWidth) + (t * distance)
  45. local endLeftY = pStart.y + (y * self.sWidth) + (i * distance)
  46. local endLeftZ = pStart.z + (z * self.sWidth) + (u * distance)
  47.  
  48. local startRightX = pStart.x - (x * self.sWidth)
  49. local startRightY = pStart.y - (y * self.sWidth)
  50. local startRightZ = pStart.z - (z * self.sWidth)
  51. local endRightX = pStart.x - (x * self.sWidth) + (t * distance)
  52. local endRightY = pStart.y - (y * self.sWidth) + (i * distance)
  53. local endRightZ = pStart.z - (z * self.sWidth)+ (u * distance)
  54.  
  55. local startLeft = WorldToScreen(D3DXVECTOR3(startLeftX, startLeftY, startLeftZ))
  56. local endLeft = WorldToScreen(D3DXVECTOR3(endLeftX, endLeftY, endLeftZ))
  57. local startRight = WorldToScreen(D3DXVECTOR3(startRightX, startRightY, startRightZ))
  58. local endRight = WorldToScreen(D3DXVECTOR3(endRightX, endRightY, endRightZ))
  59.  
  60. local poly = Polygon(Point(startLeft.x, startLeft.y), Point(endLeft.x, endLeft.y), Point(startRight.x, startRight.y), Point(endRight.x, endRight.y))
  61.  
  62. for index, minion in pairs(self.enemyMinions.objects) do
  63. if minion ~= nil and minion.valid and not minion.dead then
  64. if GetDistance(pStart, minion) < distance then
  65. local pos, t, vec = prediction:GetPrediction(minion)
  66. local lineSegmentLeft = LineSegment(Point(startLeftX,startLeftZ), Point(endLeftX, endLeftZ))
  67. local lineSegmentRight = LineSegment(Point(startRightX,startRightZ), Point(endRightX, endRightZ))
  68. local toScreen, toPoint
  69. if pos ~= nil then
  70. toScreen = WorldToScreen(D3DXVECTOR3(minion.x, minion.y, minion.z))
  71. toPoint = Point(toScreen.x, toScreen.y)
  72. else
  73. toScreen = WorldToScreen(D3DXVECTOR3(minion.x, minion.y, minion.z))
  74. toPoint = Point(toScreen.x, toScreen.y)
  75. end
  76.  
  77.  
  78. if poly:contains(toPoint) then
  79. table.insert(mCollision, minion)
  80. else
  81. if pos ~= nil then
  82. distance1 = Point(pos.x, pos.z):distance(lineSegmentLeft)
  83. distance2 = Point(pos.x, pos.z):distance(lineSegmentRight)
  84. else
  85. distance1 = Point(minion.x, minion.z):distance(lineSegmentLeft)
  86. distance2 = Point(minion.x, minion.z):distance(lineSegmentRight)
  87. end
  88. if (distance1 < (getHitBoxRadius(minion)*2+10) or distance2 < (getHitBoxRadius(minion) *2+10)) then
  89. table.insert(mCollision, minion)
  90. end
  91. end
  92. end
  93. end
  94. end
  95. if #mCollision > 0 then return true, mCollision else return false, mCollision end
  96. end
  97.  
  98. function CollisionPE:GetHeroCollision(pStart, pEnd, mode)
  99. if mode == nil then mode = HERO_ENEMY end
  100. local heros = {}
  101.  
  102. for i = 1, heroManager.iCount do
  103. local hero = heroManager:GetHero(i)
  104. if (mode == HERO_ENEMY or mode == HERO_ALL) and hero.team ~= myHero.team then
  105. table.insert(heros, hero)
  106. elseif (mode == HERO_ALLY or mode == HERO_ALL) and hero.team == myHero.team and not hero.isMe then
  107. table.insert(heros, hero)
  108. end
  109. end
  110.  
  111. local distance = GetDistance(pStart, pEnd)
  112. local prediction = TargetPredictionVIP(self.sRange, self.projSpeed, self.sDelay, self.sWidth)
  113. local hCollision = {}
  114.  
  115. if distance > self.sRange then
  116. distance = self.sRange
  117. end
  118.  
  119. local V = Vector(pEnd) - Vector(pStart)
  120. local k = V:normalized()
  121. local P = V:perpendicular2():normalized()
  122.  
  123. local t,i,u = k:unpack()
  124. local x,y,z = P:unpack()
  125.  
  126. local startLeftX = pStart.x + (x *self.sWidth)
  127. local startLeftY = pStart.y + (y *self.sWidth)
  128. local startLeftZ = pStart.z + (z *self.sWidth)
  129. local endLeftX = pStart.x + (x * self.sWidth) + (t * distance)
  130. local endLeftY = pStart.y + (y * self.sWidth) + (i * distance)
  131. local endLeftZ = pStart.z + (z * self.sWidth) + (u * distance)
  132.  
  133. local startRightX = pStart.x - (x * self.sWidth)
  134. local startRightY = pStart.y - (y * self.sWidth)
  135. local startRightZ = pStart.z - (z * self.sWidth)
  136. local endRightX = pStart.x - (x * self.sWidth) + (t * distance)
  137. local endRightY = pStart.y - (y * self.sWidth) + (i * distance)
  138. local endRightZ = pStart.z - (z * self.sWidth)+ (u * distance)
  139.  
  140. local startLeft = WorldToScreen(D3DXVECTOR3(startLeftX, startLeftY, startLeftZ))
  141. local endLeft = WorldToScreen(D3DXVECTOR3(endLeftX, endLeftY, endLeftZ))
  142. local startRight = WorldToScreen(D3DXVECTOR3(startRightX, startRightY, startRightZ))
  143. local endRight = WorldToScreen(D3DXVECTOR3(endRightX, endRightY, endRightZ))
  144.  
  145. local poly = Polygon(Point(startLeft.x, startLeft.y), Point(endLeft.x, endLeft.y), Point(startRight.x, startRight.y), Point(endRight.x, endRight.y))
  146.  
  147. for index, hero in pairs(heros) do
  148. if hero ~= nil and hero.valid and not hero.dead then
  149. if GetDistance(pStart, hero) < distance then
  150. local pos, t, vec = prediction:GetPrediction(hero)
  151. local lineSegmentLeft = LineSegment(Point(startLeftX,startLeftZ), Point(endLeftX, endLeftZ))
  152. local lineSegmentRight = LineSegment(Point(startRightX,startRightZ), Point(endRightX, endRightZ))
  153. local toScreen, toPoint
  154. if pos ~= nil then
  155. toScreen = WorldToScreen(D3DXVECTOR3(pos.x, hero.y, pos.z))
  156. toPoint = Point(toScreen.x, toScreen.y)
  157. else
  158. toScreen = WorldToScreen(D3DXVECTOR3(hero.x, hero.y, hero.z))
  159. toPoint = Point(toScreen.x, toScreen.y)
  160. end
  161.  
  162.  
  163. if poly:contains(toPoint) then
  164. table.insert(hCollision, hero)
  165. else
  166. if pos ~= nil then
  167. distance1 = Point(pos.x, pos.z):distance(lineSegmentLeft)
  168. distance2 = Point(pos.x, pos.z):distance(lineSegmentRight)
  169. else
  170. distance1 = Point(hero.x, hero.z):distance(lineSegmentLeft)
  171. distance2 = Point(hero.x, hero.z):distance(lineSegmentRight)
  172. end
  173. if (distance1 < (getHitBoxRadius(hero)*2+10) or distance2 < (getHitBoxRadius(hero) *2+10)) then
  174. table.insert(hCollision, hero)
  175. end
  176. end
  177. end
  178. end
  179. end
  180. if #hCollision > 0 then return true, hCollision else return false, hCollision end
  181. end
  182.  
  183. function CollisionPE:GetCollision(pStart, pEnd)
  184. local b , minions = self:GetMinionCollision(pStart, pEnd)
  185. local t , heros = self:GetHeroCollision(pStart, pEnd, HERO_ENEMY)
  186.  
  187. if not b then return t, heros end
  188. if not t then return b, minions end
  189.  
  190. local all = {}
  191.  
  192. for index, hero in pairs(heros) do
  193. table.insert(all, hero)
  194. end
  195.  
  196. for index, minion in pairs(minions) do
  197. table.insert(all, minion)
  198. end
  199.  
  200. return true, all
  201. end
  202.  
  203.  
  204. function getHitBoxRadius(target)
  205. return GetDistance(target, target.minBBox)/2
  206. end
  207.  
  208. _G.evade = false
  209. moveBuffer = 25
  210. smoothing = 75
  211. dashrange = 0
  212.  
  213.  
  214. champions = {}
  215. champions2 = {
  216. ["Lux"] = {charName = "Lux", skillshots = {
  217. ["Light Binding"] = {name = "LightBinding", spellName = "LuxLightBinding", spellDelay = 250, projectileName = "LuxLightBinding_mis.troy", projectileSpeed = 1200, range = 1300, radius = 80, type = "line", cc = "true", collision = "false", shieldnow = "true"},
  218. ["Lux LightStrike Kugel"] = {name = "LuxLightStrikeKugel", spellName = "LuxLightStrikeKugel", spellDelay = 250, projectileName = "LuxLightstrike_mis.troy", projectileSpeed = 1400, range = 1100, radius = 275, type = "circle", cc = "false", collision = "false", shieldnow = "false"},
  219. ["Lux Malice Cannon"] = {name = "LuxMaliceCannon", spellName = "LuxMaliceCannon", spellDelay = 1375, projectileName = "LuxMaliceCannon_cas.troy", projectileSpeed = 50000, range = 3500, radius = 190, type = "line", cc = "true", collision = "false", shieldnow = "true"}}},
  220. ["Nidalee"] = {charName = "Nidalee", skillshots = {
  221. ["Javelin Toss"] = {name = "JavelinToss", spellName = "JavelinToss", spellDelay = 125, projectileName = "nidalee_javelinToss_mis.troy", projectileSpeed = 1300, range = 1500, radius = 60, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  222. ["Kennen"] = {charName = "Kennen", skillshots = {
  223. ["Thundering Shuriken"] = {name = "ThunderingShuriken", spellName = "KennenShurikenHurlMissile1", spellDelay = 180, projectileName = "kennen_ts_mis.troy", projectileSpeed = 1700, range = 1050, radius = 50, type = "line", cc = "false", collision = "true", shieldnow = "true"}}},
  224. ["Amumu"] = {charName = "Amumu", skillshots = {
  225. ["Bandage Toss"] = {name = "BandageToss", spellName = "BandageToss", spellDelay = 250, projectileName = "Bandage_beam.troy", projectileSpeed = 2000, range = 1100, radius = 80, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  226. ["Lee Sin"] = {charName = "LeeSin", skillshots = {
  227. ["Sonic Wave"] = {name = "SonicWave", spellName = "BlindMonkQOne", spellDelay = 250, projectileName = "blindMonk_Q_mis_01.troy", projectileSpeed = 1800, range = 1100, radius = 70, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  228. ["Morgana"] = {charName = "Morgana", skillshots = {
  229. ["Dark Binding Missile"] = {name = "DarkBinding", spellName = "DarkBindingMissile", spellDelay = 250, projectileName = "DarkBinding_mis.troy", projectileSpeed = 1200, range = 1300, radius = 80, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  230. ["Sejuani"] = {charName = "Sejuani", skillshots = {
  231. ["SejuaniR"] = {name = "SejuaniR", spellName = "SejuaniGlacialPrisonCast", spellDelay = 250, projectileName = "Sejuani_R_mis.troy", projectileSpeed = 1600, range = 1200, radius = 110, type="line", cc = "true", collision = "false", shieldnow = "true"}}},
  232. ["Sona"] = {charName = "Sona", skillshots = {
  233. ["Crescendo"] = {name = "Crescendo", spellName = "SonaCrescendo", spellDelay = 240, projectileName = "SonaCrescendo_mis.troy", projectileSpeed = 2400, range = 1000, radius = 160, type = "line", cc = "true", collision = "false", shieldnow = "true"}}},
  234. ["Gragas"] = {charName = "Gragas", skillshots = {
  235. ["Barrel Roll"] = {name = "BarrelRoll", spellName = "GragasBarrelRoll", spellDelay = 250, projectileName = "gragas_barrelroll_mis.troy", projectileSpeed = 1000, range = 1115, radius = 180, type = "circle", cc = "false", collision = "false", shieldnow = "false"},
  236. ["Barrel Roll Missile"] = {name = "BarrelRollMissile", spellName = "GragasBarrelRollMissile", spellDelay = 0, projectileName = "gragas_barrelroll_mis.troy", projectileSpeed = 1000, range = 1115, radius = 180, type = "circle", cc = "false", collision = "false", shieldnow = "false"}}},
  237. ["Syndra"] = {charName = "Syndra", skillshots = {
  238. ["Q"] = {name = "Q", spellName = "SyndraQ", spellDelay = 250, projectileName = "Syndra_Q_fall.troy", projectileSpeed = 500, range = 825, radius = 175, type = "circular", cc = "false", collision = "false", shieldnow = "true"},
  239. ["W"] = {name = "W", spellName = "syndrawcast", spellDelay = 250, projectileName = "Syndra_W_fall.troy", projectileSpeed = 500, range = 950, radius = 200, type = "circular", cc = "false", collision = "false", shieldnow = "true"}}},
  240. ["Malphite"] = {charName = "Malphite", skillshots = {
  241. ["UFSlash"] = {name = "UFSlash", spellName = "UFSlash", spellDelay = 0, projectileName = "UnstoppableForce_cas.troy", projectileSpeed = 550, range = 1000, radius = 300, type="circular", cc = "true", collision = "false", shieldnow = "true"}}},
  242. ["Ezreal"] = {charName = "Ezreal", skillshots = {
  243. ["Mystic Shot"] = {name = "MysticShot", spellName = "EzrealMysticShot", spellDelay = 250, projectileName = "Ezreal_mysticshot_mis.troy", projectileSpeed = 2000, range = 1200, radius = 80, type = "line", cc = "false", collision = "true", shieldnow = "true"},
  244. ["Essence Flux"] = {name = "EssenceFlux", spellName = "EzrealEssenceFlux", spellDelay = 250, projectileName = "Ezreal_essenceflux_mis.troy", projectileSpeed = 1500, range = 1050, radius = 80, type = "line", cc = "false", collision = "false", shieldnow = "true"},
  245. ["Mystic Shot (Pulsefire)"] = {name = "MysticShot", spellName = "EzrealMysticShotPulse", spellDelay = 250, projectileName = "Ezreal_mysticshot_mis.troy", projectileSpeed = 2000, range = 1200, radius = 80, type = "line", cc = "false", collision = "true", shieldnow = "true"},
  246. ["Trueshot Barrage"] = {name = "TrueshotBarrage", spellName = "EzrealTrueshotBarrage", spellDelay = 1000, projectileName = "Ezreal_TrueShot_mis.troy", projectileSpeed = 2000, range = 20000, radius = 160, type = "line", cc = "false", collision = "false", shieldnow = "true"}}},
  247. ["Ahri"] = {charName = "Ahri", skillshots = {
  248. ["Orb of Deception"] = {name = "OrbofDeception", spellName = "AhriOrbofDeception", spellDelay = 250, projectileName = "Ahri_Orb_mis.troy", projectileSpeed = 2500, range = 900, radius = 100, type = "line", cc = "false", collision = "false", shieldnow = "true"},
  249. ["Orb of Deception Back"] = {name = "OrbofDeceptionBack", spellName = "AhriOrbofDeceptionherpityderp", spellDelay = 250+360, projectileName = "Ahri_Orb_mis_02.troy", projectileSpeed = 915, range = 900, radius = 100, type = "line", cc = "false", collision = "false", shieldnow = "true"},
  250. ["Charm"] = {name = "Charm", spellName = "AhriSeduce", spellDelay = 250, projectileName = "Ahri_Charm_mis.troy", projectileSpeed = 1000, range = 1000, radius = 60, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  251. ["Olaf"] = {charName = "Olaf", skillshots = {
  252. ["Undertow"] = {name = "Undertow", spellName = "OlafAxeThrow", spellDelay = 250, projectileName = "olaf_axe_mis.troy", projectileSpeed = 1600, range = 1000, radius = 90, type = "line", cc = "true", collision = "false", shieldnow = "true"}}},
  253. ["Leona"] = {charName = "Leona", skillshots = {
  254. ["Zenith Blade"] = {name = "LeonaZenithBlade", spellName = "LeonaZenithBlade", spellDelay = 250, projectileName = "Leona_ZenithBlade_mis.troy", projectileSpeed = 2000, range = 950, radius = 110, type = "line", cc = "true", collision = "false", shieldnow = "true"},
  255. ["Leona Solar Flare"] = {name = "LeonaSolarFlare", spellName = "LeonaSolarFlare", spellDelay = 250, projectileName = "Leona_SolarFlare_cas.troy", projectileSpeed = 1500, range = 1200, radius = 300, type = "circular", cc = "true", collision = "false", shieldnow = "true"}}},
  256. ["Karthus"] = {charName = "Karthus", skillshots = {
  257. ["Lay Waste"] = {name = "LayWaste", spellName = "KarthusLayWasteA", spellDelay = 250, projectileName = "Karthus_Base_Q_Point_red.troy", projectileSpeed = 20, range = 875, radius = 450, type = "circular", cc = "false", collision = "false", shieldnow = "true"}}},
  258. ["Chogath"] = {charName = "Chogath", skillshots = {
  259. ["Rupture"] = {name = "Rupture", spellName = "Rupture", spellDelay = 0, projectileName = "rupture_cas_01_red_team.troy", projectileSpeed = 950, range = 950, radius = 250, type = "circular", cc = "true", collision = "false", shieldnow = "true"}}},
  260. ["Blitzcrank"] = {charName = "Blitzcrank", skillshots = {
  261. ["Rocket Grab"] = {name = "RocketGrab", spellName = "RocketGrabMissile", spellDelay = 250, projectileName = "FistGrab_mis.troy", projectileSpeed = 1800, range = 1050, radius = 70, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  262. ["Anivia"] = {charName = "Anivia", skillshots = {
  263. ["Flash Frost"] = {name = "FlashFrost", spellName = "FlashFrostSpell", spellDelay = 250, projectileName = "cryo_FlashFrost_mis.troy", projectileSpeed = 850, range = 1100, radius = 110, type = "line", cc = "true", collision = "false", shieldnow = "true"}}},
  264. ["Zyra"] = {charName = "Zyra", skillshots = {
  265. ["Grasping Roots"] = {name = "GraspingRoots", spellName = "ZyraGraspingRoots", spellDelay = 250, projectileName = "Zyra_E_sequence_impact.troy", projectileSpeed = 1150, range = 1150, radius = 70, type = "line", cc = "true", collision = "false", shieldnow = "true"},
  266. ["Zyra Passive Death"] = {name = "ZyraPassive", spellName = "zyrapassivedeathmanager", spellDelay = 500, projectileName = "zyra_passive_plant_mis.troy", projectileSpeed = 2000, range = 1474, radius = 60, type = "line", cc = "false", collision = "false", shieldnow = "true"},
  267. ["Deadly Bloom"] = {name = "DeadlyBloom", spellName = "ZyraQFissure", spellDelay = 1000, projectileName = "Zyra_Q_cas.troy", projectileSpeed = 0, range = 800, radius = 250, type = "circular", cc = "false", collision = "false", shieldnow = "true"}}},
  268. ["Nautilus"] = {charName = "Nautilus", skillshots = {
  269. ["Dredge Line"] = {name = "DredgeLine", spellName = "NautilusAnchorDrag", spellDelay = 250, projectileName = "Nautilus_Q_mis.troy", projectileSpeed = 2000, range = 1080, radius = 80, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  270. ["Caitlyn"] = {charName = "Caitlyn", skillshots = {
  271. ["Piltover Peacemaker"] = {name = "PiltoverPeacemaker", spellName = "CaitlynPiltoverPeacemaker", spellDelay = 625, projectileName = "caitlyn_Q_mis.troy", projectileSpeed = 2200, range = 1300, radius = 90, type = "line", cc = "false", collision = "false", shieldnow = "true"},
  272. ["Caitlyn Entrapment"] = {name = "CaitlynEntrapment", spellName = "CaitlynEntrapment", spellDelay = 150, projectileName = "caitlyn_entrapment_mis.troy", projectileSpeed = 2000, range = 950, radius = 80, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  273. ["Mundo"] = {charName = "DrMundo", skillshots = {
  274. ["Infected Cleaver"] = {name = "InfectedCleaver", spellName = "InfectedCleaverMissile", spellDelay = 250, projectileName = "dr_mundo_infected_cleaver_mis.troy", projectileSpeed = 2000, range = 1050, radius = 75, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  275. ["Brand"] = {charName = "Brand", skillshots = {
  276. ["BrandBlaze"] = {name = "BrandBlaze", spellName = "BrandBlaze", spellDelay = 250, projectileName = "BrandBlaze_mis.troy", projectileSpeed = 1600, range = 1100, radius = 80, type = "line", cc = "true", collision = "true", shieldnow = "true"},
  277. ["Pillar of Flame"] = {name = "PillarofFlame", spellName = "BrandFissure", spellDelay = 250, projectileName = "BrandPOF_tar_green.troy", projectileSpeed = 900, range = 1100, radius = 240, type = "circular", cc = "false", collision = "false", shieldnow = "true"}}},
  278. ["Corki"] = {charName = "Corki", skillshots = {
  279. ["Missile Barrage"] = {name = "MissileBarrage", spellName = "MissileBarrage", spellDelay = 250, projectileName = "corki_MissleBarrage_mis.troy", projectileSpeed = 2000, range = 1300, radius = 40, type = "line", cc = "false", collision = "true", shieldnow = "true"},
  280. ["Missile Barrage big"] = {name = "MissileBarragebig", spellName = "MissileBarrage!", spellDelay = 250, projectileName = "Corki_MissleBarrage_DD_mis.troy", projectileSpeed = 2000, range = 1300, radius = 40, type = "line", cc = "false", collision = "true", shieldnow = "true"}}},
  281. ["TwistedFate"] = {charName = "TwistedFate", skillshots = {
  282. ["Loaded Dice"] = {name = "LoadedDice", spellName = "WildCards", spellDelay = 250, projectileName = "Roulette_mis.troy", projectileSpeed = 1000, range = 1450, radius = 40, type = "line", cc = "false", collision = "false", shieldnow = "true"}}},
  283. ["Swain"] = {charName = "Swain", skillshots = {
  284. ["Nevermove"] = {name = "Nevermove", spellName = "SwainShadowGrasp", spellDelay = 250, projectileName = "swain_shadowGrasp_transform.troy", projectileSpeed = 1000, range = 900, radius = 180, type = "circular", cc = "true", collision = "false", shieldnow = "true"}}},
  285. ["Cassiopeia"] = {charName = "Cassiopeia", skillshots = {
  286. ["Noxious Blast"] = {name = "NoxiousBlast", spellName = "CassiopeiaNoxiousBlast", spellDelay = 250, projectileName = "CassNoxiousSnakePlane_green.troy", projectileSpeed = 500, range = 850, radius = 130, type = "circular", cc = "false", collision = "false", shieldnow = "true"}}},
  287. ["Sivir"] = {charName = "Sivir", skillshots = {
  288. ["Boomerang Blade"] = {name = "BoomerangBlade", spellName = "SivirQ", spellDelay = 250, projectileName = "Sivir_Base_Q_mis.troy", projectileSpeed = 1350, range = 1150, radius = 101, type = "line", cc = "false", collision = "false", shieldnow = "true"}}},
  289. ["Ashe"] = {charName = "Ashe", skillshots = {
  290. ["Enchanted Arrow"] = {name = "EnchantedArrow", spellName = "EnchantedCrystalArrow", spellDelay = 250, projectileName = "Ashe_Base_R_mis.troy", projectileSpeed = 1600, range = 25000, radius = 120, type = "line", cc = "true", collision = "false", shieldnow = "true"}}},
  291. ["KogMaw"] = {charName = "KogMaw", skillshots = {
  292. ["Living Artillery"] = {name = "LivingArtillery", spellName = "KogMawLivingArtillery", spellDelay = 250, projectileName = "KogMawLivingArtillery_mis.troy", projectileSpeed = 1050, range = 2200, radius = 225, type = "circular", cc = "false", collision = "false", shieldnow = "true"}}},
  293. ["Khazix"] = {charName = "Khazix", skillshots = {
  294. ["KhazixW"] = {name = "KhazixW", spellName = "KhazixW", spellDelay = 250, projectileName = "Khazix_W_mis_enhanced.troy", projectileSpeed = 1700, range = 1025, radius = 70, type = "line", cc = "true", collision = "true", shieldnow = "true"},
  295. ["khazixwlong"] = {name = "khazixwlong", spellName = "khazixwlong", spellDelay = 250, projectileName = "Khazix_W_mis_enhanced.troy", projectileSpeed = 1700, range = 1025, radius = 70, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  296. ["Zed"] = {charName = "Zed", skillshots = {
  297. ["ZedShuriken"] = {name = "ZedShuriken", spellName = "ZedShuriken", spellDelay = 250, projectileName = "Zed_Q_Mis.troy", projectileSpeed = 1700, range = 925, radius = 50, type = "line", cc = "false", collision = "false", shieldnow = "true"}}},
  298. ["Leblanc"] = {charName = "Leblanc", skillshots = {
  299. ["Ethereal Chains"] = {name = "EtherealChains", spellName = "LeblancSoulShackle", spellDelay = 250, projectileName = "leBlanc_shackle_mis.troy", projectileSpeed = 1600, range = 960, radius = 70, type = "line", cc = "true", collision = "true", shieldnow = "true"},
  300. ["Ethereal Chains R"] = {name = "EtherealChainsR", spellName = "LeblancSoulShackleM", spellDelay = 250, projectileName = "leBlanc_shackle_mis_ult.troy", projectileSpeed = 1600, range = 960, radius = 70, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  301. ["Draven"] = {charName = "Draven", skillshots = {
  302. ["Stand Aside"] = {name = "StandAside", spellName = "DravenDoubleShot", spellDelay = 250, projectileName = "Draven_E_mis.troy", projectileSpeed = 1400, range = 1100, radius = 130, type = "line", cc = "true", collision = "false", shieldnow = "true"},
  303. ["DravenR"] = {name = "DravenR", spellName = "DravenRCast", spellDelay = 500, projectileName = "Draven_R_mis!.troy", projectileSpeed = 2000, range = 25000, radius = 160, type = "line", cc = "false", collision = "false", shieldnow = "true"}}},
  304. ["Elise"] = {charName = "Elise", skillshots = {
  305. ["Cocoon"] = {name = "Cocoon", spellName = "EliseHumanE", spellDelay = 250, projectileName = "Elise_human_E_mis.troy", projectileSpeed = 1450, range = 1100, radius = 70, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  306. ["Lulu"] = {charName = "Lulu", skillshots = {
  307. ["LuluQ"] = {name = "LuluQ", spellName = "LuluQ", spellDelay = 250, projectileName = "Lulu_Q_Mis.troy", projectileSpeed = 1450, range = 1000, radius = 50, type = "line", cc = "true", collision = "false", shieldnow = "true"}}},
  308. ["Thresh"] = {charName = "Thresh", skillshots = {
  309. ["ThreshQ"] = {name = "ThreshQ", spellName = "ThreshQ", spellDelay = 500, projectileName = "Thresh_Q_whip_beam.troy", projectileSpeed = 1900, range = 1100, radius = 65, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  310. ["Shen"] = {charName = "Shen", skillshots = {
  311. ["ShadowDash"] = {name = "ShadowDash", spellName = "ShenShadowDash", spellDelay = 0, projectileName = "shen_shadowDash_mis.troy", projectileSpeed = 3000, range = 575, radius = 50, type = "line", cc = "true", collision = "false", shieldnow = "true"}}},
  312. ["Quinn"] = {charName = "Quinn", skillshots = {
  313. ["QuinnQ"] = {name = "QuinnQ", spellName = "QuinnQ", spellDelay = 250, projectileName = "Quinn_Q_missile.troy", projectileSpeed = 1550, range = 1050, radius = 80, type = "line", cc = "false", collision = "true", shieldnow = "true"}}},
  314. ["Veigar"] = {charName = "Veigar", skillshots = {
  315. ["Dark Matter"] = {name = "VeigarDarkMatter", spellName = "VeigarDarkMatter", spellDelay = 250, projectileName = "!", projectileSpeed = 900, range = 900, radius = 225, type = "circular", cc = "false", collision = "false", shieldnow = "true"}}},
  316. ["Jayce"] = {charName = "Jayce", skillshots = {
  317. ["JayceShockBlast"] = {name = "JayceShockBlast", spellName = "jayceshockblast", spellDelay = 250, projectileName = "JayceOrbLightning.troy", projectileSpeed = 1450, range = 1050, radius = 70, type = "line", cc = "false", collision = "true", shieldnow = "true"},
  318. ["JayceShockBlastCharged"] = {name = "JayceShockBlastCharged", spellName = "jayceshockblast", spellDelay = 250, projectileName = "JayceOrbLightningCharged.troy", projectileSpeed = 2350, range = 1600, radius = 70, type = "line", cc = "false", collision = "true", shieldnow = "true"}}},
  319. ["Nami"] = {charName = "Nami", skillshots = {
  320. ["NamiQ"] = {name = "NamiQ", spellName = "NamiQ", spellDelay = 250, projectileName = "Nami_Q_mis.troy", projectileSpeed = 1500, range = 1625, radius = 225, type = "circle", cc = "true", collision = "false", shieldnow = "true"}}},
  321. ["Fizz"] = {charName = "Fizz", skillshots = {
  322. ["Fizz Ultimate"] = {name = "FizzULT", spellName = "FizzMarinerDoom", spellDelay = 250, projectileName = "Fizz_UltimateMissile.troy", projectileSpeed = 1350, range = 1275, radius = 80, type = "line", cc = "true", collision = "false", shieldnow = "true"}}},
  323. ["Varus"] = {charName = "Varus", skillshots = {
  324. ["Varus Q Missile"] = {name = "VarusQMissile", spellName = "somerandomspellnamethatwillnevergetcalled", spellDelay = 0, projectileName = "VarusQ_mis.troy", projectileSpeed = 1900, range = 1600, radius = 70, type = "line", cc = "false", collision = "false", shieldnow = "true"},
  325. ["VarusR"] = {name = "VarusR", spellName = "VarusR", spellDelay = 250, projectileName = "VarusRMissile.troy", projectileSpeed = 1950, range = 1250, radius = 100, type = "line", cc = "true", collision = "false", shieldnow = "true"}}},
  326. ["Karma"] = {charName = "Karma", skillshots = {
  327. ["KarmaQ"] = {name = "KarmaQ", spellName = "KarmaQ", spellDelay = 250, projectileName = "TEMP_KarmaQMis.troy", projectileSpeed = 1700, range = 1050, radius = 90, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  328. ["Aatrox"] = {charName = "Aatrox", skillshots = {
  329. ["Blade of Torment"] = {name = "BladeofTorment", spellName = "AatroxE", spellDelay = 250, projectileName = "AatroxBladeofTorment_mis.troy", projectileSpeed = 1200, range = 1075, radius = 75, type = "line", cc = "true", collision = "false", shieldnow = "true"},
  330. ["AatroxQ"] = {name = "AatroxQ", spellName = "AatroxQ", spellDelay = 250, projectileName = "AatroxQ.troy", projectileSpeed = 450, range = 650, radius = 145, type = "circle", cc = "true", collision = "false", shieldnow = "true"}}},
  331. ["Xerath"] = {charName = "Xerath", skillshots = {
  332. ["Xerath Arcanopulse"] = {name = "xeratharcanopulse21", spellName = "xeratharcanopulse2", spellDelay = 400, projectileName = "hiu", projectileSpeed = 25000, range = 0, radius = 100, type = "line", cc = "false", collision = "false", shieldnow = "true"},
  333. ["XerathArcaneBarrage2"] = {name = "XerathArcaneBarrage2", spellName = "XerathArcaneBarrage2", spellDelay = 500, projectileName = "Xerath_Base_W_cas.troy", projectileSpeed = 0, range = 1100, radius = 325, type = "circular", cc = "true", collision = "false", shieldnow = "true"},
  334. ["XerathMageSpear"] = {name = "XerathMageSpear", spellName = "XerathMageSpear", spellDelay = 250, projectileName = "Xerath_Base_E_mis.troy", projectileSpeed = 1600, range = 1050, radius = 125, type = "line", cc = "true", collision = "true", shieldnow = "true"},
  335. ["xerathlocuspulse"] = {name = "xerathlocuspulse", spellName = "xerathlocuspulse", spellDelay = 250, projectileName = "Xerath_Base_R_mis.troy", projectileSpeed = 300, range = 5600, radius = 265, type = "circular", cc = "false", collision = "false", shieldnow = "true"}}},
  336. ["Lucian"] = {charName = "Lucian", skillshots = {
  337. ["LucianQ"] = {name = "LucianQ", spellName = "LucianQ", spellDelay = 350, projectileName = "Lucian_Q_laser.troy", projectileSpeed = 25000, range = 570*2, radius = 65, type = "line", cc = "false", collision = "false", shieldnow = "true"},
  338. ["LucianW"] = {name = "LucianW", spellName = "LucianW", spellDelay = 300, projectileName = "Lucian_W_mis.troy", projectileSpeed = 1600, range = 1000, radius = 80, type = "line", cc = "false", collision = "false", shieldnow = "true"}}},
  339. ["Viktor"] = {charName = "Viktor", skillshots = {
  340. ["ViktorDeathRay1"] = {name = "ViktorDeathRay1", spellName = "ViktorDeathRay!", spellDelay = 500, projectileName = "Viktor_DeathRay_Fix_Mis.troy", projectileSpeed = 780, range = 700, radius = 80, type = "line", cc = "false", collision = "false", shieldnow = "true"},
  341. ["ViktorDeathRay2"] = {name = "ViktorDeathRay2", spellName = "ViktorDeathRay!", spellDelay = 500, projectileName = "Viktor_DeathRay_Fix_Mis_Augmented.troy", projectileSpeed = 780, range = 700, radius = 80, type = "line", cc = "false", collision = "false", shieldnow = "true"}}},
  342. ["Rumble"] = {charName = "Rumble", skillshots = {
  343. ["RumbleGrenade"] = {name = "RumbleGrenade", spellName = "RumbleGrenade", spellDelay = 250, projectileName = "rumble_taze_mis.troy", projectileSpeed = 2000, range = 950, radius = 90, type = "line", cc = "true", collision = "true", shieldnow = "true"}}},
  344. ["Nocturne"] = {charName = "Nocturne", skillshots = {
  345. ["NocturneDuskbringer"] = {name = "NocturneDuskbringer", spellName = "NocturneDuskbringer", spellDelay = 250, projectileName = "NocturneDuskbringer_mis.troy", projectileSpeed = 1400, range = 1125, radius = 60, type = "line", cc = "false", collision = "false", shieldnow = "true"}}},
  346. ["Yasuo"] = {charName = "Yasuo", skillshots = {
  347. ["yasuoq3"] = {name = "yasuoq3", spellName = "yasuoq3w", spellDelay = 250, projectileName = "Yasuo_Q_wind_mis.troy", projectileSpeed = 1200, range = 1000, radius = 80, type = "line", cc = "true", collision = "false", shieldnow = "true"},
  348. ["yasuoq1"] = {name = "yasuoq1", spellName = "yasuoQW", spellDelay = 250, projectileName = "Yasuo_Q_WindStrike.troy", projectileSpeed = 25000, range = 475, radius = 40, type = "line", cc = "false", collision = "false", shieldnow = "true"},
  349. ["yasuoq2"] = {name = "yasuoq2", spellName = "yasuoq2w", spellDelay = 250, projectileName = "Yasuo_Q_windstrike_02.troy", projectileSpeed = 25000, range = 475, radius = 40, type = "line", cc = "false", collision = "false", shieldnow = "true"}}},
  350. ["Orianna"] = {charName = "Orianna", skillshots = {
  351. ["OrianaIzunaCommand"] = {name = "OrianaIzunaCommand", spellName = "OrianaIzunaCommand", spellDelay = 0, projectileName = "Oriana_Ghost_mis.troy", projectileSpeed = 1300, range = 800, radius = 80, type = "line", cc = "true", collision = "false", shieldnow = "true"},
  352. ["OrianaDetonateCommand"] = {name = "OrianaDetonateCommand", spellName = "OrianaDetonateCommand", spellDelay = 100, projectileName = "Oriana_Shockwave_nova.troy", projectileSpeed = 400, range = 2000, radius = 400, type = "circular", cc = "true", collision = "false", shieldnow = "true"}}},
  353. ["Ziggs"] = {charName = "Ziggs", skillshots = {
  354. ["ZiggsQ"] = {name = "ZiggsQ", spellName = "ZiggsQ", spellDelay = 250, projectileName = "ZiggsQ.troy", projectileSpeed = 1700, range = 1400, radius = 155, type = "line", cc = "false", collision = "true", shieldnow = "true"}}},
  355. ["Annie"] = {charName = "Annie", skillshots = {
  356. ["AnnieR"] = {name = "AnnieR", spellName = "InfernalGuardian", spellDelay = 100, projectileName = "nothing", projectileSpeed = 0, range = 600, radius = 300, type = "circular", cc = "true", collision = "false", shieldnow = "true"}}},
  357. ["Galio"] = {charName = "Galio", skillshots = {
  358. ["GalioResoluteSmite"] = {name = "GalioResoluteSmite", spellName = "GalioResoluteSmite", spellDelay = 250, projectileName = "galio_concussiveBlast_mis.troy", projectileSpeed = 850, range = 2000, radius = 200, type = "circle", cc = "true", collision = "false", shieldnow = "true"}}},
  359. ["Jinx"] = {charName = "Jinx", skillshots = {
  360. ["W"] = {name = "Zap", spellName = "JinxW", spellDelay = 600, projectileName = "Jinx_W_Beam.troy", projectileSpeed = 3300, range = 1450, radius = 70, type = "line", cc = "true", collision = "true", shieldnow = "true"},
  361. ["R"] = {name = "SuperMegaDeathRocket", spellName = "JinxRWrapper", spellDelay = 600, projectileName = "Jinx_R_Mis.troy", projectileSpeed = 1700, range = 20000, radius = 120, type = "line", cc = "false", collision = "false", shieldnow = "true"}}},
  362. ["Velkoz"] = {charName = "Velkoz", skillshots = {
  363. ["PlasmaFission"] = {name = "PlasmaFission", spellName = "VelKozQ", spellDelay = 250, projectileName = "Velkoz_Base_Q_mis.troy", projectileSpeed = 1200, range = 1050, radius = 120, type = "line", cc = "true", collision = "true", shieldnow = "true"},
  364. ["Plasma Fission Split"] = {name = "VelKozQSplit", spellName = "VelKozQ", spellDelay = 250, projectileName = "Velkoz_Base_Q_Split_mis.troy", projectileSpeed = 1200, range = 1050, radius = 120, type = "line", cc = "true", collision = "true", shieldnow = "true"},
  365. ["Void Rift"] = {name = "VelkozW", spellName = "VelkozW", spellDelay = 250, projectileName = "Velkoz_Base_W_Turret.troy", projectileSpeed = 1200, range = 1050, radius = 125, type = "line", cc = "false", collision = "false", shieldnow = "true"},
  366. ["Tectonic Disruption"] = {name = "VelkozE", spellName = "VelkozE", spellDelay = 250, projectileName = "DarkBinding_mis.troy", projectileSpeed = 1200, range = 800, radius = 225, type = "circular", cc = "true", collision = "false", shieldnow = "true"}}},
  367. ["Heimerdinger"] = {charName = "Heimerdinger", skillshots = {
  368. --["Micro-Rockets"] = {name = "MicroRockets", spellName = "HeimerdingerW1", spellDelay = 500, projectileName = "Heimerdinger_Base_w_Mis.troy", projectileSpeed = 902, range = 1325, radius = 100, type = "line", cc = "false", collision = "true", shieldnow = "true"},
  369. --["Storm Grenade"] = {name = "StormGrenade", spellName = "HeimerdingerE", spellDelay = 250, projectileName = "Heimerdinger_Base_E_Mis.troy", projectileSpeed = 2500, range = 970, radius = 180, type = "circular", cc = "true", collision = "false", shieldnow = "true"},
  370. --["Micro-RocketsUlt"] = {name = "MicroRocketsUlt", spellName = "HeimerdingerW2", spellDelay = 500, projectileName = "Heimerdinger_Base_W_Mis_Ult.troy", projectileSpeed = 902, range = 1325, radius = 100, type = "line", cc = "false", collision = "true", shieldnow = "true"},
  371. --["Storm Grenade"] = {name = "StormGrenade", spellName = "HeimerdingerE2", spellDelay = 250, projectileName = "Heimerdinger_Base_E_Mis_Ult.troy", projectileSpeed = 2500, range = 970, radius = 180, type = "line", cc = "true", collision = "false", shieldnow = "true"},
  372. }},
  373. ["Malzahar"] = {charName = "Malzahar", skillshots = {
  374. ["Call Of The Void"] = {name = "CallOfTheVoid", spellName ="AlZaharCalloftheVoid1", spellDelay = 0, projectileName = "AlzaharCallofthevoid_mis.troy", projectileSpeed = 1600, range = 450, radius = 100, type = "line", cc = "true", collision = "false", shieldnow = "true"}}} ,
  375. ["Janna"] = {charName = "Janna", skillshots = {
  376. ["Howling Gale"] = {name = "HowlingGale", spellName ="HowlingGale", spellDelay = 0, projectileName = "HowlingGale_mis.troy", projectileSpeed = 500, range = 0, radius = 100, type = "line", cc = "true", collision = "false", shieldnow = "true"}}},
  377. ["Braum"] = {charName = "Braum", skillshots = {
  378. ["Winters Bite"] = {name = "WintersBite", spellName = "BraumQ", spellDelay = 225, projectileName = "Braum_Base_Q_mis.troy", projectileSpeed = 1600, range = 1000, radius = 100, type = "line", cc = "false", collision = "true", shieldnow = "true"},
  379. ["Glacial Fissure"] = {name = "GlacialFissure", spellName = "BraumRWrapper", spellDelay = 500, projectileName = "Braum_Base_R_mis.troy", projectileSpeed = 1250, range = 1250, radius = 100, type = "line", cc = "false", collision = "true", shieldnow = "true"}}},
  380. ["Ekko"] = {charName = "Ekko", skillshots = {
  381. ["Timewinder"] = {name = "Timewinder", spellName = "EkkoQ", spellDelay = 250, projectileName = "Ekko_Base_Q_Aoe_Dilation.troy", projectileSpeed = 1650, range = 950, radius = 60, type = "line", cc = "false", collision = "true", shieldnow = "true"},
  382. ["Parallel Convergence"] = {name = "Parallel Convergence", spellName = "EkkoW", spellDelay = 3750, projectileName = "Ekko_Base_W_Branch_Timeline.troy", projectileSpeed = 1650, radius = 373, type = "circular", cc = "false", collision = "false", shieldnow = "false"},
  383. }}
  384. }
  385.  
  386. champions3 = {
  387. ["Aatrox"] = "AatroxW AatroxW2",
  388. ["Amumu"] = "AuraOfDespair",
  389. ["Anivia"] = "GlacialStorm",
  390. ["Annie"] = "MoltenShield",
  391. ["Ashe"] = "FrostShot",
  392. ["Blitzcrank"] = "Overdrive",
  393. ["Chogath"] = "VorpalSpikes",
  394. ["Corki"] = "GGun",
  395. ["Darius"] = "DariusCleave",
  396. ["DrMundo"] = "BurningAgony Masochism",
  397. ["Draven"] = "DravenSpinning DravenFury",
  398. ["Elise"] = "EliseSpiderW EliseRSpider EliseRHuman",
  399. ["Evelynn"] = "EvelynnQ EvelynnW",
  400. ["Fiora"] = "FioraRiposte FioraFlurry",
  401. ["Fizz"] = "FizzSeastonePassive",
  402. ["Galio"] = "GalioBulwark",
  403. ["Garen"] = "GarenQ GarenW GarenE",
  404. ["Gragas"] = "GragasBarrelRollToggle",
  405. ["Hecarim"] = "HecarimRapidSlash HecarimW HecarimRamp",
  406. ["Heimerdinger"] = "HeimerdingerR",
  407. ["Irelia"] = "IreliaHitenStyle IreliaTranscendentBlades",
  408. ["Janna"] = "HowlingGale SowTheWind EyeOfTheStorm",
  409. ["JarvanIV"] = "JarvanIVGoldenAegis JarvanIVDemacianStandard",
  410. ["Jax"] = "JaxEmpowerTwo JaxCounterStrike JaxRelentlessAssault",
  411. ["Jayce"] = "JayceStaticField JayceHyperCharge JayceAccelerationGate JayceStanceGtH JayceStanceHtG",
  412. ["Jinx"] = "JinxQ JinxE",
  413. ["Karma"] = "KarmaSolKimShield KarmaMantra",
  414. ["Karthus"] = "Defile",
  415. ["Kassadin"] = "NetherBlade",
  416. ["Katarina"] = "KatarinaW",
  417. ["Kayle"] = "JudicatorDivineBlessing JudicatorRighteousFury JudicatorIntervention",
  418. ["Kennen"] = "KennenLightningRush",
  419. ["KhaZix"] = "KhaZixR",
  420. ["KogMaw"] = "KogMawBioArcaneBarrage",
  421. ["Leona"] = "LeonaShieldOfDaybreak LeonaSolarBarrier",
  422. ["Lissandra"] = "LissandraW",
  423. ["Lucian"] = "LucianR",
  424. ["Lulu"] = "LuluW LuluE LuluR",
  425. ["Lux"] = "LuxLightStrikeToggle",
  426. ["Malphite"] = "Obduracy",
  427. ["Malzahar"] = "AlZaharNullZone",
  428. ["Maokai"] = "MaokaiDrain3Toggle",
  429. ["MasterYi"] = "WujuStyle Highlander",
  430. ["MissFortune"] = "MissFortuneViciousStrikes",
  431. ["Mordekaiser"] = "MordekaiserCreepingDeathCast",
  432. ["Morgana"] = "BlackShield",
  433. ["Nami"] = "NamiE",
  434. ["Nautilus"] = "NautilusPiercingGaze",
  435. ["Nidalee"] = "Takedown PrimalSurge AspectOfTheCougar",
  436. ["Nocturne"] = "NocturneShroudOfDarkness NocturneParanoia",
  437. ["Nunu"] = "BloodBoil",
  438. ["Olaf"] = "OlafFrenziedStrikes OlafRagnarok",
  439. ["Orianna"] = "OrianalzunaCommand OrianaDissonanceCommand OrianaRedactCommand OrianaDetonateCommand",
  440. ["Poppy"] = "PoppyDevastatingBlow PoppyParagonOfDemacia",
  441. ["Quinn"] = "QuinnW QuinnR QuinnValorQ QuinnRFinale",
  442. ["Rammus"] = "PowerBall DefensiveBallCurl Tremors2",
  443. ["Renekton"] = "RenektonPreExecute",
  444. ["Rengar"] = "RengarW RengarR",
  445. ["Rumble"] = "RumbleFlameThrower RumbleShield",
  446. ["Ryze"] = "DesperatePower",
  447. ["Sejuani"] = "SejuaniNorthernWinds",
  448. ["Shaco"] = "HallucinateGuide",
  449. ["Shen"] = "ShenFeint",
  450. ["Shyvana"] = "ShyvanaDoubleAttack ShyvanaImmolationAura",
  451. ["Singed"] = "PoisonTrail InsanityPotion",
  452. ["Sion"] = "DeathsCaressFull Enrage",
  453. ["Sivir"] = "SivirW SivirE SivirR",
  454. ["Skarner"] = "SkarnerExoskeleton",
  455. ["Sona"] = "SonaHymOfValor SonaAiraOfPerseverance SonaSongOfDiscord",
  456. ["Swain"] = "SwainMetamorphism",
  457. ["Syndra"] = "SyndraQ SyndraW SyndraR",
  458. ["Talon"] = "TalonNoxianDiplomacy",
  459. ["Teemo"] = "MoveQuick",
  460. ["Tristana"] = "RapidFire",
  461. ["Trundle"] = "TrundleTrollSmash",
  462. ["Tryndamere"] = "Bloodlust UndyingRage",
  463. ["Twisted Fate"] = "PickACard BlueCardLock RedCardLock GoldCardLock Destiny",
  464. ["Twitch"] = "HideInShadows FullAutomatic",
  465. ["Udyr"] = "UdyrTigerStance UdyrTurtleStance UdyrBearStance UdyrPhoenixStance",
  466. ["Urgot"] = "UrgotTerrorCapacitorActive2",
  467. ["Vayne"] = "VayneInquisition",
  468. ["Vi"] = "ViE",
  469. ["Vladimir"] = "VladimirSanguinePool",
  470. ["Volibear"] = "VolibearQ VolibearW",
  471. ["Warwick"] = "HuntersCall BloodScent",
  472. ["Wukong"] = "WukongQ WukongW WukongR",
  473. ["Xin Zhao"] = "XenZhaoComboTarget ZenZhaoBattleCry",
  474. ["Zac"] = "ZacW",
  475. ["Zed"] = "ZedPBAOEDummy",
  476. ["Ziggs"] = "ZiggsWToggle",
  477. ["Zilean"] = "Rewind TimeWarp",
  478. ["Zyra"] = "ZyraSeed"
  479. }
  480. hitboxTable = {
  481. ['Yasuo'] = 65,
  482. ['VelKoz'] = 65,
  483. ['Xerath'] = 65,
  484. ['Kassadin'] = 65,
  485. ['Rengar'] = 65,
  486. ['Thresh'] = 55.0,
  487. ['Ziggs'] = 55.0,
  488. ['KogMaw'] = 65,
  489. ['Katarina'] = 65,
  490. ['Riven'] = 65,
  491. ['Ashe'] = 65,
  492. ['Soraka'] = 65,
  493. ['Jinx'] = 65,
  494. ['JarvanIV'] = 65,
  495. ['Tryndamere'] = 65,
  496. ['Singed'] = 65,
  497. ['Diana'] = 65,
  498. ['Ahri'] = 65,
  499. ['Lulu'] = 65,
  500. ['MasterYi'] = 65,
  501. ['Lissandra'] = 65,
  502. ['Draven'] = 65,
  503. ['FiddleSticks'] = 65,
  504. ['Maokai'] = 80.0,
  505. ['Sivir'] = 65,
  506. ['Corki'] = 65,
  507. ['Janna'] = 65,
  508. ['Nasus'] = 80.0,
  509. ['LeeSin'] = 65,
  510. ['Jax'] = 65,
  511. ['Blitzcrank'] = 80.0,
  512. ['Shen'] = 65,
  513. ['Nocturne'] = 65,
  514. ['Sona'] = 65,
  515. ['Caitlyn'] = 65,
  516. ['Trundle'] = 65,
  517. ['Malphite'] = 80.0,
  518. ['Mordekaiser'] = 80.0,
  519. ['Vi'] = 50,
  520. ['Renekton'] = 80.0,
  521. ['Anivia'] = 65,
  522. ['Fizz'] = 65,
  523. ['Heimerdinger'] = 55.0,
  524. ['Evelynn'] = 65,
  525. ['Rumble'] = 80.0,
  526. ['Leblanc'] = 65,
  527. ['Darius'] = 80.0,
  528. ['Viktor'] = 65,
  529. ['XinZhao'] = 65,
  530. ['Orianna'] = 65,
  531. ['Vladimir'] = 65,
  532. ['Nidalee'] = 65,
  533. ['Syndra'] = 65,
  534. ['Zac'] = 80.0,
  535. ['Olaf'] = 65,
  536. ['Veigar'] = 55.0,
  537. ['Twitch'] = 65,
  538. ['Alistar'] = 80.0,
  539. ['Akali'] = 65,
  540. ['Urgot'] = 80.0,
  541. ['Leona'] = 65,
  542. ['Talon'] = 65,
  543. ['Karma'] = 65,
  544. ['Jayce'] = 65,
  545. ['Galio'] = 80.0,
  546. ['Shaco'] = 65,
  547. ['Taric'] = 65,
  548. ['TwistedFate'] = 65,
  549. ['Varus'] = 65,
  550. ['Garen'] = 65,
  551. ['Swain'] = 65,
  552. ['Vayne'] = 65,
  553. ['Fiora'] = 65,
  554. ['Quinn'] = 65,
  555. ['Kayle'] = 65,
  556. ['Brand'] = 65,
  557. ['Teemo'] = 55.0,
  558. ['Amumu'] = 55.0,
  559. ['Annie'] = 55.0,
  560. ['Elise'] = 65,
  561. ['Nami'] = 65,
  562. ['Poppy'] = 55.0,
  563. ['AniviaEgg'] = 65,
  564. ['Tristana'] = 55.0,
  565. ['Graves'] = 65,
  566. ['Morgana'] = 65,
  567. ['Gragas'] = 80.0,
  568. ['MissFortune'] = 65,
  569. ['Warwick'] = 65,
  570. ['Cassiopeia'] = 65,
  571. ['DrMundo'] = 80.0,
  572. ['Volibear'] = 80.0,
  573. ['Irelia'] = 65,
  574. ['Lucian'] = 65,
  575. ['Yorick'] = 80.0,
  576. ['Udyr'] = 65,
  577. ['MonkeyKing'] = 65,
  578. ['Kennen'] = 55.0,
  579. ['Nunu'] = 65,
  580. ['Ryze'] = 65,
  581. ['Zed'] = 65,
  582. ['Nautilus'] = 80.0,
  583. ['Gangplank'] = 65,
  584. ['shopevo'] = 65,
  585. ['Lux'] = 65,
  586. ['Sejuani'] = 80.0,
  587. ['Ezreal'] = 65,
  588. ['Khazix'] = 65,
  589. ['Sion'] = 80.0,
  590. ['Aatrox'] = 65,
  591. ['Hecarim'] = 80.0,
  592. ['Pantheon'] = 65,
  593. ['Shyvana'] = 50.0,
  594. ['Zyra'] = 65,
  595. ['Karthus'] = 65,
  596. ['Rammus'] = 65,
  597. ['Zilean'] = 65,
  598. ['Chogath'] = 80.0,
  599. ['Malzahar'] = 65,
  600. ['KogMawDead'] = 65,
  601. ['QuinnValor'] = 65,
  602. ['Nidalee_Cougar'] = 65
  603. }
  604.  
  605. blockedSpell = {
  606. ['Yasuo'] = {Slot = _W, Delay = 0.25, SpellName = "Wind Wall"},
  607. ['Braum'] = {Slot = _E, Delay = 0.25, SpellName = "Unbreakable"},
  608. }
  609. WardJumpSpell = {
  610. ['Katarina'] = {Slot = _E, SpellName = "Shunpo"},
  611. ['Jax'] = {Slot = _Q, SpellName = "Leap Strike"},
  612. ['LeeSin'] = {Slot = _W, SpellName = "Safeguard"},
  613. }
  614.  
  615. wrotedisclaimer = false
  616. enemies = {}
  617. nAllies = 0
  618. allies = {}
  619. XerathQTickCount = 0
  620. nEnemies = 0
  621. evading = false
  622. allowCustomMovement = true
  623. captureMovements = true
  624. lastMovement = {}
  625. detectedSkillshots = {}
  626. nSkillshots = 0
  627. CastingSpell = false
  628. HowlingGale = false
  629. lastset = 0
  630. trueWidth = {}
  631. trueSpeed = {}
  632. trueDelay = {}
  633. haveflash = false
  634. flashSlot = nil
  635. flashready = false
  636. lastspell = "Q"
  637. useflash = false
  638. shieldslot = _E
  639. shieldtick = nil
  640. blockedtick = nil
  641. blockPos = nil
  642. alreadywritten = false
  643. thatfile = SCRIPT_PATH.."movementblock.txt"
  644. currentbuffer = 0
  645. bufferset = false
  646. lastnonattack = 0
  647.  
  648. function getTarget(targetId)
  649. if targetId ~= 0 and targetId ~= nil then
  650. return objManager:GetObjectByNetworkId(targetId)
  651. end
  652. return nil
  653. end
  654.  
  655. function spellStopMovement(champName, champSkill, selfCast)
  656. if GoodEvadeConfig.allowMove == false then
  657. return false
  658. end
  659. local champSkill2
  660. if(champSkill == 0) then
  661. champSkill2 = GetMyHero():GetSpellData(0).name
  662. if GoodEvadeConfig.stopCCMoves and (GetMyHero().charName == "Varus" or GetMyHero().charName == "Vi" or GetMyHero().charName == "Xerath") then
  663. return true
  664. else
  665. return false
  666. end
  667. elseif(champSkill == 1) then
  668. champSkill2 = GetMyHero():GetSpellData(1).name
  669. if(GetMyHero().charName) == "LeeSin" and selfCast then
  670. return true
  671. end
  672. elseif(champSkill == 2) then
  673. champSkill2 = GetMyHero():GetSpellData(2).name
  674. elseif(champSkill == 3) then
  675. champSkill2 = GetMyHero():GetSpellData(3).name
  676. else
  677. champSkill2 = "null"
  678. end
  679. if(champions3[champName] ~= nil) then
  680. return string.find(string.lower(champions3[champName]), string.lower(champSkill2)) ~= nil
  681. end
  682. return false
  683. end
  684.  
  685. function getLastMovementDestination()
  686. mousePosition = Point2(mousePos.x, mousePos.z)
  687. if VIP_USER then
  688. if lastMovement.type == 3 then
  689. heroPosition = Point2(myHero.x, myHero.z)
  690. mousePosition = Point2(mousePos.x, mousePos.z)
  691.  
  692. target = getTarget(lastMovement.targetId)
  693. if _isValidTarget(target) then
  694. targetPosition = Point2(target.x, target.z)
  695.  
  696. local attackRange = (myHero.range + GetDistance(myHero.minBBox, myHero.maxBBox) / 2 + GetDistance(target.minBBox, target.maxBBox) / 2)
  697.  
  698. if attackRange <= heroPosition:distance(targetPosition) then
  699. return targetPosition + (heroPosition - targetPosition):normalized() * attackRange
  700. else
  701. return mousePosition
  702. end
  703. else
  704. return mousePosition
  705. end
  706. elseif lastMovement.type == 7 then
  707. heroPosition = Point2(myHero.x, myHero.z)
  708. mousePosition = Point2(mousePos.x, mousePos.z)
  709. target = getTarget(lastMovement.targetId)
  710. if _isValidTarget(target) then
  711. targetPosition = Point2(target.x, target.z)
  712.  
  713. local castRange = myHero:GetSpellData(lastMovement.spellId).range
  714.  
  715. if castRange <= heroPosition:distance(targetPosition) then
  716. return targetPosition + (heroPosition - targetPosition):normalized() * castRange
  717. else
  718. return mousePosition
  719. end
  720. else
  721. local castRange = myHero:GetSpellData(lastMovement.spellId).range
  722.  
  723. if castRange <= heroPosition:distance(lastMovement.destination) then
  724. return lastMovement.destination + (heroPosition - lastMovement.destination):normalized() * castRange
  725. else
  726. return mousePosition
  727. end
  728. end
  729. else
  730. return lastMovement.destination
  731. end
  732. else return lastMovement.destination
  733. end
  734. end
  735. function CheckBall(obj)
  736. if obj == nil or obj.name == nil then return end
  737.  
  738. if (obj.name:find("Oriana_Ghost_mis") or obj.name:find("Oriana_Ghost_mis_protect") ) then
  739. ball = nil
  740. return
  741. end
  742.  
  743. if obj.name:find("yomu_ring_red") then
  744. ball = obj
  745. return
  746. end
  747.  
  748. if obj.name:find("Oriana_Ghost_bind") then
  749. for i, target in pairs(enemies) do
  750. if GetDistance(target, obj) < 40 then
  751. ball = target
  752. end
  753. end
  754. end
  755. end
  756.  
  757. --FreakingGoodEvade
  758. local versionmessage = "<font color=\"#81BEF7\" >Changelog: Updated for 5.18 patch. Changed scripter</font>"
  759.  
  760. function OnLoad()
  761. ToUpdate = {}
  762. ToUpdate.Host = "raw.githubusercontent.com"
  763. ToUpdate.VersionPath = "/kej1191/anonym/master/GoodEvade/GoodEvade.version"
  764. ToUpdate.ScriptPath = "/kej1191/anonym/master/GoodEvade/GoodEvade.lua"
  765. ToUpdate.SavePath = SCRIPT_PATH .. GetCurrentEnv().FILE_NAME
  766. ToUpdate.CallbackUpdate = function(NewVersion, OldVersion) print("<font color=\"#81BEF7\"><b>GoodEvade </b></font> <font color=\"#6699ff\">Updated to "..NewVersion..". </b></font>") end
  767. ToUpdate.CallbackNoUpdate = function(OldVersion) print("<font color=\"#81BEF7\"><b>GoodEvade </b></font> <font color=\"#6699ff\">You have lastest version ("..OldVersion..")</b></font>") end
  768. ToUpdate.CallbackNewVersion = function(NewVersion) print("<font color=\"#81BEF7\"><b>GoodEvade </b></font> <font color=\"#6699ff\">New Version found ("..NewVersion.."). Please wait until its downloaded</b></font>") end
  769. ToUpdate.CallbackError = function(NewVersion) print("<font color=\"#81BEF7\"><b>GoodEvade </b></font> <font color=\"#6699ff\">Error while Downloading. Please try again.</b></font>") end
  770. ScriptUpdate(Version, true, ToUpdate.Host, ToUpdate.VersionPath, ToUpdate.ScriptPath, ToUpdate.SavePath, ToUpdate.CallbackUpdate,ToUpdate.CallbackNoUpdate, ToUpdate.CallbackNewVersion,ToUpdate.CallbackError)
  771.  
  772. hitboxSize = hitboxTable[GetMyHero().charName]
  773.  
  774. if hitboxSize == nil then
  775. hitboxSize = 80.0
  776. end
  777.  
  778. ball = nil
  779. GoodEvadeConfig = scriptConfig("Freaking Good Evade", "Freaking Good Evade")
  780. GoodEvadeConfig:addParam("evadeBuffer", "Increase Skillshot width by", SCRIPT_PARAM_SLICE, 15, 0, 50, 0)
  781. GoodEvadeConfig:addParam("fowdelay", "Delay for skillshots from FOW", SCRIPT_PARAM_SLICE, 1, 1, 20, 0)
  782. GoodEvadeConfig:addParam("dodgeEnabled", "Dodge Skillshots", SCRIPT_PARAM_ONKEYTOGGLE, false, 192)
  783. GoodEvadeConfig:addParam("dodgeCConly", "Dodge CC only spells", SCRIPT_PARAM_ONKEYDOWN, false, 32)
  784. GoodEvadeConfig:addParam("dodgeCConly2", "Toggle dodge CC only spells", SCRIPT_PARAM_ONKEYTOGGLE, false, 77)
  785. GoodEvadeConfig:addParam("dashPercent", "Use skill to dodge below what % HP", SCRIPT_PARAM_SLICE, 100, 0, 100)
  786. GoodEvadeConfig:addParam("resetdodge", "Reset Dodge", SCRIPT_PARAM_ONKEYDOWN, false, 17)
  787. GoodEvadeConfig:addParam("allowMove", "Allow use of 0 cast time spells", SCRIPT_PARAM_ONOFF, true)
  788. GoodEvadeConfig:addParam("stopCCMoves", "Use 0 cast time spells with self cc", SCRIPT_PARAM_ONOFF, true)
  789. GoodEvadeConfig:addParam("freemovementblock", "Free Users Movement Block", SCRIPT_PARAM_ONOFF, false)
  790. GoodEvadeConfig:addSubMenu("Evading Setting", "Skill")
  791. GoodEvadeConfig.Skill:addSubMenu("Dodge Setting", "Dodge")
  792. GoodEvadeConfig.Skill.Dodge:addParam("linerOn", "Dodge Liner Spell", SCRIPT_PARAM_ONOFF, true)
  793. GoodEvadeConfig.Skill.Dodge:addParam("circularOn", "Dodge Circular Spell", SCRIPT_PARAM_ONOFF, true)
  794.  
  795. if blockedSpell[myHero.charName] ~= nil then
  796. GoodEvadeConfig.Skill:addSubMenu("Blocking Spell", "Block")
  797. GoodEvadeConfig.Skill.Block:addParam("blocking", "block with "..tostring(blockedSpell[myHero.charName].SpellName), SCRIPT_PARAM_ONOFF, true)
  798. end
  799. if WardJumpSpell[myHero.charName] ~= nil then
  800. GoodEvadeConfig.Skill:addSubMenu("WardJumpSpell", "WardJ")
  801. GoodEvadeConfig.Skill.WardJ:addParam("wardj", "block with "..tostring(WardJumpSpell[myHero.charName].SpellName), SCRIPT_PARAM_ONOFF, true)
  802. end
  803.  
  804. GoodEvadeConfig.Skill:addParam("usedashes", "Dash to dodge spells", SCRIPT_PARAM_ONOFF, true)
  805. GoodEvadeConfig.Skill:addParam("usejumps", "WardJump to dodge spells", SCRIPT_PARAM_ONOFF, true)
  806. GoodEvadeConfig.Skill:addParam("dashMouse", "Always dash toward your mouse", SCRIPT_PARAM_ONOFF, true)
  807. GoodEvadeConfig.Skill:addParam("lineallways", "Always try to dodge line skillshots", SCRIPT_PARAM_ONOFF, true)
  808. GoodEvadeConfig.Skill:addParam("useSummonerFlash", "Flash to dodge dangerous spells", SCRIPT_PARAM_ONOFF, true)
  809.  
  810. GoodEvadeConfig:addSubMenu("Drawing Setting","Draw")
  811. GoodEvadeConfig.Draw:addParam("drawEnabled", "Draw Skillshots", SCRIPT_PARAM_ONOFF, true)
  812. GoodEvadeConfig.Draw:addParam("oldDrawing", "Use old drawing", SCRIPT_PARAM_ONOFF, false)
  813.  
  814. GoodEvadeConfig:permaShow("dodgeEnabled")
  815. for i = 1, heroManager.iCount do
  816. local hero = heroManager:GetHero(i)
  817. if hero.team ~= myHero.team then
  818. for i, skillShotChampion in pairs(champions2) do
  819. if skillShotChampion.charName == hero.charName then
  820. table.insert(champions, skillShotChampion)
  821. end
  822. end
  823. end
  824. end
  825. GoodEvadeSkillshotConfig = scriptConfig("FGE skillshots", "FGE skillshots config")
  826. for i, skillShotChampion in pairs(champions) do
  827. for i, skillshot in pairs(skillShotChampion.skillshots) do
  828. name = tostring(skillshot.name)
  829. name2 = tostring(skillshot.name)
  830. if skillshot.cc == "true" then
  831. GoodEvadeSkillshotConfig:addParam(name, "Dodge "..name2, SCRIPT_PARAM_SLICE, 2, 0, 2, 0)
  832. elseif skillshot.cc == "false" then GoodEvadeSkillshotConfig:addParam(name, "Dodge "..name2, SCRIPT_PARAM_SLICE, 1, 0, 2, 0)
  833. elseif skillshot.cc == "never" then GoodEvadeSkillshotConfig:addParam(name, "Dodge "..name2, SCRIPT_PARAM_SLICE, 0, 0, 2, 0)
  834. end
  835. end
  836. end
  837.  
  838. stopEvade()
  839.  
  840. isSivir = false
  841. isNocturne = false
  842. isVayne = false
  843. isGraves = false
  844. isEzreal = false
  845. isLeblanc = false
  846. isRiven = false
  847. isFizz = false
  848. isShen = false
  849. isShaco = false
  850. isRenekton = false
  851. isTristana = false
  852. isTryndamere = false
  853. isCorki = false
  854. isLucian = false
  855. isMorgana = false
  856. isYasuo = false
  857. isBraum = false
  858. isLeeSin = false
  859. isKatarina = false
  860.  
  861. if myHero.charName == "Sivir" then isSivir = true
  862. elseif myHero.charName == "Nocturne" then isNocturne = true
  863. elseif myHero.charName == "Vayne" then isVayne = true
  864. elseif myHero.charName == "Graves" then isGraves = true
  865. elseif myHero.charName == "Ezreal" then isEzreal = true
  866. elseif myHero.charName == "Caitlyn" then isCaitlyn = true
  867. elseif myHero.charName == "Leblanc" then isLeblanc = true
  868. elseif myHero.charName == "Riven" then isRiven = true
  869. elseif myHero.charName == "Fizz" then isFizz = true
  870. elseif myHero.charName == "Shen" then isShen = true
  871. elseif myHero.charName == "Shaco" then isShaco = true
  872. elseif myHero.charName == "Renekton" then isRenekton = true
  873. elseif myHero.charName == "Tristana" then isTristana = true
  874. elseif myHero.charName == "Tryndamere" then isTryndamere = true
  875. elseif myHero.charName == "Corki" then isCorki = true
  876. elseif myHero.charName == "Morgana" then isMorgana = true
  877. elseif myHero.charName == "Yasuo" then isYasuo = true
  878. elseif myHero.charName == "Braum" then isBraum = true
  879. elseif myHero.charName == "LeeSin" then isLeeSin = true
  880. elseif myHero.charName == "Katarina" then isKatarina = true
  881. elseif myHero.charName == "Jax" then isJax = true
  882. elseif myHero.charName == "Lucian" then isLucian = true end
  883.  
  884. if myHero:GetSpellData(SUMMONER_1).name:find("SummonerFlash") then
  885. haveflash = true
  886. flashSlot = SUMMONER_1
  887. elseif myHero:GetSpellData(SUMMONER_2).name:find("SummonerFlash") then
  888. flashSlot = SUMMONER_2
  889. haveflash = true
  890. end
  891.  
  892. lastMovement = {
  893. destination = Point2(myHero.x, myHero.z),
  894. moveCommand = Point2(myHero.x, myHero.z),
  895. type = 2,
  896. targetId = nil,
  897. spellId = nil,
  898. approachedPoint = nil
  899. }
  900.  
  901. for i = 1, heroManager.iCount do
  902. local hero = heroManager:GetHero(i)
  903. if hero.team ~= myHero.team then
  904. table.insert(enemies, hero)
  905. elseif hero.team == myHero.team and hero.nEnemies ~= myHero.networkID then
  906. table.insert(allies, hero)
  907. end
  908. end
  909. isOrianna = false
  910. for i, enemy in pairs(enemies) do
  911. if enemy.charName == "Orianna" then
  912. isOrianna = true
  913. end
  914. end
  915. if #enemies == 5 then
  916. for i, skillShotChampion in pairs(champions) do
  917. if skillShotChampion.charName ~= enemies[1].charName and skillShotChampion.charName ~= enemies[2].charName and skillShotChampion.charName ~= enemies[3].charName
  918. and skillShotChampion.charName ~= enemies[4].charName and skillShotChampion.charName ~= enemies[5].charName then
  919. champions[i] = nil
  920. end
  921. end
  922. end
  923.  
  924. player:RemoveCollision()
  925. player:SetVisionRadius(1700)
  926.  
  927. GoodEvadeConfig.dodgeEnabled = true
  928. currentbuffer = GoodEvadeConfig.evadeBuffer
  929. PrintChat(versionmessage)
  930. if AutoUpdate then
  931. DelayAction(Update, 3)
  932. end
  933. end
  934.  
  935. function getSideOfLine(linePoint1, linePoint2, point)
  936. if not point then return 0 end
  937. result = ((linePoint2.x - linePoint1.x) * (point.y - linePoint1.y) - (linePoint2.y - linePoint1.y) * (point.x - linePoint1.x))
  938. if result < 0 then
  939. return -1
  940. elseif result > 0 then
  941. return 1
  942. else
  943. return 0
  944. end
  945. end
  946.  
  947. colstartpos = nil
  948. colendpos = nil
  949.  
  950. function dodgeSkillshot(skillshot)
  951. if GoodEvadeConfig.dodgeEnabled and not myHero.dead and CastingSpell == false then
  952. if GoodEvadeSkillshotConfig[tostring(skillshot.skillshot.name)] == 2 or (GoodEvadeSkillshotConfig[tostring(skillshot.skillshot.name)] == 1 and nEnemies <= 2 and not (GoodEvadeConfig.dodgeCConly == skillshot.skillshot.cc or GoodEvadeConfig.dodgeCConly2 == skillshot.skillshot.cc)) then
  953. if skillshot.skillshot.type == "line" then
  954. if skillshot.skillshot.collision == "true" and VIP_USER then
  955. heropos = Point2(myHero.x, myHero.z)
  956. endposition = skillshot.startPosition + (skillshot.endPosition - skillshot.startPosition):normalized() * (heropos:distance(skillshot.startPosition))
  957. colstartpos = Vector(skillshot.startPosition.x, myHero.y, skillshot.startPosition.y)
  958. colendpos = Vector(endposition.x, myHero.y, endposition.y)
  959. collisionshit = CollisionPE(skillshot.skillshot.range, skillshot.skillshot.projectileSpeed, skillshot.skillshot.spellDelay, skillshot.skillshot.radius)
  960. if collisionshit:GetMinionCollision(colstartpos, colendpos) then return end
  961. end
  962. dodgeLineShot(skillshot)
  963. else
  964. dodgeCircularShot(skillshot)
  965. end
  966. end
  967. end
  968. end
  969.  
  970. function dodgeCircularShot(skillshot)
  971. skillshot.evading = true
  972. alreadydodged = false
  973. heroPosition = Point2(myHero.x, myHero.z)
  974.  
  975. moveableDistance = myHero.ms * math.max(skillshot.endTick - GetTickCount() - GetLatency()/2, 0) / 1000
  976. evadeRadius = skillshot.skillshot.radius + hitboxSize / 2 + GoodEvadeConfig.evadeBuffer + moveBuffer
  977.  
  978. safeTarget = skillshot.endPosition + (heroPosition - skillshot.endPosition):normalized() * evadeRadius
  979.  
  980. if isreallydangerous(skillshot) then
  981. if mainCircularskillshot1(skillshot, heroPosition, moveableDistance, evadeRadius, safeTarget) then
  982. alreadydodged = true
  983. elseif dodgeDangerousCircle1(skillshot) then
  984. alreadydodged = true
  985. elseif dodgeDangerousCircle2(skillshot, safeTarget) then
  986. alreadydodged = true
  987. elseif dodgeDangerousCircle3(skillshot, safeTarget) then
  988. alreadydodged = true
  989. end
  990. end
  991.  
  992. if not alreadydodged then
  993. if mainCircularskillshot1(skillshot, heroPosition, moveableDistance, evadeRadius, safeTarget) then
  994. alreadydodged = true
  995. elseif mainCircularskillshot2(skillshot) then
  996. alreadydodged = true
  997. elseif mainCircularskillshot3(skillshot, heroPosition) then
  998. alreadydodged = true
  999. elseif mainCircularskillshot4(skillshot, heroPosition, moveableDistance, evadeRadius, safeTarget) then
  1000. alreadydodged = true
  1001. elseif mainCircularskillshot5(skillshot, safeTarget) then
  1002. alreadydodged = true
  1003. end
  1004. end
  1005. end
  1006.  
  1007. function haveShield()
  1008. if isSivir and myHero:CanUseSpell(_E) == READY then
  1009. return true
  1010. elseif isNocturne and myHero:CanUseSpell(_W) == READY then
  1011. return true
  1012. end
  1013. return false
  1014. end
  1015.  
  1016. function haveBlocked()
  1017. if isYasuo and myHero:CanUseSpell(_W) == READY then
  1018. return true
  1019. elseif isBraum and myHero:CanUseSpell(_E) == READY then
  1020. return true
  1021. end
  1022. return false
  1023. end
  1024.  
  1025. function Blocking(Pos)
  1026. if isYasuo and GoodEvadeConfig.Skill.Block.blocking then
  1027. local myVec = Vector(myHero.x-Pos.x, 0 , myHero.z - Pos.z):normalized()
  1028. local pos = WorldToScreen(D3DXVECTOR3(myHero.x - (myVec.x*(10 + 10)), myVec.y*(10 + 10), myHero.z - (myVec.z*(10 + 10))))
  1029. CastSpell(_W, Pos.x, Pos.z)
  1030. return true
  1031. elseif isBraum and GoodEvadeConfig.Skill.Block.blocking then
  1032. CastSpell(_E, Pos.x, Pos.z)
  1033. return true
  1034. end
  1035. return false
  1036. end
  1037.  
  1038. function FlashTo(x, y)
  1039.  
  1040. if GoodEvadeConfig.Skill.dashMouse then
  1041.  
  1042. local evadePos = Point2(mousePos.x, mousePos.z)
  1043. local myPos = Point2(myHero.x, myHero.z)
  1044. local ourdistance = evadePos:distance(myPos)
  1045. local dashPos = myPos - (myPos - evadePos):normalized() * 400
  1046.  
  1047. x = dashPos.x
  1048. y = dashPos.y
  1049. end
  1050.  
  1051. CastSpell(flashSlot, x, y)
  1052. end
  1053.  
  1054.  
  1055. function dodgeLineShot(skillshot)
  1056. alreadydodged = false
  1057. heroPosition = Point2(myHero.x, myHero.z)
  1058. local evadeTo1
  1059. local evadeTo2
  1060. skillshot.evading = true
  1061. skillshotLine = Line2(skillshot.startPosition, skillshot.endPosition)
  1062. distanceFromSkillshotPath = skillshotLine:distance(heroPosition)
  1063. blockPos = skillshot.startposition
  1064. evadeDistance = skillshot.skillshot.radius + hitboxSize / 2 + GoodEvadeConfig.evadeBuffer + moveBuffer
  1065. normalVector = Point2(skillshot.directionVector.y, -skillshot.directionVector.x):normalized()
  1066. nessecaryMoveWidth = evadeDistance - distanceFromSkillshotPath
  1067. evadeTo1 = heroPosition + normalVector * nessecaryMoveWidth
  1068. evadeTo2 = heroPosition - normalVector * nessecaryMoveWidth
  1069.  
  1070. if isreallydangerous(skillshot) then
  1071. if lineSkillshot1(skillshot, heroPosition, skillshotLine, distanceFromSkillshotPath, evadeDistance, normalVector, nessecaryMoveWidth, evadeTo1, evadeTo2)
  1072. then alreadydodged = true
  1073. elseif dodgeDangerousLine1(skillshot) then
  1074. alreadydodged = true
  1075. elseif dodgeDangerousLine2(skillshot, evadeTo1, evadeTo2) then
  1076. alreadydodged = true
  1077. end
  1078. end
  1079.  
  1080. if not alreadydodged then
  1081. if lineSkillshot1(skillshot, heroPosition, skillshotLine, distanceFromSkillshotPath, evadeDistance, normalVector, nessecaryMoveWidth, evadeTo1, evadeTo2) then --
  1082. alreadydodged = true
  1083. elseif Blocking(skillshot.owner)
  1084. then alreadydodged = true
  1085. elseif lineSkillshot2(skillshot)
  1086. then alreadydodged = true
  1087. elseif lineSkillshot3(skillshot, evadeTo1, evadeTo2)
  1088. then alreadydodged = true
  1089. elseif lineSkillshot4(skillshot, evadeTo1, evadeTo2)
  1090. then alreadydodged = true
  1091. end
  1092. end
  1093.  
  1094. end
  1095.  
  1096. function _isDangerSkillshot(skillshot)
  1097. if skillshot.skillshot.name == "LeonaZenithBlade"
  1098. or skillshot.skillshot.name == "EnchantedArrow"
  1099. or skillshot.skillshot.name == "LuxMaliceCannon"
  1100. or skillshot.skillshot.name == "SejuaniR"
  1101. or skillshot.skillshot.name == "Crescendo"
  1102. or skillshot.skillshot.name == "TrueshotBarrage"
  1103. or skillshot.skillshot.name == "RocketGrab"
  1104. or skillshot.skillshot.name == "DredgeLine"
  1105. or skillshot.skillshot.name == "ShadowDash"
  1106. or skillshot.skillshot.name == "FizzULT"
  1107. or skillshot.skillshot.name == "VarusR"
  1108. or skillshot.skillshot.name == "SuperMegaDeathRocket"
  1109. or skillshot.skillshot.name == "UFSlash"
  1110. or skillshot.skillshot.name == "LeonaSolarFlare"
  1111. or skillshot.skillshot.name == "AnnieR"
  1112. or skillshot.skillshot.name == "OrianaDetonateCommand"
  1113. then
  1114. return true
  1115. else
  1116. return false
  1117. end
  1118. end
  1119.  
  1120. function isreallydangerous(skillshot)
  1121. if skillshot.skillshot.name == "UFSlash"
  1122. or skillshot.skillshot.name == "Crescendo"
  1123. or skillshot.skillshot.name == "FizzULT"
  1124. or skillshot.skillshot.name == "EnchantedArrow"
  1125. or skillshot.skillshot.name == "AnnieR"
  1126. or skillshot.skillshot.name == "OrianaDetonateCommand"
  1127. or skillshot.skillshot.name == "LeonaSolarFlare"
  1128. or skillshot.skillshot.name == "VarusR"
  1129. or skillshot.skillshot.name == "EnchantedArrow"
  1130. or skillshot.skillshot.name == "SejuaniR"
  1131. then return true
  1132. else
  1133. return false
  1134. end
  1135. end
  1136.  
  1137. function InsideTheWall(evadeTestPoint)
  1138. local heroPosition = Point2(myHero.x, myHero.z)
  1139. local dist = evadeTestPoint:distance(heroPosition)
  1140. local interval = 50
  1141. local nChecks = math.ceil((dist+50)/50)
  1142.  
  1143. if evadeTestPoint.x == 0 or evadeTestPoint.y == 0 then
  1144. return true
  1145. end
  1146. for k=1, nChecks, 1 do
  1147. local checksPos = evadeTestPoint + (evadeTestPoint - heroPosition):normalized()*(interval*k)
  1148. if IsWall(D3DXVECTOR3(checksPos.x, myHero.y, checksPos.y)) then
  1149. return true
  1150. end
  1151. end
  1152. if IsWall(D3DXVECTOR3(evadeTestPoint.x + 20, myHero.y, evadeTestPoint.y + 20)) then return true end
  1153. if IsWall(D3DXVECTOR3(evadeTestPoint.x + 20, myHero.y, evadeTestPoint.y - 20)) then return true end
  1154. if IsWall(D3DXVECTOR3(evadeTestPoint.x - 20, myHero.y, evadeTestPoint.y - 20)) then return true end
  1155. if IsWall(D3DXVECTOR3(evadeTestPoint.x - 20, myHero.y, evadeTestPoint.y + 20)) then return true end
  1156.  
  1157. return false
  1158. end
  1159.  
  1160. function findBestDirection(skillshot, referencePoint, possiblePoints)
  1161. if not skillshot then return closestPoint end
  1162. closestPoint = nil
  1163. closestDistance = nil
  1164. side1 = getSideOfLine(skillshot.startPosition, skillshot.endPosition, Point2(myHero.x, myHero.z))
  1165. for i, point in pairs(possiblePoints) do
  1166. if point ~= nil and skillshot ~= nil then
  1167. side2 = getSideOfLine(skillshot.startPosition, skillshot.endPosition, point)
  1168. distToSkillshot = Line2(skillshot.startPosition, skillshot.endPosition):distance(point)
  1169. mindistSkillshot = skillshot.skillshot.radius + hitboxSize / 2 + GoodEvadeConfig.evadeBuffer
  1170. distance = point:distance(referencePoint)
  1171. if (closestDistance == nil or distance <= closestDistance) and not InsideTheWall(point)
  1172. and distToSkillshot > mindistSkillshot and (side1 == side2 or side1 == 0) then
  1173. closestDistance = distance
  1174. closestPoint = point
  1175. end
  1176. end
  1177. end
  1178.  
  1179. return closestPoint
  1180. end
  1181.  
  1182. function calculateLongitudinalApproachLength(skillshot, d)
  1183. v1 = skillshot.skillshot.projectileSpeed
  1184. v2 = myHero.ms
  1185. longitudinalDistance = math.max(skillshotPosition(skillshot, GetTickCount()):distance(getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, Point2(myHero.x, myHero.z))) - hitboxSize / 2 - skillshot.skillshot.radius, 0) + v1 * math.max(skillshot.startTick - GetTickCount(), 0) / 1000
  1186.  
  1187. preResult = -d^2 * v1^4 + d^2 * v2^2 * v1^2 + longitudinalDistance^2 * v2^2 * v1^2
  1188. if preResult >= 0 then
  1189. result = (math.sqrt(preResult) - longitudinalDistance * v2^2) / (v1^2 - v2^2)
  1190. if result >= 0 then
  1191. return result
  1192. end
  1193. end
  1194.  
  1195. return -1
  1196. end
  1197.  
  1198. function calculateLongitudinalRetreatLength(skillshot, d)
  1199. v1 = skillshot.skillshot.projectileSpeed
  1200. v2 = myHero.ms
  1201. longitudinalDistance = math.max(skillshotPosition(skillshot, GetTickCount()):distance(getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, Point2(myHero.x, myHero.z))) - hitboxSize / 2 - skillshot.skillshot.radius, 0) + v1 * math.max(skillshot.startTick - GetTickCount(), 0) / 1000
  1202.  
  1203. preResult = -d^2 * v1^4 + d^2 * v2^2 * v1^2 + longitudinalDistance^2 * v2^2 * v1^2
  1204. if preResult >= 0 then
  1205. result = (math.sqrt(preResult) + longitudinalDistance * v2^2) / (v1^2 - v2^2)
  1206. if result >= 0 then
  1207. return result
  1208. end
  1209. end
  1210.  
  1211. return -1
  1212. end
  1213.  
  1214. function inDangerousArea(skillshot, coordinate)
  1215. if skillshot.skillshot.type == "line" then
  1216. return inRange(skillshot, coordinate)
  1217. and not skillshotHasPassed(skillshot, coordinate)
  1218. and Line2(skillshot.startPosition, skillshot.endPosition):distance(coordinate) < (skillshot.skillshot.radius + hitboxSize / 2 + GoodEvadeConfig.evadeBuffer)
  1219. and coordinate:distance(skillshot.startPosition + skillshot.directionVector) <= coordinate:distance(skillshot.startPosition - skillshot.directionVector)
  1220. else
  1221. return coordinate:distance(skillshot.endPosition) <= skillshot.skillshot.radius + hitboxSize / 2 + GoodEvadeConfig.evadeBuffer
  1222. end
  1223. end
  1224.  
  1225. function inRange(skillshot, coordinate)
  1226. return getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, coordinate):distance(skillshot.startPosition) <= skillshot.skillshot.range
  1227. end
  1228.  
  1229. function OnCreateObj(object)
  1230. if object ~= nil and object.type == "obj_GeneralParticleEmmiter" then
  1231. for i, skillShotChampion in pairs(champions) do
  1232. for i, skillshot in pairs(skillShotChampion.skillshots) do
  1233. if skillshot.projectileName == object.name then
  1234. for i, detectedSkillshot in pairs(detectedSkillshots) do
  1235. if detectedSkillshot.skillshot.projectileName == skillshot.projectileName then
  1236. return
  1237. end
  1238. end
  1239. for i = 1, heroManager.iCount, 1 do
  1240. currentHero = heroManager:GetHero(i)
  1241. if currentHero.team == myHero.team and skillShotChampion.charName == currentHero.charName then
  1242. return
  1243. end
  1244. end
  1245.  
  1246. if skillshot.type == "line" then
  1247. if(skillshotToAdd ~= nil) then
  1248. skillshotToAdd2 = {object = object, startPosition = object.startPos, endPosition = object.endPos, directionVector = nil, startTick = GetTickCount(), endTick = GetTickCount() + skillshot.range/skillshot.projectileSpeed*1000, skillshot = skillshot, evading = false, drawit = true, alreadydashed = false}
  1249. else
  1250. skillshotToAdd = {object = object, startPosition = object.startPos, endPosition = object.startPos, directionVector = nil, startTick = GetTickCount(), endTick = GetTickCount() + skillshot.range/skillshot.projectileSpeed*1000, skillshot = skillshot, evading = false, drawit = true, alreadydashed = false}
  1251. end
  1252. elseif skillshot.type == "circular" then
  1253. endPosition = Point2(object.x, object.z)
  1254. startPosition = Point2(object.x, object.z)
  1255. table.insert(detectedSkillshots, {startPosition = startPosition, endPosition = endPosition,
  1256. directionVector = (endPosition - startPosition):normalized(), startTick = GetTickCount() + skillshot.spellDelay,
  1257. endTick = GetTickCount() + skillshot.spellDelay + skillshot.projectileSpeed, skillshot = skillshot, evading = false, drawit = false, alreadydashed = false})
  1258. end
  1259. end
  1260. return
  1261. end
  1262. end
  1263. end
  1264. end
  1265. function OnAnimation(unit, animationName)
  1266. if CastingSpell == true then
  1267. if unit.isMe and (animationName == "Idle1" or animationName == "Run") then CastingSpell = false end
  1268. end
  1269. end
  1270.  
  1271. function OnProcessSpell(unit, spell)
  1272. if unit.isMe and myHero.charName == "MasterYi" and spell.name == myHero:GetSpellData(_W).name then
  1273. CastingSpell = true
  1274. elseif unit.isMe and myHero.charName == "Nunu" and spell.name == myHero:GetSpellData(_R).name then
  1275. CastingSpell = true
  1276. elseif unit.isMe and myHero.charName == "MissFortune" and spell.name == myHero:GetSpellData(_R).name then
  1277. CastingSpell = true
  1278. elseif unit.isMe and myHero.charName == "Malzahar" and spell.name == myHero:GetSpellData(_R).name then
  1279. CastingSpell = true
  1280. elseif unit.isMe and myHero.charName == "Katarina" and spell.name == myHero:GetSpellData(_R).name then
  1281. CastingSpell = true
  1282. elseif unit.isMe and myHero.charName == "Janna" and spell.name == myHero:GetSpellData(_R).name then
  1283. CastingSpell = true
  1284. elseif unit.isMe and myHero.charName == "Galio" and spell.name == myHero:GetSpellData(_R).name then
  1285. CastingSpell = true
  1286. elseif unit.isMe and myHero.charName == "FiddleSticks" and spell.name == myHero:GetSpellData(_W).name then
  1287. CastingSpell = true
  1288. elseif unit.isMe and myHero.charName == "FiddleSticks" and spell.name == myHero:GetSpellData(_R).name then
  1289. CastingSpell = true
  1290. end
  1291. if unit.isMe and isLeblanc then
  1292. if spell.name == myHero:GetSpellData(_Q).name then lastspell = "Q"
  1293. elseif spell.name == myHero:GetSpellData(_W).name then lastspell = "W"
  1294. elseif spell.name == myHero:GetSpellData(_E).name then lastspell = "E"
  1295. end
  1296. end
  1297. if not myHero.dead and unit.team ~= myHero.team then
  1298. for i, skillShotChampion in pairs(champions) do
  1299. if skillShotChampion.charName == unit.charName then
  1300. for i, skillshot in pairs(skillShotChampion.skillshots) do
  1301. continueAdding = false
  1302. if skillshot.spellName == "KarthusLayWasteA" then
  1303. if spell.name == "KarthusLayWasteA1" or "KarthusLayWasteA2" or "KarthusLayWasteA3" then
  1304. continueAdding = true
  1305. end
  1306. else
  1307. if skillshot.spellName == spell.name then
  1308. continueAdding = true
  1309. end
  1310. end
  1311. if continueAdding then
  1312. startPosition = Point2(spell.startPos.x, spell.startPos.z)
  1313. endPosition = Point2(spell.endPos.x, spell.endPos.z)
  1314. if(spell.name == "xeratharcanopulse2") then
  1315. skillshot.range = startPosition:distance(endPosition)
  1316. end
  1317.  
  1318. if(spell.name == "HowlingGale" and HowlingGale) then
  1319. skillshot.range = startPosition:distance(endPosition)
  1320. HowlingGale = false
  1321. else
  1322. if(spell.name == "HowlingGale")then
  1323. HowlingGale = true
  1324. end
  1325. end
  1326.  
  1327. if isOrianna and unit.charName == "Orianna" then
  1328. ball = nil
  1329. for i = 1, objManager.maxObjects, 1 do
  1330. local obj = objManager:GetObject(i)
  1331. CheckBall(obj)
  1332. end
  1333. if ball ~= nil then
  1334. startPosition = Point2(ball.x, ball.z)
  1335. if skillshot.spellName == "OrianaDetonateCommand" then
  1336. endPosition = Point2(ball.x, ball.z)
  1337. end
  1338. end
  1339. end
  1340. directionVector = (endPosition - startPosition):normalized()
  1341. if isOrianna and unit.charName == "Orianna" then
  1342. if skillshot.spellName == "OrianaIzunaCommand" then skillshot.range = startPosition:distance(endPosition) end
  1343. end
  1344.  
  1345. if skillshot.type == "line" then
  1346. table.insert(detectedSkillshots, {startPosition = startPosition, endPosition = startPosition + directionVector * skillshot.range,
  1347. directionVector = directionVector, startTick = GetTickCount() + skillshot.spellDelay,
  1348. endTick = GetTickCount() + skillshot.spellDelay + skillshot.range/skillshot.projectileSpeed*1000, skillshot = skillshot, evading = false, drawit = true, alreadydashed = false, owner = unit})
  1349. elseif skillshot.type == "circular" then
  1350. table.insert(detectedSkillshots, {startPosition = startPosition, endPosition = endPosition,
  1351. directionVector = directionVector, startTick = GetTickCount() + skillshot.spellDelay,
  1352. endTick = GetTickCount() + skillshot.spellDelay + skillshot.projectileSpeed, skillshot = skillshot, evading = false, drawit = true, alreadydashed = false})
  1353. else
  1354. local ssrange = endPosition:distance(startPosition)
  1355. table.insert(detectedSkillshots, {startPosition = startPosition, endPosition = endPosition,
  1356. directionVector = directionVector, startTick = GetTickCount() + skillshot.spellDelay,
  1357. endTick = GetTickCount() + skillshot.spellDelay + (skillshot.projectileSpeed * (ssrange/skillshot.range)), skillshot = skillshot, evading = false, drawit = true, alreadydashed = false})
  1358. end
  1359. return
  1360. end
  1361. end
  1362. end
  1363. end
  1364. end
  1365. end
  1366.  
  1367. function skillshotPosition(skillshot, tickCount)
  1368. if skillshot.skillshot.type == "line" then
  1369. return skillshot.startPosition + skillshot.directionVector * math.max(tickCount - skillshot.startTick, 0) * skillshot.skillshot.projectileSpeed / 1000
  1370. else
  1371. return skillshot.endPosition
  1372. end
  1373. end
  1374.  
  1375. function skillshotHasPassed(skillshot, coordinate)
  1376. footOfPerpendicular = getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, coordinate)
  1377. currentSkillshotPosition = skillshotPosition(skillshot, GetTickCount() - 2 * GetLatency())
  1378. side1 = getSideOfLine(coordinate, footOfPerpendicular, currentSkillshotPosition)
  1379. side2 = getSideOfLine(coordinate, footOfPerpendicular, skillshot.startPosition)
  1380. return side1 ~= side2 and currentSkillshotPosition:distance(footOfPerpendicular) >= (skillshot.skillshot.radius + hitboxSize / 2)
  1381. end
  1382.  
  1383. function getPerpendicularFootpoint(linePoint1, linePoint2, point)
  1384. distanceFromLine = Line2(linePoint1, linePoint2):distance(point)
  1385. directionVector = (linePoint2 - linePoint1):normalized()
  1386.  
  1387. footOfPerpendicular = point + Point2(-directionVector.y, directionVector.x) * distanceFromLine
  1388. if Line2(linePoint1, linePoint2):distance(footOfPerpendicular) > distanceFromLine then
  1389. footOfPerpendicular = point - Point2(-directionVector.y, directionVector.x) * distanceFromLine
  1390. end
  1391.  
  1392. return footOfPerpendicular
  1393. end
  1394.  
  1395. function OnTick()
  1396. if GoodEvadeConfig.freemovementblock then
  1397. if evading and not alreadywritten then
  1398. local file = io.open(thatfile, "w")
  1399. file:write("1")
  1400. file:close()
  1401. alreadywritten = true
  1402. elseif not evading and alreadywritten then
  1403. local file = io.open(thatfile, "w")
  1404. file:write("0")
  1405. file:close()
  1406. alreadywritten = false
  1407. end
  1408. if not wrotedisclaimer then
  1409. PrintChat("<font color=\"#FF0000\" >You just enabled free user movement block, this function will only work if you followed tutorial in main thread of the script before allowing it.</font>")
  1410. wrotedisclaimer = true
  1411. end
  1412. end
  1413. if skillshotToAdd ~= nil and skillshotToAdd.object ~= nil and skillshotToAdd.object.valid and (GetTickCount() - skillshotToAdd.startTick) >= GoodEvadeConfig.fowdelay and skillshotToAdd.startPosition == nil then
  1414. skillshotToAdd.startPosition = Point2(skillshotToAdd.object.startPos.x, skillshotToAdd.object.startPos.x)
  1415. elseif skillshotToAdd ~= nil and skillshotToAdd.object ~= nil and skillshotToAdd.object.valid and (GetTickCount() - skillshotToAdd.startTick) >= (GoodEvadeConfig.fowdelay+1) then
  1416. skillshotToAdd.directionVector = (Point2(skillshotToAdd.object.x, skillshotToAdd.object.z) - skillshotToAdd.startPosition):normalized()
  1417. skillshotToAdd.endPosition = Point2(skillshotToAdd.object.endPos.x, skillshotToAdd.object.endPos.x)
  1418. table.insert(detectedSkillshots, skillshotToAdd)
  1419. skillshotToAdd = nil
  1420. end
  1421. if skillshotToAdd2 ~= nil and skillshotToAdd2.object ~= nil and skillshotToAdd2.object.valid and (GetTickCount() - skillshotToAdd2.startTick) >= GoodEvadeConfig.fowdelay and skillshotToAdd2.startPosition == nil then
  1422. skillshotToAdd2.startPosition = Point2(skillshotToAdd2.object.startPos.x, skillshotToAdd2.object.startPos.x)
  1423. elseif skillshotToAdd2 ~= nil and skillshotToAdd2.object ~= nil and skillshotToAdd2.object.valid and (GetTickCount() - skillshotToAdd2.startTick) >= (GoodEvadeConfig.fowdelay+1) then
  1424. skillshotToAdd2.directionVector = (Point2(skillshotToAdd2.object.x, skillshotToAdd2.object.z) - skillshotToAdd2.startPosition):normalized()
  1425. skillshotToAdd2.endPosition = Point2(skillshotToAdd2.object.endPos.x, skillshotToAdd2.object.endPos.x)
  1426. table.insert(detectedSkillshots, skillshotToAdd2)
  1427. skillshotToAdd2 = nil
  1428. end
  1429.  
  1430. if shieldtick ~= nil then
  1431. if GetTickCount() >= shieldtick then
  1432. if haveShield() then
  1433. if isSivir then
  1434. CastSpell(_E)
  1435. elseif isNocturne then
  1436. CastSpell(_W)
  1437. end
  1438. shieldtick = nil
  1439. end
  1440. end
  1441. end
  1442. if evading then
  1443. for i, detectedSkillshot in pairs(detectedSkillshots) do
  1444. if detectedSkillshot and detectedSkillshot.evading and inDangerousArea(detectedSkillshot, Point2(myHero.x, myHero.z)) then
  1445. dodgeSkillshot(detectedSkillshot)
  1446. end
  1447. end
  1448. end
  1449. if haveflash then
  1450. if myHero:CanUseSpell(flashSlot) == READY then
  1451. flashready = true
  1452. else flashready = false
  1453. end
  1454. end
  1455. if GoodEvadeConfig.resetdodge then
  1456. stopEvade()
  1457. detectedSkillshots = {}
  1458. end
  1459. if AutoCarry ~= nil then
  1460. if AutoCarry.MainMenu ~= nil then
  1461. if AutoCarry.MainMenu.AutoCarry or AutoCarry.MainMenu.LastHit or AutoCarry.MainMenu.MixedMode or AutoCarry.MainMenu.LaneClear
  1462. then
  1463. if not bufferset then
  1464. currentbuffer = GoodEvadeConfig.evadeBuffer
  1465. bufferset = true
  1466. end
  1467. if not VIP_USER then
  1468. if lastset < GetTickCount()
  1469. then lastMovement.destination = Point2(mousePos.x, mousePos.z)
  1470. lastset = GetTickCount() + 100
  1471. end
  1472. end
  1473. end
  1474. elseif AutoCarry.Keys ~= nil then
  1475. if AutoCarry.Keys.AutoCarry or AutoCarry.Keys.MixedMode or AutoCarry.Keys.LastHit or AutoCarry.Keys.LaneClear then
  1476. if not bufferset then
  1477. currentbuffer = GoodEvadeConfig.evadeBuffer
  1478. bufferset = true
  1479. end
  1480. if not VIP_USER then
  1481. if lastset < GetTickCount()
  1482. then lastMovement.destination = Point2(mousePos.x, mousePos.z)
  1483. lastset = GetTickCount() + 100
  1484. end
  1485. end
  1486. end
  1487. end
  1488. elseif MMA_Loaded ~= nil then
  1489. if _G.MMA_Orbwalker or _G.MMA_HybridMode or _G.MMA_LaneClear or _G.MMA_LastHit then
  1490. if not bufferset then
  1491. currentbuffer = GoodEvadeConfig.evadeBuffer
  1492. bufferset = true
  1493. end
  1494. if not VIP_USER then
  1495. if lastset < GetTickCount()
  1496. then lastMovement.destination = Point2(mousePos.x, mousePos.z)
  1497. lastset = GetTickCount() + 100
  1498. end
  1499. end
  1500. end
  1501. end
  1502. nSkillshots = 0
  1503. for _, detectedSkillshot in pairs(detectedSkillshots) do
  1504. if detectedSkillshot then
  1505. nSkillshots = nSkillshots + 1
  1506. end
  1507. end
  1508.  
  1509. if not allowCustomMovement and nSkillshots == 0 then
  1510. stopEvade()
  1511. end
  1512.  
  1513. hitboxSize = hitboxTable[GetMyHero().charName]
  1514.  
  1515. if hitboxSize == nil then
  1516. hitboxSize = 80.0
  1517. end
  1518.  
  1519. nEnemies = CountEnemyHeroInRange(1500)
  1520. table.sort(enemies, function(x,y) return GetDistance(x) < GetDistance(y) end)
  1521.  
  1522.  
  1523. heroPosition = Point2(myHero.x, myHero.z)
  1524. for i, detectedSkillshot in ipairs(detectedSkillshots) do
  1525. if detectedSkillshot.endTick <= GetTickCount() then
  1526. table.remove(detectedSkillshots, i)
  1527. i = i-1
  1528. if(detectedSkillshot.skillshot.name == "BoomerangBlade" and detectedSkillshot.done ~= true) then
  1529. directionVector = (detectedSkillshot.startPosition - detectedSkillshot.endPosition):normalized()
  1530. newSkillshot = {startPosition = detectedSkillshot.endPosition, endPosition = detectedSkillshot.startPosition,
  1531. directionVector = directionVector, startTick = GetTickCount(),
  1532. endTick = GetTickCount() + detectedSkillshot.skillshot.range/detectedSkillshot.skillshot.projectileSpeed*1000, skillshot = detectedSkillshot.skillshot, evading = detectedSkillshot.evading, drawit = true, alreadydashed = detectedSkillshot.alreadydashed, done = true}
  1533.  
  1534. table.insert(detectedSkillshots, newSkillshot)
  1535. end
  1536. if(detectedSkillshot.skillshot.name == "AhriOrbofDeception" and detectedSkillshot.done ~= true) then
  1537. directionVector = (detectedSkillshot.startPosition - detectedSkillshot.endPosition):normalized()
  1538. newSkillshot = {startPosition = detectedSkillshot.endPosition, endPosition = detectedSkillshot.startPosition,
  1539. directionVector = directionVector, startTick = GetTickCount(),
  1540. endTick = GetTickCount() + detectedSkillshot.skillshot.range/detectedSkillshot.skillshot.projectileSpeed*1000, skillshot = detectedSkillshot.skillshot, evading = detectedSkillshot.evading, drawit = true, alreadydashed = detectedSkillshot.alreadydashed, done = true}
  1541.  
  1542. table.insert(detectedSkillshots, newSkillshot)
  1543. end
  1544.  
  1545. if detectedSkillshot.evading then
  1546. continueMovement(detectedSkillshot)
  1547. end
  1548. else
  1549. if evading then
  1550. if detectedSkillshot.evading and not inDangerousArea(detectedSkillshot, heroPosition) then
  1551. if detectedSkillshot.skillshot.type == "line" then
  1552. side1 = getSideOfLine(detectedSkillshot.startPosition, detectedSkillshot.endPosition, heroPosition)
  1553. side2 = getSideOfLine(detectedSkillshot.startPosition, detectedSkillshot.endPosition, getLastMovementDestination())
  1554. if skillshotHasPassed(detectedSkillshot, heroPosition) then
  1555. continueMovement(detectedSkillshot)
  1556.  
  1557. elseif not inDangerousArea(detectedSkillshot, getLastMovementDestination()) and (side1 == side2) and (side1 ~= 0) then
  1558. continueMovement(detectedSkillshot)
  1559.  
  1560. elseif not inRange(detectedSkillshot, heroPosition) and not inRange(detectedSkillshot, getLastMovementDestination()) then
  1561. continueMovement(detectedSkillshot)
  1562.  
  1563. elseif lastMovement.approachedPoint ~= getLastMovementDestination() then
  1564. dodgeSkillshot(detectedSkillshot)
  1565. end
  1566. else
  1567. dodgeSkillshot(detectedSkillshot)
  1568. end
  1569. end
  1570. elseif inDangerousArea(detectedSkillshot, heroPosition) then
  1571. dodgeSkillshot(detectedSkillshot)
  1572. end
  1573. end
  1574. end
  1575. end
  1576.  
  1577. function WardJumpTo(x, y)
  1578. if GoodEvadeConfig.Skill.WardJ then
  1579. if GoodEvadeConfig.Skill.dashMouse then
  1580. local evadePos = Point2(mousePos.x, mousePos.z)
  1581. local myPos = Point2(myHero.x, myHero.z)
  1582. local ourdistance = evadePos:distance(myPos)
  1583. local dashPos = myPos - (myPos - evadePos):normalized() * 400
  1584.  
  1585. x = jumpPos.x
  1586. y = jumpPos.y
  1587. end
  1588. if isJax and myHero:CanUseSpell(_Q) == READY then
  1589.  
  1590. elseif isKatarina and myHero:CanUseSpell(_E) == READY then
  1591.  
  1592. elseif isLeeSin and myHero:CanUseSpell(_W) == READY and myHero:GetSpellData(_W).name:lower():find("one") then
  1593.  
  1594. end
  1595. end
  1596. end
  1597.  
  1598. function DashTo(x, y)
  1599. if GoodEvadeConfig.Skill.usedashes then
  1600.  
  1601. if GoodEvadeConfig.Skill.dashMouse then
  1602.  
  1603. local evadePos = Point2(mousePos.x, mousePos.z)
  1604. local myPos = Point2(myHero.x, myHero.z)
  1605. local ourdistance = evadePos:distance(myPos)
  1606. local dashPos = myPos - (myPos - evadePos):normalized() * dashrange
  1607.  
  1608. x = dashPos.x
  1609. y = dashPos.y
  1610.  
  1611. end
  1612.  
  1613. if isVayne and myHero:CanUseSpell(_Q) == READY then
  1614. CastSpell(_Q, x, y)
  1615. elseif isRiven and myHero:CanUseSpell(_E) == READY then
  1616. CastSpell(_E, x, y)
  1617. elseif isGraves and myHero:CanUseSpell(_E) == READY then
  1618. CastSpell(_E, x, y)
  1619. elseif isEzreal and myHero:CanUseSpell(_E) == READY then
  1620. CastSpell(_E, x, y)
  1621. elseif isKassadin and myHero:CanUseSpell(_R) == READY then
  1622. CastSpell(_R, x, y)
  1623. elseif isLeblanc and myHero:CanUseSpell(_W) == READY then
  1624. CastSpell(_W, x, y)
  1625. elseif isLeblanc and myHero:CanUseSpell(_R) == READY and lastspell == "W" then
  1626. CastSpell(_R, x, y)
  1627. elseif isFizz and myHero:CanUseSpell(_E) == READY then
  1628. CastSpell(_E, x, y)
  1629. elseif isShaco and myHero:CanUseSpell(_Q) == READY then
  1630. CastSpell(_Q, x, y)
  1631. elseif isCorki and myHero:CanUseSpell(_W) == READY then
  1632. CastSpell(_W, x, y)
  1633. elseif isRenekton and myHero:CanUseSpell(_E) == READY then
  1634. CastSpell(_E, x, y)
  1635. elseif isLucian and myHero:CanUseSpell(_E) == READY then
  1636. CastSpell(_E, x, y)
  1637. elseif isCaitlyn and myHero:CanUseSpell(_E) == READY then
  1638. myPos = Point2(myHero.x, myHero.z)
  1639. castpos = myPos + (myPos - (Point2(x, y)))
  1640. CastSpell(_E, castpos.x, castpos.y)
  1641. elseif isTristana and myHero:CanUseSpell(_W) == READY then
  1642. CastSpell(_W, x, y)
  1643. elseif isShen and myHero:CanUseSpell(_E) == READY then
  1644. CastSpell(_E, x, y)
  1645. elseif isTryndamere and myHero:CanUseSpell(_E) == READY then
  1646. CastSpell(_E, x, y)
  1647. end
  1648. end
  1649. end
  1650.  
  1651. function NeedWardJump(skillshot, forceJump)
  1652. if (GoodEvadeSkillshotConfig[tostring(skillshot.skillshot.name)] == 2 or (GoodEvadeSkillshotConfig[tostring(skillshot.skillshot.name)] == 1 and nEnemies <= 2 and not (skillshot.skillshot.cc and ((GoodEvadeConfig.dodgeCConly == skillshot.skillshot.cc or GoodEvadeConfig.dodgeCConly2 == skillshot.skillshot.cc))))) then
  1653. if GoodEvadeConfig.Skill.usejumps then
  1654. useflash = false
  1655. local hp = myHero.health / myHero.maxHealth
  1656. if isKatarina and myHero:CanUseSpell(_E) == READY then
  1657. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1658. return true
  1659. end
  1660. elseif isLeeSin and myHero:CanUseSpell(_W) == READY and myHero:GetSpellData(_W).name:lower():find("one") then
  1661. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1662. return true
  1663. end
  1664. elseif isJax and myHero:CanUseSpell(_Q) == READY then
  1665. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1666. return true
  1667. end
  1668. end
  1669. return false
  1670. end
  1671. return false
  1672. end
  1673. return false
  1674. end
  1675.  
  1676. function NeedDash(skillshot, forceDash)
  1677. if (GoodEvadeSkillshotConfig[tostring(skillshot.skillshot.name)] == 2 or (GoodEvadeSkillshotConfig[tostring(skillshot.skillshot.name)] == 1 and nEnemies <= 2 and not (skillshot.skillshot.cc and ((GoodEvadeConfig.dodgeCConly == skillshot.skillshot.cc or GoodEvadeConfig.dodgeCConly2 == skillshot.skillshot.cc))))) then
  1678. if GoodEvadeConfig.Skill.usedashes then
  1679. useflash = false
  1680. local hp = myHero.health / myHero.maxHealth
  1681. if isVayne and myHero:CanUseSpell(_Q) == READY then
  1682. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1683. dashrange = 300
  1684. return true
  1685. end
  1686. if nSkillshots > 1 or _isDangerSkillshot(skillshot) then
  1687. dashrange = 300
  1688. return true
  1689. end
  1690. elseif isRiven and myHero:CanUseSpell(_E) == READY then
  1691. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1692. dashrange = 325
  1693. return true end
  1694. if nSkillshots > 1 or _isDangerSkillshot(skillshot) then
  1695. dashrange = 325
  1696. return true end
  1697. elseif isGraves and myHero:CanUseSpell(_E) == READY then
  1698. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1699. dashrange = 425
  1700. return true end
  1701. if _isDangerSkillshot(skillshot) then
  1702. dashrange = 425
  1703. return true end
  1704. elseif isShaco and myHero:CanUseSpell(_Q) == READY then
  1705. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1706. dashrange = 400
  1707. return true end
  1708. if _isDangerSkillshot(skillshot) then
  1709. dashrange = 400
  1710. return true end
  1711. elseif isEzreal and myHero:CanUseSpell(_E) == READY then
  1712. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1713. dashrange = 450
  1714. return true end
  1715. if _isDangerSkillshot(skillshot) then
  1716. dashrange = 450
  1717. return true end
  1718. elseif isFizz and myHero:CanUseSpell(_E) == READY then
  1719. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1720. dashrange = 400
  1721. return true end
  1722. if _isDangerSkillshot(skillshot) then
  1723. dashrange = 400
  1724. return true end
  1725. elseif isKassadin and myHero:CanUseSpell(_R) == READY then
  1726. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1727. dashrange = 700
  1728. return true end
  1729. if _isDangerSkillshot(skillshot) then
  1730. dashrange = 700
  1731. return true end
  1732. elseif isLeblanc and myHero:CanUseSpell(_W) == READY then
  1733. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1734. dashrange = 600
  1735. return true end
  1736. if _isDangerSkillshot(skillshot) then
  1737. dashrange = 600
  1738. return true end
  1739. elseif isLeblanc and myHero:CanUseSpell(_R) == READY and lastspell == "W" then
  1740. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1741. dashrange = 600
  1742. return true end
  1743. if _isDangerSkillshot(skillshot) then
  1744. dashrange = 600
  1745. return true end
  1746. elseif isRenekton and myHero:CanUseSpell(_E) == READY then
  1747. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1748. dashrange = 450
  1749. return true end
  1750. if _isDangerSkillshot(skillshot) then
  1751. dashrange = 450
  1752. return true end
  1753. elseif isCorki and myHero:CanUseSpell(_W) == READY then
  1754. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1755. dashrange = 800
  1756. end
  1757. if _isDangerSkillshot(skillshot) then
  1758. dashrange = 800
  1759. return true end
  1760. elseif isLucian and myHero:CanUseSpell(_E) == READY then
  1761. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1762. dashrange = 425
  1763. return true
  1764. end
  1765. if _isDangerSkillshot(skillshot) then
  1766. dashrange = 425
  1767. return true
  1768. end
  1769. elseif isTryndamere and myHero:CanUseSpell(_E) == READY then
  1770. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1771. dashrange = 660
  1772. return true end
  1773. elseif isCaitlyn and myHero:CanUseSpell(_E) == READY then
  1774. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1775. dashrange = 400
  1776. return true end
  1777. elseif isTristana and myHero:CanUseSpell(_W) == READY then
  1778. if _isDangerSkillshot(skillshot) then
  1779. dashrange = 900
  1780. return true end
  1781. elseif isShen and myHero:CanUseSpell(_E) == READY then
  1782. if hp < (GoodEvadeConfig["dashPercent"] / 100) then
  1783. dashrange = 600
  1784. return true end
  1785. if _isDangerSkillshot(skillshot) then
  1786. dashrange = 600
  1787. return true end
  1788. end
  1789. end
  1790. end
  1791. return false
  1792. end
  1793.  
  1794. function evadeTo(x, y, forceDash, skillshot)
  1795. _type = 0
  1796. if NeedDash(skillshot, true) then
  1797. _type = 1
  1798. elseif NeedWardJump(skillshot, true) then
  1799. _type = 2
  1800. dashrange = 400
  1801. end
  1802. startEvade()
  1803. evadePoint = Point2(x, y)
  1804. allowCustomMovement = true
  1805. captureMovements = false
  1806. if forceDash then
  1807. local evadePos = Point2(x, y)
  1808. local myPos = Point2(myHero.x, myHero.z)
  1809. local ourdistance = evadePos:distance(myPos)
  1810. local dashPos = myPos - (myPos - evadePos):normalized() * dashrange
  1811. if _type == 1 then
  1812. DashTo(x, y)
  1813. elseif _type == 2 then
  1814. WardJumpTo(x, y)
  1815. end
  1816. else
  1817. myHero:MoveTo(x, y)
  1818. end
  1819. lastMovement.moveCommand = Point2(x, y)
  1820. captureMovements = true
  1821. allowCustomMovement = false
  1822. evading = true
  1823. evadingTick = GetTickCount()
  1824. end
  1825.  
  1826. function continueMovement(skillshot)
  1827. if VIP_USER then
  1828. if evading then
  1829. skillshot.evading = false
  1830. lastMovement.approachedPoint = nil
  1831.  
  1832. stopEvade()
  1833.  
  1834. if lastMovement.type == 2 then
  1835. captureMovements = false
  1836. myHero:MoveTo(getLastMovementDestination().x, getLastMovementDestination().y)
  1837. captureMovements = true
  1838. elseif lastMovement.type == 3 then
  1839. target = getTarget(lastMovement.targetId)
  1840.  
  1841. if _isValidTarget(target) then
  1842. captureMovements = false
  1843. myHero:Attack(target)
  1844. captureMovements = true
  1845. else
  1846. captureMovements = false
  1847. myHero:MoveTo(myHero.x, myHero.z)
  1848. captureMovements = true
  1849. end
  1850. elseif lastMovement.type == 10 then
  1851. myHero:HoldPosition()
  1852. elseif lastMovement.type == 7 then
  1853. lastMovement.type = 3
  1854. end
  1855. end
  1856. elseif evading then
  1857. skillshot.evading = false
  1858. lastMovement.approachedPoint = nil
  1859. stopEvade()
  1860. if continuetarget == nil then
  1861. captureMovements = false
  1862. myHero:MoveTo(getLastMovementDestination().x, getLastMovementDestination().y)
  1863. captureMovements = true
  1864. elseif continuetarget ~= nil then
  1865. target = continuetarget
  1866. if _isValidTarget(target) then
  1867. captureMovements = false
  1868. myHero:Attack(target)
  1869. captureMovements = true
  1870. else
  1871. captureMovements = false
  1872. myHero:MoveTo(myHero.x, myHero.z)
  1873. captureMovements = true
  1874. end
  1875. end
  1876. end
  1877. end
  1878.  
  1879. function GetAngleOfLineBetweenTwoPoints(p1, p2)
  1880. local xDiff = p2.x - p1.x
  1881. local yDiff = p2.y - p1.y
  1882. return math.atan2(yDiff, xDiff)
  1883. end
  1884.  
  1885. function drawLineshit(point1, point2, color, width1, skillshot)
  1886.  
  1887. if(GoodEvadeConfig.Draw["oldDrawing"])then
  1888. apoint = WorldToScreen(D3DXVECTOR3(point1.x, 0, point1.y))
  1889. bpoint = WorldToScreen(D3DXVECTOR3(point2.x, 0, point2.y))
  1890.  
  1891. DrawLine(apoint.x, apoint.y, bpoint.x, bpoint.y, width1, color)
  1892. else
  1893.  
  1894. local Height = skillshot.skillshot.radius * 2
  1895. local Width = skillshot.skillshot.range
  1896.  
  1897. A = GetAngleOfLineBetweenTwoPoints(point1, point2)
  1898.  
  1899. x = math.floor((point2.x + point1.x) / 2)
  1900. y = math.floor((point2.y + point1.y) / 2)
  1901.  
  1902. UL = Point2((math.cos(A) * ((x + Width / 2) - x)) - (math.sin(A) * ((y + Height / 2) - y)) + x, (math.cos(A) * ((y + Height / 2) - y)) + (math.sin(A) * ((x + Width / 2) - x)) + y)
  1903. UR = Point2((math.cos(A) * ((x - Width / 2) - x)) - (math.sin(A) * ((y + Height / 2) - y)) + x, (math.cos(A) * ((y + Height / 2) - y)) + (math.sin(A) * ((x - Width / 2) - x)) + y)
  1904. BL = Point2((math.cos(A) * ((x + Width / 2) - x)) - (math.sin(A) * ((y - Height / 2) - y)) + x, (math.cos(A) * ((y - Height / 2) - y)) + (math.sin(A) * ((x + Width / 2) - x)) + y)
  1905. BR = Point2((math.cos(A) * ((x - Width / 2) - x)) - (math.sin(A) * ((y - Height / 2) - y)) + x, (math.cos(A) * ((y - Height / 2) - y)) + (math.sin(A) * ((x - Width / 2) - x)) + y)
  1906.  
  1907. UL2 = WorldToScreen(D3DXVECTOR3(UL.x, GetMyHero().y, UL.y))
  1908. UR2 = WorldToScreen(D3DXVECTOR3(UR.x, GetMyHero().y, UR.y))
  1909. BL2 = WorldToScreen(D3DXVECTOR3(BL.x, GetMyHero().y, BL.y))
  1910. BR2 = WorldToScreen(D3DXVECTOR3(BR.x, GetMyHero().y, BR.y))
  1911.  
  1912. DrawLine(UL2.x, UL2.y, UR2.x, UR2.y, 1, 0xFFFF0000)
  1913. DrawLine(UL2.x, UL2.y, BL2.x, BL2.y, 1, 0xFFFF0000)
  1914. DrawLine(BR2.x, BR2.y, UR2.x, UR2.y, 1, 0xFFFF0000)
  1915. DrawLine(BR2.x, BR2.y, BL2.x, BL2.y, 1, 0xFFFF0000)
  1916.  
  1917.  
  1918. end
  1919. end
  1920.  
  1921. function OnDraw()
  1922. if GoodEvadeConfig.Draw.drawEnabled then
  1923. DrawCircle(GetMyHero().x, GetMyHero().y, GetMyHero().z, hitboxSize, 0xFFFFFF)
  1924. for i, detectedSkillshot in pairs(detectedSkillshots) do
  1925. skillshotPos = skillshotPosition(detectedSkillshot, GetTickCount())
  1926. if detectedSkillshot.drawit == true then
  1927. if detectedSkillshot.skillshot.type == "line" then
  1928. drawLineshit(detectedSkillshot.startPosition, detectedSkillshot.endPosition, 0xFFFF0000, 3, detectedSkillshot)
  1929. DrawCircle(skillshotPos.x, myHero.y, skillshotPos.y, detectedSkillshot.skillshot.radius, 0xFFFFFF)
  1930. else
  1931. DrawCircle(skillshotPos.x, myHero.y, skillshotPos.y, detectedSkillshot.skillshot.radius, 0x00FF00)
  1932. end
  1933. end
  1934. end
  1935. end
  1936. end
  1937.  
  1938. function _isValidTarget(target)
  1939. return target ~= nil and target.valid and target.dead == false and target.bTargetable and target.bMagicImunebMagicImune ~= true and target.bInvulnerable ~= true and target.visible
  1940. end
  1941.  
  1942. function startEvade()
  1943. allowCustomMovement = false
  1944. if AutoCarry
  1945. then if AutoCarry.MainMenu ~= nil then
  1946. if AutoCarry.CanAttack ~= nil then
  1947. _G.AutoCarry.CanAttack = false
  1948. _G.AutoCarry.CanMove = false
  1949. end
  1950. elseif AutoCarry.Keys ~= nil then
  1951. if AutoCarry.MyHero ~= nil then
  1952. _G.AutoCarry.MyHero:MovementEnabled(false)
  1953. _G.AutoCarry.MyHero:AttacksEnabled(false)
  1954. end
  1955. end
  1956. elseif MMA_Loaded then
  1957. _G.MMA_AttackAvailable = false
  1958. _G.MMA_AbleToMove = false
  1959. end
  1960. _G.evade = true
  1961. evading = true
  1962. end
  1963.  
  1964. function stopEvade()
  1965. allowCustomMovement = true
  1966. if AutoCarry then if AutoCarry.MainMenu ~= nil then
  1967. if AutoCarry.CanAttack ~= nil then
  1968. _G.AutoCarry.CanAttack = true
  1969. _G.AutoCarry.CanMove = true
  1970. end
  1971. elseif AutoCarry.Keys ~= nil then
  1972. if AutoCarry.MyHero ~= nil then
  1973. _G.AutoCarry.MyHero:MovementEnabled(true)
  1974. _G.AutoCarry.MyHero:AttacksEnabled(true)
  1975. end
  1976. end
  1977. elseif MMA_Loaded then
  1978. _G.MMA_AttackAvailable = true
  1979. _G.MMA_AbleToMove = true
  1980. end
  1981. _G.evade = false
  1982. evading = false
  1983. end
  1984.  
  1985. function OnWndMsg(msg, key)
  1986. if not VIP_USER then
  1987. if msg == WM_RBUTTONDOWN then
  1988. if evading then
  1989. for i, detectedSkillshot in pairs(detectedSkillshots) do
  1990. if detectedSkillshot and detectedSkillshot.evading and inDangerousArea(detectedSkillshot, Point2(myHero.x, myHero.z)) then
  1991. dodgeSkillshot(detectedSkillshot)
  1992. end
  1993. end
  1994. end
  1995. lastMovement.destination = Point2(mousePos.x, mousePos.z)
  1996. end
  1997. end
  1998. end
  1999. -- beggining of circular skillshot dodging functions --
  2000. function mainCircularskillshot5(skillshot, safeTarget)
  2001. if NeedDash(skillshot, true) and not skillshot.alreadydashed then
  2002. evadeTo(safeTarget.x, safeTarget.y, true, skillshot)
  2003. skillshot.alreadydashed = true
  2004. return true
  2005. else return false
  2006. end
  2007. return false
  2008. end
  2009.  
  2010. function mainCircularskillshot4(skillshot, heroPosition, moveableDistance, evadeRadius, safeTarget)
  2011. if NeedDash(skillshot, true) and not skillshot.alreadydashed then
  2012. moveableDistance = (myHero.ms * math.max(skillshot.endTick - GetTickCount() - GetLatency()/2, 0) / 1000) + dashrange
  2013. evadeRadius = skillshot.skillshot.radius + hitboxSize / 2 + GoodEvadeConfig.evadeBuffer + moveBuffer
  2014.  
  2015. safeTarget = skillshot.endPosition + (heroPosition - skillshot.endPosition):normalized() * evadeRadius
  2016. if getLastMovementDestination():distance(skillshot.endPosition) <= evadeRadius then
  2017. closestTarget = skillshot.endPosition + (getLastMovementDestination() - skillshot.endPosition):normalized() * evadeRadius
  2018. else
  2019. closestTarget = nil
  2020. end
  2021.  
  2022. lineDistance = Line2(heroPosition, getLastMovementDestination()):distance(skillshot.endPosition)
  2023. directionTarget = heroPosition + (getLastMovementDestination() - heroPosition):normalized() * (math.sqrt(heroPosition:distance(skillshot.endPosition)^2 - lineDistance^2) + math.sqrt(evadeRadius^2 - lineDistance^2))
  2024. if directionTarget:distance(skillshot.endPosition) >= evadeRadius + 1 then
  2025. directionTarget = heroPosition + (getLastMovementDestination() - heroPosition):normalized() * (math.sqrt(evadeRadius^2 - lineDistance^2) - math.sqrt(heroPosition:distance(skillshot.endPosition)^2 - lineDistance^2))
  2026. end
  2027.  
  2028. possibleMovementTargets = {}
  2029. intersectionPoints = Circle2(skillshot.endPosition, evadeRadius):intersectionPoints(Circle2(heroPosition, moveableDistance))
  2030. if #intersectionPoints == 2 then
  2031. leftTarget = intersectionPoints[1]
  2032. rightTarget = intersectionPoints[2]
  2033.  
  2034. local theta = ((-skillshot.endPosition + leftTarget):polar() - (-skillshot.endPosition + rightTarget):polar()) % 360
  2035. if ((theta >= 180 and getSideOfLine(skillshot.endPosition, leftTarget, directionTarget) == getSideOfLine(skillshot.endPosition, leftTarget, heroPosition) and getSideOfLine(skillshot.endPosition, rightTarget, directionTarget) == getSideOfLine(skillshot.endPosition, rightTarget, heroPosition)) or (theta <= 180 and (getSideOfLine(skillshot.endPosition, leftTarget, directionTarget) == getSideOfLine(skillshot.endPosition, leftTarget, heroPosition) or getSideOfLine(skillshot.endPosition, rightTarget, directionTarget) == getSideOfLine(skillshot.endPosition, rightTarget, heroPosition)))) then
  2036. table.insert(possibleMovementTargets, directionTarget)
  2037. end
  2038.  
  2039. if closestTarget ~= nil and ((theta >= 180 and getSideOfLine(skillshot.endPosition, leftTarget, closestTarget) == getSideOfLine(skillshot.endPosition, leftTarget, heroPosition) and getSideOfLine(skillshot.endPosition, rightTarget, closestTarget) == getSideOfLine(skillshot.endPosition, rightTarget, heroPosition)) or (theta <= 180 and (getSideOfLine(skillshot.endPosition, leftTarget, closestTarget) == getSideOfLine(skillshot.endPosition, leftTarget, heroPosition) or getSideOfLine(skillshot.endPosition, rightTarget, closestTarget) == getSideOfLine(skillshot.endPosition, rightTarget, heroPosition)))) then
  2040. table.insert(possibleMovementTargets, closestTarget)
  2041. end
  2042.  
  2043.  
  2044. table.insert(possibleMovementTargets, safeTarget)
  2045. table.insert(possibleMovementTargets, leftTarget)
  2046. table.insert(possibleMovementTargets, rightTarget)
  2047. else
  2048. if skillshot.skillshot.radius <= moveableDistance then
  2049. table.insert(possibleMovementTargets, closestTarget)
  2050. table.insert(possibleMovementTargets, directionTarget)
  2051. table.insert(possibleMovementTargets, safeTarget)
  2052. end
  2053. end
  2054.  
  2055. closestPoint = findBestDirection(skillshot, getLastMovementDestination(), possibleMovementTargets)
  2056. if closestPoint ~= nil then
  2057. closestPoint = closestPoint + (closestPoint - heroPosition):normalized() * smoothing
  2058. evadeTo(closestPoint.x, closestPoint.y, true, skillshot)
  2059. skillshot.alreadydashed = true
  2060. return true
  2061. else return false
  2062. end
  2063. else return false
  2064. end
  2065. return false
  2066. end
  2067.  
  2068. function mainCircularskillshot3(skillshot, heroPosition)
  2069. if getLastMovementDestination():distance(heroPosition) > 20 and NeedDash(skillshot, true) and not skillshot.alreadydashed then
  2070. dashpos = getLastMovementDestination() + (getLastMovementDestination() - heroPosition):normalized() * dashrange
  2071. if dashpos:distance(skillshot.endPosition) > skillshot.skillshot.radius and not InsideTheWall(dashpos) then
  2072. evadeTo(dashpos.x, dashpos.y, true, skillshot)
  2073. skillshot.alreadydashed = true
  2074. return true
  2075. else return false
  2076. end
  2077. else return false
  2078. end
  2079. return false
  2080. end
  2081.  
  2082. function mainCircularskillshot2(skillshot)
  2083. if haveShield() then
  2084. for i, detectedSkillshot in ipairs(detectedSkillshots) do
  2085. if detectedSkillshot.skillshot.name == skillshot.skillshot.name then
  2086. table.remove(detectedSkillshots, i)
  2087. i = i-1
  2088. if detectedSkillshot.evading then
  2089. continueMovement(detectedSkillshot)
  2090. end
  2091. end
  2092. end
  2093. if skillshot.skillshot.shieldnow == "true" then
  2094. if isSivir then
  2095. CastSpell(_E)
  2096. elseif isNocturne then
  2097. CastSpell(_W)
  2098. end
  2099. return true
  2100. elseif skillshot.skillshot.shieldnow == "false" then
  2101. shieldtick = skillshot.endTick - 50 - GetLatency()
  2102. return true
  2103. end
  2104. else return false
  2105. end
  2106. return false
  2107. end
  2108.  
  2109. function mainCircularskillshot1(skillshot, heroPosition, moveableDistance, evadeRadius, safeTarget)
  2110. if getLastMovementDestination():distance(skillshot.endPosition) <= evadeRadius then
  2111. closestTarget = skillshot.endPosition + (getLastMovementDestination() - skillshot.endPosition):normalized() * evadeRadius
  2112. else
  2113. closestTarget = nil
  2114. end
  2115.  
  2116. lineDistance = Line2(heroPosition, getLastMovementDestination()):distance(skillshot.endPosition)
  2117. directionTarget = heroPosition + (getLastMovementDestination() - heroPosition):normalized() * (math.sqrt(heroPosition:distance(skillshot.endPosition)^2 - lineDistance^2) + math.sqrt(evadeRadius^2 - lineDistance^2))
  2118. if directionTarget:distance(skillshot.endPosition) >= evadeRadius + 1 then
  2119. directionTarget = heroPosition + (getLastMovementDestination() - heroPosition):normalized() * (math.sqrt(evadeRadius^2 - lineDistance^2) - math.sqrt(heroPosition:distance(skillshot.endPosition)^2 - lineDistance^2))
  2120. end
  2121.  
  2122. possibleMovementTargets = {}
  2123. intersectionPoints = Circle2(skillshot.endPosition, evadeRadius):intersectionPoints(Circle2(heroPosition, moveableDistance))
  2124. if #intersectionPoints == 2 then
  2125. leftTarget = intersectionPoints[1]
  2126. rightTarget = intersectionPoints[2]
  2127.  
  2128. local theta = ((-skillshot.endPosition + leftTarget):polar() - (-skillshot.endPosition + rightTarget):polar()) % 360
  2129. if ((theta >= 180 and getSideOfLine(skillshot.endPosition, leftTarget, directionTarget) == getSideOfLine(skillshot.endPosition, leftTarget, heroPosition) and getSideOfLine(skillshot.endPosition, rightTarget, directionTarget) == getSideOfLine(skillshot.endPosition, rightTarget, heroPosition)) or (theta <= 180 and (getSideOfLine(skillshot.endPosition, leftTarget, directionTarget) == getSideOfLine(skillshot.endPosition, leftTarget, heroPosition) or getSideOfLine(skillshot.endPosition, rightTarget, directionTarget) == getSideOfLine(skillshot.endPosition, rightTarget, heroPosition)))) then
  2130. table.insert(possibleMovementTargets, directionTarget)
  2131. end
  2132.  
  2133. if closestTarget ~= nil and ((theta >= 180 and getSideOfLine(skillshot.endPosition, leftTarget, closestTarget) == getSideOfLine(skillshot.endPosition, leftTarget, heroPosition) and getSideOfLine(skillshot.endPosition, rightTarget, closestTarget) == getSideOfLine(skillshot.endPosition, rightTarget, heroPosition)) or (theta <= 180 and (getSideOfLine(skillshot.endPosition, leftTarget, closestTarget) == getSideOfLine(skillshot.endPosition, leftTarget, heroPosition) or getSideOfLine(skillshot.endPosition, rightTarget, closestTarget) == getSideOfLine(skillshot.endPosition, rightTarget, heroPosition)))) then
  2134. table.insert(possibleMovementTargets, closestTarget)
  2135. end
  2136.  
  2137.  
  2138. table.insert(possibleMovementTargets, safeTarget)
  2139. table.insert(possibleMovementTargets, leftTarget)
  2140. table.insert(possibleMovementTargets, rightTarget)
  2141. else
  2142. if skillshot.skillshot.radius <= moveableDistance then
  2143. table.insert(possibleMovementTargets, closestTarget)
  2144. table.insert(possibleMovementTargets, directionTarget)
  2145. table.insert(possibleMovementTargets, safeTarget)
  2146. end
  2147. end
  2148.  
  2149. closestPoint = findBestDirection(skillshot, getLastMovementDestination(), possibleMovementTargets)
  2150. if closestPoint ~= nil then
  2151. closestPoint = closestPoint + (closestPoint - heroPosition):normalized() * smoothing
  2152. evadeTo(closestPoint.x, closestPoint.y, true, skillshot)
  2153. return true
  2154. else return false
  2155. end
  2156. return false
  2157. end
  2158.  
  2159. function dodgeDangerousCircle1(skillshot)
  2160. if haveShield() then
  2161. for i, detectedSkillshot in ipairs(detectedSkillshots) do
  2162. if detectedSkillshot.skillshot.name == skillshot.skillshot.name then
  2163. table.remove(detectedSkillshots, i)
  2164. i = i-1
  2165. if detectedSkillshot.evading then
  2166. continueMovement(detectedSkillshot)
  2167. end
  2168. end
  2169. end
  2170. if isSivir then
  2171. CastSpell(_E)
  2172. elseif isNocturne then
  2173. CastSpell(_W)
  2174. end
  2175. return true
  2176. else return false
  2177. end
  2178. return false
  2179. end
  2180.  
  2181. function dodgeDangerousCircle2(skillshot, safeTarget)
  2182.  
  2183. if NeedDash(skillshot, true) and getLastMovementDestination():distance(safeTarget) > 20 and not skillshot.alreadydashed then
  2184.  
  2185. if safeTarget:distance(skillshot.endPosition) > skillshot.skillshot.radius and not InsideTheWall(safeTarget) then
  2186. local evadePos = safeTarget
  2187. local myPos = Point2(myHero.x, myHero.z)
  2188. local ourdistance = evadePos:distance(myPos)
  2189. local dashPos = myPos - (myPos - evadePos):normalized() * dashrange
  2190. DashTo(dashPos.x, dashPos.y)
  2191. skillshot.alreadydashed = true
  2192. for i, detectedSkillshot in ipairs(detectedSkillshots) do
  2193. if detectedSkillshot.skillshot.name == skillshot.skillshot.name then
  2194. table.remove(detectedSkillshots, i)
  2195. i = i-1
  2196. if detectedSkillshot.evading then
  2197. continueMovement(detectedSkillshot)
  2198. end
  2199. end
  2200. end
  2201. return true
  2202. else
  2203. return false
  2204. end else
  2205. return false
  2206. end
  2207.  
  2208. return false
  2209. end
  2210.  
  2211. function dodgeDangerousCircle3(skillshot, safeTarget)
  2212. if GoodEvadeConfig.Skill.useSummonerFlash and flashready and not skillshot.alreadydashed then
  2213. FlashTo(safeTarget.x, safeTarget.y)
  2214. skillshot.alreadydashed = true
  2215. for i, detectedSkillshot in ipairs(detectedSkillshots) do
  2216. if detectedSkillshot.skillshot.name == skillshot.skillshot.name then
  2217. table.remove(detectedSkillshots, i)
  2218. i = i-1
  2219. if detectedSkillshot.evading then
  2220. continueMovement(detectedSkillshot)
  2221. end
  2222. end
  2223. end
  2224. return true
  2225. else return false
  2226. end
  2227. return false
  2228. end
  2229.  
  2230.  
  2231. -- end of circular skillshot dodging functions --
  2232. -- beggining of line skillshot dodging functions --
  2233. function lineSkillshot1(skillshot, heroPosition, skillshotLine, distanceFromSkillshotPath, evadeDistance, normalVector, nessecaryMoveWidth, evadeTo1, evadeTo2)
  2234. if skillshotLine:distance(evadeTo1) >= skillshotLine:distance(evadeTo2) then
  2235. longitudinalApproachLength = calculateLongitudinalApproachLength(skillshot, nessecaryMoveWidth)
  2236. if longitudinalApproachLength >= 0 then
  2237. evadeToTarget1 = evadeTo1 - skillshot.directionVector * longitudinalApproachLength
  2238. end
  2239.  
  2240. longitudinalApproachLength = calculateLongitudinalApproachLength(skillshot, evadeDistance + distanceFromSkillshotPath)
  2241. if longitudinalApproachLength >= 0 then
  2242. evadeToTarget2 = heroPosition - normalVector * (evadeDistance + distanceFromSkillshotPath) - skillshot.directionVector * longitudinalApproachLength
  2243. end
  2244.  
  2245. longitudinalRetreatLength = calculateLongitudinalRetreatLength(skillshot, nessecaryMoveWidth)
  2246. if longitudinalRetreatLength >= 0 then
  2247. evadeToTarget3 = evadeTo1 + skillshot.directionVector * longitudinalRetreatLength
  2248. end
  2249.  
  2250. longitudinalRetreatLength = calculateLongitudinalRetreatLength(skillshot, evadeDistance + distanceFromSkillshotPath)
  2251. if longitudinalRetreatLength >= 0 then
  2252. evadeToTarget4 = heroPosition - normalVector * (evadeDistance + distanceFromSkillshotPath) + skillshot.directionVector * longitudinalRetreatLength
  2253. end
  2254.  
  2255. safeTarget = evadeTo1
  2256.  
  2257. closestPoint = getLastMovementDestination() + normalVector * (evadeDistance - skillshotLine:distance(getLastMovementDestination()))
  2258. closestPoint2 = getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, getLastMovementDestination()) + normalVector * evadeDistance
  2259. else
  2260. longitudinalApproachLength = calculateLongitudinalApproachLength(skillshot, nessecaryMoveWidth)
  2261. if longitudinalApproachLength >= 0 then
  2262. evadeToTarget1 = evadeTo2 - skillshot.directionVector * longitudinalApproachLength
  2263. end
  2264.  
  2265. longitudinalApproachLength = calculateLongitudinalApproachLength(skillshot, evadeDistance + distanceFromSkillshotPath)
  2266. if longitudinalApproachLength >= 0 then
  2267. evadeToTarget2 = heroPosition + normalVector * (evadeDistance + distanceFromSkillshotPath) - skillshot.directionVector * longitudinalApproachLength
  2268. end
  2269.  
  2270. longitudinalRetreatLength = calculateLongitudinalRetreatLength(skillshot, nessecaryMoveWidth)
  2271. if longitudinalRetreatLength >= 0 then
  2272. evadeToTarget3 = evadeTo2 + skillshot.directionVector * longitudinalRetreatLength
  2273. end
  2274.  
  2275. longitudinalRetreatLength = calculateLongitudinalRetreatLength(skillshot, evadeDistance + distanceFromSkillshotPath)
  2276. if longitudinalRetreatLength >= 0 then
  2277. evadeToTarget4 = heroPosition + normalVector * (evadeDistance + distanceFromSkillshotPath) + skillshot.directionVector * longitudinalRetreatLength
  2278. end
  2279.  
  2280. safeTarget = evadeTo2
  2281.  
  2282. closestPoint = getLastMovementDestination() - normalVector * (evadeDistance - skillshotLine:distance(getLastMovementDestination()))
  2283. closestPoint2 = getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, getLastMovementDestination()) - normalVector * evadeDistance
  2284. end
  2285.  
  2286. if skillshotLine:distance(getLastMovementDestination()) <= evadeDistance then
  2287. directionTarget = findBestDirection(skillshot,getLastMovementDestination(), {closestPoint, closestPoint2, getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, getLastMovementDestination()) - normalVector * evadeDistance, getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, getLastMovementDestination()) + normalVector * evadeDistance})
  2288. else
  2289. if getSideOfLine(skillshot.startPosition, skillshot.endPosition, getLastMovementDestination()) == getSideOfLine(skillshot.startPosition, skillshot.endPosition, heroPosition) then
  2290. if skillshotLine:distance(heroPosition) <= skillshotLine:distance(getLastMovementDestination()) then
  2291. directionTarget = heroPosition + (getLastMovementDestination()-heroPosition):normalized() * ((evadeDistance - distanceFromSkillshotPath) * heroPosition:distance(getLastMovementDestination())) / (skillshotLine:distance(getLastMovementDestination()) - distanceFromSkillshotPath)
  2292. else
  2293. directionTarget = heroPosition + (getLastMovementDestination()-heroPosition):normalized() * ((evadeDistance + distanceFromSkillshotPath) * heroPosition:distance(getLastMovementDestination())) / (distanceFromSkillshotPath - skillshotLine:distance(getLastMovementDestination()))
  2294. end
  2295. else
  2296. directionTarget = heroPosition + (getLastMovementDestination() - heroPosition):normalized() * (evadeDistance + distanceFromSkillshotPath) * heroPosition:distance(getLastMovementDestination()) / (skillshotLine:distance(getLastMovementDestination()) + distanceFromSkillshotPath)
  2297. end
  2298. end
  2299.  
  2300. evadeTarget = nil
  2301. if (evadeToTarget1 ~= nil and evadeToTarget3 ~= nil and Line2(evadeToTarget1, evadeToTarget3):distance(directionTarget) <= 1 and getSideOfLine(evadeToTarget1, getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, evadeToTarget1), directionTarget) ~= getSideOfLine(evadeToTarget3, getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, evadeToTarget3), directionTarget)) or (evadeToTarget2 ~= nil and evadeToTarget4 ~= nil and Line2(evadeToTarget2, evadeToTarget4):distance(directionTarget) <= 1 and getSideOfLine(evadeToTarget2, getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, evadeToTarget2), directionTarget) ~= getSideOfLine(evadeToTarget4, getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, evadeToTarget4), directionTarget)) or (evadeToTarget1 ~= nil and evadeToTarget3 == nil and getSideOfLine(heroPosition, evadeToTarget1, skillshot.startPosition) ~= getSideOfLine(heroPosition, evadeToTarget1, directionTarget)) or (evadeToTarget2 ~= nil and evadeToTarget4 == nil and getSideOfLine(heroPosition, evadeToTarget2, skillshot.startPosition) ~= getSideOfLine(heroPosition, evadeToTarget2, directionTarget)) then
  2302. evadeTarget = directionTarget
  2303. else
  2304. possibleMovementTargets = {}
  2305.  
  2306. if (evadeToTarget1 ~= nil and evadeToTarget3 ~= nil and Line2(evadeToTarget1, evadeToTarget3):distance(closestPoint2) <= 1 and getSideOfLine(evadeToTarget1, getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, evadeToTarget1), closestPoint2) ~= getSideOfLine(evadeToTarget3, getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, evadeToTarget3), closestPoint2)) or (evadeToTarget2 ~= nil and evadeToTarget4 ~= nil and Line2(evadeToTarget2, evadeToTarget4):distance(closestPoint2) <= 1 and getSideOfLine(evadeToTarget2, getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, evadeToTarget2), closestPoint2) ~= getSideOfLine(evadeToTarget4, getPerpendicularFootpoint(skillshot.startPosition, skillshot.endPosition, evadeToTarget4), closestPoint2)) or (evadeToTarget1 ~= nil and evadeToTarget3 == nil and getSideOfLine(heroPosition, evadeToTarget1, skillshot.startPosition) ~= getSideOfLine(heroPosition, evadeToTarget1, closestPoint2)) or (evadeToTarget2 ~= nil and evadeToTarget4 == nil and getSideOfLine(heroPosition, evadeToTarget2, skillshot.startPosition) ~= getSideOfLine(heroPosition, evadeToTarget2, closestPoint2)) then
  2307. table.insert(possibleMovementTargets, closestPoint2)
  2308. end
  2309.  
  2310. if evadeToTarget1 ~= nil then
  2311. table.insert(possibleMovementTargets, evadeToTarget1)
  2312. end
  2313.  
  2314. if evadeToTarget2 ~= nil then
  2315. table.insert(possibleMovementTargets, evadeToTarget2)
  2316. end
  2317.  
  2318. if evadeToTarget3 ~= nil then
  2319. table.insert(possibleMovementTargets, evadeToTarget3)
  2320. end
  2321.  
  2322. if evadeToTarget4 ~= nil then
  2323. table.insert(possibleMovementTargets, evadeToTarget4)
  2324. end
  2325.  
  2326. evadeTarget = findBestDirection(skillshot,getLastMovementDestination(), possibleMovementTargets)
  2327. end
  2328.  
  2329. if evadeTarget then
  2330. if getSideOfLine(skillshot.startPosition, skillshot.endPosition, evadeTarget) == getSideOfLine(skillshot.startPosition, skillshot.endPosition, getLastMovementDestination()) and skillshotLine:distance(getLastMovementDestination()) > evadeDistance then
  2331. pathDirectionVector = (evadeTarget - heroPosition)
  2332. if getSideOfLine(skillshot.startPosition, skillshot.endPosition, heroPosition) == getSideOfLine(skillshot.startPosition, skillshot.endPosition, evadeTarget) then
  2333. evadeTarget = evadeTarget + pathDirectionVector:normalized() * (pathDirectionVector:len() + smoothing / (evadeDistance - distanceFromSkillshotPath) * pathDirectionVector:len())
  2334. else
  2335. evadeTarget = evadeTarget + pathDirectionVector:normalized() * (pathDirectionVector:len() + smoothing / (evadeDistance + distanceFromSkillshotPath) * pathDirectionVector:len())
  2336. end
  2337. end
  2338. evadeTo(evadeTarget.x, evadeTarget.y, true, skillshot)
  2339. return true
  2340. else return false
  2341. end
  2342. return false
  2343. end
  2344.  
  2345. function lineSkillshot2(skillshot)
  2346. if haveShield() then
  2347. for i, detectedSkillshot in ipairs(detectedSkillshots) do
  2348. if detectedSkillshot.skillshot.name == skillshot.skillshot.name then
  2349. table.remove(detectedSkillshots, i)
  2350. i = i-1
  2351. if detectedSkillshot.evading then
  2352. continueMovement(detectedSkillshot)
  2353. end
  2354. end
  2355. end
  2356. if isSivir then
  2357. CastSpell(_E)
  2358. elseif isNocturne then
  2359. CastSpell(_W)
  2360. end
  2361. return true
  2362. elseif haveBlocked() then
  2363. for i, detectedSkillshot in ipairs(detectedSkillshots) do
  2364. if detectedSkillshot.skillshot.name == skillshot.skillshot.name then
  2365. table.remove(detectedSkillshots, i)
  2366. i = i-1
  2367. if detectedSkillshot.evading then
  2368. continueMovement(detectedSkillshot)
  2369. end
  2370. end
  2371. end
  2372. if isYasuo and GoodEvadeConfig.Skill.Block.blocking then
  2373. CastSpell(_W, blockPos.x, blockPos.z)
  2374. end
  2375. if isBraum and GoodEvadeConfig.Skill.Block.blocking then
  2376. CastSpell(_E, blockPos.x, blockPos.z)
  2377. end
  2378. return true
  2379. else
  2380. return false
  2381. end
  2382. return false
  2383. end
  2384.  
  2385. function lineSkillshot3(skillshot, evadeTo1, evadeTo2)
  2386. if not skillshot.alreadydashed then
  2387. local safeTarget = nil
  2388. if NeedDash(skillshot, true)
  2389. then if (evadeTo1:distance(lastMovement.destination) > evadeTo2:distance(lastMovement.destination)) and not InsideTheWall(evadeTo2) then
  2390. safeTarget = evadeTo2
  2391. elseif (evadeTo2:distance(lastMovement.destination) > evadeTo1:distance(lastMovement.destination)) and not InsideTheWall(evadeTo1) then
  2392. safeTarget = evadeTo1
  2393. elseif InsideTheWall(evadeTo2) then
  2394. safeTarget = evadeTo1
  2395. elseif InsideTheWall(evadeTo1) then
  2396. safeTarget = evadeTo2
  2397. end
  2398. if safeTarget ~= nil then
  2399. evadeTo(safeTarget.x, safeTarget.y, true, skillshot)
  2400. skillshot.alreadydashed = true
  2401. return true
  2402. else return false
  2403. end
  2404. else return false
  2405. end
  2406. else return false
  2407. end
  2408. return false
  2409. end
  2410.  
  2411. function lineSkillshot4(skillshot, evadeTo1, evadeTo2)
  2412. if GoodEvadeConfig.Skill.lineallways then
  2413. if skillshotLine:distance(evadeTo1) >= skillshotLine:distance(evadeTo2) then
  2414. if not InsideTheWall(evadeTo1) then
  2415. safeTarget = evadeTo1
  2416. elseif not InsideTheWall(evadeTo2) then
  2417. safeTarget = evadeTo2
  2418. else
  2419. safeTarget = getLastMovementDestination()
  2420. end
  2421.  
  2422. else
  2423. if not InsideTheWall(evadeTo2) then
  2424. safeTarget = evadeTo2
  2425. elseif not InsideTheWall(evadeTo1) then
  2426. safeTarget = evadeTo1
  2427. else
  2428. safeTarget = getLastMovementDestination()
  2429. end
  2430. end
  2431.  
  2432. if safeTarget ~= nil then
  2433. evadeTo(safeTarget.x, safeTarget.y, false, skillshot)
  2434. return true
  2435. else return false
  2436. end
  2437. else return false
  2438. end
  2439. return false
  2440. end
  2441.  
  2442. function dodgeDangerousLine1(skillshot)
  2443. if haveShield() then
  2444. for i, detectedSkillshot in ipairs(detectedSkillshots) do
  2445. if detectedSkillshot.skillshot.name == skillshot.skillshot.name then
  2446. table.remove(detectedSkillshots, i)
  2447. i = i-1
  2448. if detectedSkillshot.evading then
  2449. continueMovement(detectedSkillshot)
  2450. end
  2451. end
  2452. end
  2453. if isSivir then
  2454. CastSpell(_E)
  2455. elseif isNocturne then
  2456. CastSpell(_W)
  2457. end
  2458. return true
  2459. elseif haveBlocked() then
  2460. for i, detectedSkillshot in ipairs(detectedSkillshots) do
  2461. if detectedSkillshot.skillshot.name == skillshot.skillshot.name then
  2462. table.remove(detectedSkillshots, i)
  2463. i = i-1
  2464. if detectedSkillshot.evading then
  2465. continueMovement(detectedSkillshot)
  2466. end
  2467. end
  2468. end
  2469. blockPos = skillshot.startPosition
  2470. Blocking(skillshot.startPosition)
  2471. return true
  2472. else
  2473. return false
  2474. end
  2475. end
  2476.  
  2477. function dodgeDangerousLine2(skillshot, evadeTo1, evadeTo2)
  2478. local safeTarget = nil
  2479. if haveflash and useflash and GoodEvadeConfig.Skill.useSummonerFlash and not skillshot.alreadydashed
  2480. then if (evadeTo1:distance(lastMovement.destination) > evadeTo2:distance(lastMovement.destination)) and not InsideTheWall(evadeTo2) then
  2481. safeTarget = evadeTo2
  2482. elseif (evadeTo2:distance(lastMovement.destination) > evadeTo1:distance(lastMovement.destination)) and not InsideTheWall(evadeTo1) then
  2483. safeTarget = evadeTo1
  2484. elseif InsideTheWall(evadeTo2) then
  2485. safeTarget = evadeTo1
  2486. elseif InsideTheWall(evadeTo1) then
  2487. safeTarget = evadeTo2
  2488. end
  2489. if safeTarget ~= nil then
  2490. FlashTo(safeTarget.x, safeTarget.y)
  2491. skillshot.alreadydashed = true
  2492. return true
  2493. else return false
  2494. end
  2495. else return false
  2496. end
  2497. return false
  2498. end
  2499. -- end of line skillshot dodging functions --
  2500.  
  2501.  
  2502. class("ScriptUpdate")
  2503. function ScriptUpdate:__init(LocalVersion,UseHttps, Host, VersionPath, ScriptPath, SavePath, CallbackUpdate, CallbackNoUpdate, CallbackNewVersion,CallbackError)
  2504. self.LocalVersion = LocalVersion
  2505. self.Host = Host
  2506. self.VersionPath = '/BoL/TCPUpdater/GetScript'..(UseHttps and '5' or '6')..'.php?script='..self:Base64Encode(self.Host..VersionPath)..'&rand='..math.random(99999999)
  2507. self.ScriptPath = '/BoL/TCPUpdater/GetScript'..(UseHttps and '5' or '6')..'.php?script='..self:Base64Encode(self.Host..ScriptPath)..'&rand='..math.random(99999999)
  2508. self.SavePath = SavePath
  2509. self.CallbackUpdate = CallbackUpdate
  2510. self.CallbackNoUpdate = CallbackNoUpdate
  2511. self.CallbackNewVersion = CallbackNewVersion
  2512. self.CallbackError = CallbackError
  2513. AddDrawCallback(function() self:OnDraw() end)
  2514. self:CreateSocket(self.VersionPath)
  2515. self.DownloadStatus = 'Connect to Server for VersionInfo'
  2516. AddTickCallback(function() self:GetOnlineVersion() end)
  2517. end
  2518.  
  2519. function ScriptUpdate:print(str)
  2520. print('<font color="#FFFFFF">'..os.clock()..': '..str)
  2521. end
  2522.  
  2523. function ScriptUpdate:OnDraw()
  2524.  
  2525. if self.DownloadStatus ~= 'Downloading Script (100%)' and self.DownloadStatus ~= 'Downloading VersionInfo (100%)'then
  2526. DrawText('Download Status: '..(self.DownloadStatus or 'Unknown'),18,10,50,ARGB(0xFF,0xFF,0xFF,0xFF))
  2527. end
  2528.  
  2529. end
  2530.  
  2531. function ScriptUpdate:CreateSocket(url)
  2532.  
  2533. if not self.LuaSocket then
  2534. self.LuaSocket = require("socket")
  2535. else
  2536. self.Socket:close()
  2537. self.Socket = nil
  2538. self.Size = nil
  2539. self.RecvStarted = false
  2540. end
  2541.  
  2542. self.LuaSocket = require("socket")
  2543. self.Socket = self.LuaSocket.tcp()
  2544. self.Socket:settimeout(0, 'b')
  2545. self.Socket:settimeout(99999999, 't')
  2546. self.Socket:connect('sx-bol.eu', 80)
  2547. self.Url = url
  2548. self.Started = false
  2549. self.LastPrint = ""
  2550. self.File = ""
  2551. end
  2552.  
  2553. function ScriptUpdate:Base64Encode(data)
  2554.  
  2555. local b='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
  2556.  
  2557. return ((data:gsub('.', function(x)
  2558.  
  2559. local r,b='',x:byte()
  2560.  
  2561. for i=8,1,-1 do
  2562. r=r..(b%2^i-b%2^(i-1)>0 and '1' or '0')
  2563. end
  2564.  
  2565. return r;
  2566. end)..'0000'):gsub('%d%d%d?%d?%d?%d?', function(x)
  2567.  
  2568. if (#x < 6) then
  2569. return ''
  2570. end
  2571.  
  2572. local c=0
  2573.  
  2574. for i=1,6 do
  2575. c=c+(x:sub(i,i)=='1' and 2^(6-i) or 0)
  2576. end
  2577.  
  2578. return b:sub(c+1,c+1)
  2579. end)..({ '', '==', '=' })[#data%3+1])
  2580.  
  2581. end
  2582.  
  2583. function ScriptUpdate:GetOnlineVersion()
  2584.  
  2585. if self.GotScriptVersion then
  2586. return
  2587. end
  2588.  
  2589. self.Receive, self.Status, self.Snipped = self.Socket:receive(1024)
  2590.  
  2591. if self.Status == 'timeout' and not self.Started then
  2592. self.Started = true
  2593. self.Socket:send("GET "..self.Url.." HTTP/1.1\r\nHost: sx-bol.eu\r\n\r\n")
  2594. end
  2595.  
  2596. if (self.Receive or (#self.Snipped > 0)) and not self.RecvStarted then
  2597. self.RecvStarted = true
  2598. self.DownloadStatus = 'Downloading VersionInfo (0%)'
  2599. end
  2600.  
  2601. self.File = self.File .. (self.Receive or self.Snipped)
  2602.  
  2603. if self.File:find('</s'..'ize>') then
  2604.  
  2605. if not self.Size then
  2606. self.Size = tonumber(self.File:sub(self.File:find('<si'..'ze>')+6,self.File:find('</si'..'ze>')-1))
  2607. end
  2608.  
  2609. if self.File:find('<scr'..'ipt>') then
  2610.  
  2611. local _,ScriptFind = self.File:find('<scr'..'ipt>')
  2612. local ScriptEnd = self.File:find('</scr'..'ipt>')
  2613.  
  2614. if ScriptEnd then
  2615. ScriptEnd = ScriptEnd-1
  2616. end
  2617.  
  2618. local DownloadedSize = self.File:sub(ScriptFind+1,ScriptEnd or -1):len()
  2619.  
  2620. self.DownloadStatus = 'Downloading VersionInfo ('..math.round(100/self.Size*DownloadedSize,2)..'%)'
  2621. end
  2622.  
  2623. end
  2624.  
  2625. if self.File:find('</scr'..'ipt>') then
  2626. self.DownloadStatus = 'Downloading VersionInfo (100%)'
  2627.  
  2628. local a,b = self.File:find('\r\n\r\n')
  2629.  
  2630. self.File = self.File:sub(a,-1)
  2631. self.NewFile = ''
  2632.  
  2633. for line,content in ipairs(self.File:split('\n')) do
  2634.  
  2635. if content:len() > 5 then
  2636. self.NewFile = self.NewFile .. content
  2637. end
  2638.  
  2639. end
  2640.  
  2641. local HeaderEnd, ContentStart = self.File:find('<scr'..'ipt>')
  2642. local ContentEnd, _ = self.File:find('</sc'..'ript>')
  2643.  
  2644. if not ContentStart or not ContentEnd then
  2645.  
  2646. if self.CallbackError and type(self.CallbackError) == 'function' then
  2647. self.CallbackError()
  2648. end
  2649.  
  2650. else
  2651. self.OnlineVersion = (Base64Decode(self.File:sub(ContentStart+1,ContentEnd-1)))
  2652. self.OnlineVersion = tonumber(self.OnlineVersion)
  2653.  
  2654. if self.OnlineVersion > self.LocalVersion then
  2655.  
  2656. if self.CallbackNewVersion and type(self.CallbackNewVersion) == 'function' then
  2657. self.CallbackNewVersion(self.OnlineVersion,self.LocalVersion)
  2658. end
  2659.  
  2660. self:CreateSocket(self.ScriptPath)
  2661. self.DownloadStatus = 'Connect to Server for ScriptDownload'
  2662. AddTickCallback(function() self:DownloadUpdate() end)
  2663. else
  2664.  
  2665. if self.CallbackNoUpdate and type(self.CallbackNoUpdate) == 'function' then
  2666. self.CallbackNoUpdate(self.LocalVersion)
  2667. end
  2668.  
  2669. end
  2670.  
  2671. end
  2672.  
  2673. self.GotScriptVersion = true
  2674. end
  2675.  
  2676. end
  2677.  
  2678. function ScriptUpdate:DownloadUpdate()
  2679.  
  2680. if self.GotScriptUpdate then
  2681. return
  2682. end
  2683.  
  2684. self.Receive, self.Status, self.Snipped = self.Socket:receive(1024)
  2685.  
  2686. if self.Status == 'timeout' and not self.Started then
  2687. self.Started = true
  2688. self.Socket:send("GET "..self.Url.." HTTP/1.1\r\nHost: sx-bol.eu\r\n\r\n")
  2689. end
  2690.  
  2691. if (self.Receive or (#self.Snipped > 0)) and not self.RecvStarted then
  2692. self.RecvStarted = true
  2693. self.DownloadStatus = 'Downloading Script (0%)'
  2694. end
  2695.  
  2696. self.File = self.File .. (self.Receive or self.Snipped)
  2697.  
  2698. if self.File:find('</si'..'ze>') then
  2699.  
  2700. if not self.Size then
  2701. self.Size = tonumber(self.File:sub(self.File:find('<si'..'ze>')+6,self.File:find('</si'..'ze>')-1))
  2702. end
  2703.  
  2704. if self.File:find('<scr'..'ipt>') then
  2705.  
  2706. local _,ScriptFind = self.File:find('<scr'..'ipt>')
  2707. local ScriptEnd = self.File:find('</scr'..'ipt>')
  2708.  
  2709. if ScriptEnd then
  2710. ScriptEnd = ScriptEnd-1
  2711. end
  2712.  
  2713. local DownloadedSize = self.File:sub(ScriptFind+1,ScriptEnd or -1):len()
  2714.  
  2715. self.DownloadStatus = 'Downloading Script ('..math.round(100/self.Size*DownloadedSize,2)..'%)'
  2716. end
  2717.  
  2718. end
  2719.  
  2720. if self.File:find('</scr'..'ipt>') then
  2721. self.DownloadStatus = 'Downloading Script (100%)'
  2722.  
  2723. local a,b = self.File:find('\r\n\r\n')
  2724.  
  2725. self.File = self.File:sub(a,-1)
  2726. self.NewFile = ''
  2727.  
  2728. for line,content in ipairs(self.File:split('\n')) do
  2729.  
  2730. if content:len() > 5 then
  2731. self.NewFile = self.NewFile .. content
  2732. end
  2733.  
  2734. end
  2735.  
  2736. local HeaderEnd, ContentStart = self.NewFile:find('<sc'..'ript>')
  2737. local ContentEnd, _ = self.NewFile:find('</scr'..'ipt>')
  2738.  
  2739. if not ContentStart or not ContentEnd then
  2740.  
  2741. if self.CallbackError and type(self.CallbackError) == 'function' then
  2742. self.CallbackError()
  2743. end
  2744.  
  2745. else
  2746.  
  2747. local newf = self.NewFile:sub(ContentStart+1,ContentEnd-1)
  2748. local newf = newf:gsub('\r','')
  2749.  
  2750. if newf:len() ~= self.Size then
  2751.  
  2752. if self.CallbackError and type(self.CallbackError) == 'function' then
  2753. self.CallbackError()
  2754. end
  2755.  
  2756. return
  2757. end
  2758.  
  2759. local newf = Base64Decode(newf)
  2760.  
  2761. if type(load(newf)) ~= 'function' then
  2762.  
  2763. if self.CallbackError and type(self.CallbackError) == 'function' then
  2764. self.CallbackError()
  2765. end
  2766.  
  2767. else
  2768.  
  2769. local f = io.open(self.SavePath,"w+b")
  2770.  
  2771. f:write(newf)
  2772. f:close()
  2773.  
  2774. if self.CallbackUpdate and type(self.CallbackUpdate) == 'function' then
  2775. self.CallbackUpdate(self.OnlineVersion,self.LocalVersion)
  2776. end
  2777.  
  2778. end
  2779.  
  2780. end
  2781.  
  2782. self.GotScriptUpdate = true
  2783. end
  2784.  
  2785. end
  2786.  
  2787. --}
  2788. --{ old2dgeo
  2789.  
  2790.  
  2791. uniqueId2 = 0
  2792.  
  2793. -- Code ------------------------------------------------------------------------
  2794.  
  2795. class 'Point2' -- {
  2796. function Point2:__init(x, y)
  2797. uniqueId2 = uniqueId2 + 1
  2798. self.uniqueId2 = uniqueId2
  2799.  
  2800. self.x = x
  2801. self.y = y
  2802.  
  2803. self.points = {self}
  2804. end
  2805.  
  2806. function Point2:__type()
  2807. return "Point2"
  2808. end
  2809.  
  2810. function Point2:__eq(spatialObject)
  2811. return spatialObject:__type() == "Point2" and self.x == spatialObject.x and self.y == spatialObject.y
  2812. end
  2813.  
  2814. function Point2:__unm()
  2815. return Point2(-self.x, -self.y)
  2816. end
  2817.  
  2818. function Point2:__add(p)
  2819. return Point2(self.x + p.x, self.y + p.y)
  2820. end
  2821.  
  2822. function Point2:__sub(p)
  2823. return Point2(self.x - p.x, self.y - p.y)
  2824. end
  2825.  
  2826. function Point2:__mul(p)
  2827. if type(p) == "number" then
  2828. return Point2(self.x * p, self.y * p)
  2829. else
  2830. return Point2(self.x * p.x, self.y * p.y)
  2831. end
  2832. end
  2833.  
  2834. function Point2:tostring()
  2835. return "Point2(" .. tostring(self.x) .. ", " .. tostring(self.y) .. ")"
  2836. end
  2837.  
  2838. function Point2:__div(p)
  2839. if type(p) == "number" then
  2840. return Point2(self.x / p, self.y / p)
  2841. else
  2842. return Point2(self.x / p.x, self.y / p.y)
  2843. end
  2844. end
  2845.  
  2846. function Point2:between(point1, point2)
  2847. local normal = Line2(point1, point2):normal()
  2848.  
  2849. return Line2(point1, point1 + normal):side(self) ~= Line2(point2, point2 + normal):side(self)
  2850. end
  2851.  
  2852. function Point2:len()
  2853. return math.sqrt(self.x * self.x + self.y * self.y)
  2854. end
  2855.  
  2856. function Point2:normalize()
  2857. len = self:len()
  2858.  
  2859. self.x = self.x / len
  2860. self.y = self.y / len
  2861.  
  2862. return self
  2863. end
  2864.  
  2865. function Point2:clone()
  2866. return Point2(self.x, self.y)
  2867. end
  2868.  
  2869. function Point2:normalized()
  2870. local a = self:clone()
  2871. a:normalize()
  2872. return a
  2873. end
  2874.  
  2875. function Point2:getPoints()
  2876. return self.points
  2877. end
  2878.  
  2879. function Point2:getLineSegments()
  2880. return {}
  2881. end
  2882.  
  2883. function Point2:perpendicularFoot(line)
  2884. local distanceFromLine = line:distance(self)
  2885. local normalVector = line:normal():normalized()
  2886.  
  2887. local footOfPerpendicular = self + normalVector * distanceFromLine
  2888. if line:distance(footOfPerpendicular) > distanceFromLine then
  2889. footOfPerpendicular = self - normalVector * distanceFromLine
  2890. end
  2891.  
  2892. return footOfPerpendicular
  2893. end
  2894.  
  2895. function Point2:contains(spatialObject)
  2896. if spatialObject:__type() == "Line2" then
  2897. return false
  2898. elseif spatialObject:__type() == "Circle2" then
  2899. return spatialObject.point == self and spatialObject.radius == 0
  2900. else
  2901. for i, point in ipairs(spatialObject:getPoints()) do
  2902. if point ~= self then
  2903. return false
  2904. end
  2905. end
  2906. end
  2907.  
  2908. return true
  2909. end
  2910.  
  2911. function Point2:polar()
  2912. if math.close(self.x, 0) then
  2913. if self.y > 0 then return 90
  2914. elseif self.y < 0 then return 270
  2915. else return 0
  2916. end
  2917. else
  2918. local theta = math.deg(math.atan(self.y / self.x))
  2919. if self.x < 0 then theta = theta + 180 end
  2920. if theta < 0 then theta = theta + 360 end
  2921. return theta
  2922. end
  2923. end
  2924.  
  2925. function Point2:insideOf(spatialObject)
  2926. return spatialObject.contains(self)
  2927. end
  2928.  
  2929. function Point2:distance(spatialObject)
  2930. if spatialObject:__type() == "Point2" then
  2931. return math.sqrt((self.x - spatialObject.x)^2 + (self.y - spatialObject.y)^2)
  2932. elseif spatialObject:__type() == "Line2" then
  2933. denominator = (spatialObject.points[2].x - spatialObject.points[1].x)
  2934. if denominator == 0 then
  2935. return math.abs(self.x - spatialObject.points[2].x)
  2936. end
  2937.  
  2938. m = (spatialObject.points[2].y - spatialObject.points[1].y) / denominator
  2939.  
  2940. return math.abs((m * self.x - self.y + (spatialObject.points[1].y - m * spatialObject.points[1].x)) / math.sqrt(m * m + 1))
  2941. elseif spatialObject:__type() == "Circle2" then
  2942. return self:distance(spatialObject.point) - spatialObject.radius
  2943. elseif spatialObject:__type() == "LineSegment2" then
  2944. local t = ((self.x - spatialObject.points[1].x) * (spatialObject.points[2].x - spatialObject.points[1].x) + (self.y - spatialObject.points[1].y) * (spatialObject.points[2].y - spatialObject.points[1].y)) / ((spatialObject.points[2].x - spatialObject.points[1].x)^2 + (spatialObject.points[2].y - spatialObject.points[1].y)^2)
  2945.  
  2946. if t <= 0.0 then
  2947. return self:distance(spatialObject.points[1])
  2948. elseif t >= 1.0 then
  2949. return self:distance(spatialObject.points[2])
  2950. else
  2951. return self:distance(Line2(spatialObject.points[1], spatialObject.points[2]))
  2952. end
  2953. else
  2954. local minDistance = nil
  2955.  
  2956. for i, lineSegment in ipairs(spatialObject:getLineSegments()) do
  2957. if minDistance == nil then
  2958. minDistance = self:distance(lineSegment)
  2959. else
  2960. minDistance = math.min(minDistance, self:distance(lineSegment))
  2961. end
  2962. end
  2963.  
  2964. return minDistance
  2965. end
  2966. end
  2967. -- }
  2968.  
  2969. --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--
  2970.  
  2971. class 'Line2' -- {
  2972. function Line2:__init(point1, point2)
  2973. uniqueId2 = uniqueId2 + 1
  2974. self.uniqueId2 = uniqueId2
  2975.  
  2976. self.points = {point1, point2}
  2977. end
  2978.  
  2979. function Line2:__type()
  2980. return "Line2"
  2981. end
  2982.  
  2983. function Line2:__eq(spatialObject)
  2984. return spatialObject:__type() == "Line2" and self:distance(spatialObject) == 0
  2985. end
  2986.  
  2987. function Line2:getPoints()
  2988. return self.points
  2989. end
  2990.  
  2991. function Line2:getLineSegments()
  2992. return {}
  2993. end
  2994.  
  2995. function Line2:direction()
  2996. return self.points[2] - self.points[1]
  2997. end
  2998.  
  2999. function Line2:normal()
  3000. return Point2(- self.points[2].y + self.points[1].y, self.points[2].x - self.points[1].x)
  3001. end
  3002.  
  3003. function Line2:perpendicularFoot(point)
  3004. return point:perpendicularFoot(self)
  3005. end
  3006.  
  3007. function Line2:side(spatialObject)
  3008. leftPoints = 0
  3009. rightPoints = 0
  3010. onPoints = 0
  3011. for i, point in ipairs(spatialObject:getPoints()) do
  3012. local result = ((self.points[2].x - self.points[1].x) * (point.y - self.points[1].y) - (self.points[2].y - self.points[1].y) * (point.x - self.points[1].x))
  3013.  
  3014. if result < 0 then
  3015. leftPoints = leftPoints + 1
  3016. elseif result > 0 then
  3017. rightPoints = rightPoints + 1
  3018. else
  3019. onPoints = onPoints + 1
  3020. end
  3021. end
  3022.  
  3023. if leftPoints ~= 0 and rightPoints == 0 and onPoints == 0 then
  3024. return -1
  3025. elseif leftPoints == 0 and rightPoints ~= 0 and onPoints == 0 then
  3026. return 1
  3027. else
  3028. return 0
  3029. end
  3030. end
  3031.  
  3032. function Line2:contains(spatialObject)
  3033. if spatialObject:__type() == "Point2" then
  3034. return spatialObject:distance(self) == 0
  3035. elseif spatialObject:__type() == "Line2" then
  3036. return self.points[1]:distance(spatialObject) == 0 and self.points[2]:distance(spatialObject) == 0
  3037. elseif spatialObject:__type() == "Circle2" then
  3038. return spatialObject.point:distance(self) == 0 and spatialObject.radius == 0
  3039. elseif spatialObject:__type() == "LineSegment2" then
  3040. return spatialObject.points[1]:distance(self) == 0 and spatialObject.points[2]:distance(self) == 0
  3041. else
  3042. for i, point in ipairs(spatialObject:getPoints()) do
  3043. if point:distance(self) ~= 0 then
  3044. return false
  3045. end
  3046. end
  3047.  
  3048. return true
  3049. end
  3050.  
  3051. return false
  3052. end
  3053.  
  3054. function Line2:insideOf(spatialObject)
  3055. return spatialObject:contains(self)
  3056. end
  3057.  
  3058. function Line2:distance(spatialObject)
  3059. if spatialObject == nil then return 0 end
  3060. if spatialObject:__type() == "Circle2" then
  3061. return spatialObject.point:distance(self) - spatialObject.radius
  3062. elseif spatialObject:__type() == "Line2" then
  3063. distance1 = self.points[1]:distance(spatialObject)
  3064. distance2 = self.points[2]:distance(spatialObject)
  3065. if distance1 ~= distance2 then
  3066. return 0
  3067. else
  3068. return distance1
  3069. end
  3070. else
  3071. local minDistance = nil
  3072. for i, point in ipairs(spatialObject:getPoints()) do
  3073. distance = point:distance(self)
  3074. if minDistance == nil or distance <= minDistance then
  3075. minDistance = distance
  3076. end
  3077. end
  3078.  
  3079. return minDistance
  3080. end
  3081. end
  3082. -- }
  3083.  
  3084. --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--
  3085.  
  3086. class 'Circle2' -- {
  3087. function Circle2:__init(point, radius)
  3088. uniqueId2 = uniqueId2 + 1
  3089. self.uniqueId2 = uniqueId2
  3090.  
  3091. self.point = point
  3092. self.radius = radius
  3093.  
  3094. self.points = {self.point}
  3095. end
  3096.  
  3097. function Circle2:__type()
  3098. return "Circle2"
  3099. end
  3100.  
  3101. function Circle2:__eq(spatialObject)
  3102. return spatialObject:__type() == "Circle2" and (self.point == spatialObject.point and self.radius == spatialObject.radius)
  3103. end
  3104.  
  3105. function Circle2:getPoints()
  3106. return self.points
  3107. end
  3108.  
  3109. function Circle2:getLineSegments()
  3110. return {}
  3111. end
  3112.  
  3113. function Circle2:contains(spatialObject)
  3114. if spatialObject:__type() == "Line2" then
  3115. return false
  3116. elseif spatialObject:__type() == "Circle2" then
  3117. return self.radius >= spatialObject.radius + self.point:distance(spatialObject.point)
  3118. else
  3119. for i, point in ipairs(spatialObject:getPoints()) do
  3120. if self.point:distance(point) >= self.radius then
  3121. return false
  3122. end
  3123. end
  3124.  
  3125. return true
  3126. end
  3127. end
  3128.  
  3129. function Circle2:insideOf(spatialObject)
  3130. return spatialObject:contains(self)
  3131. end
  3132.  
  3133. function Circle2:distance(spatialObject)
  3134. return self.point:distance(spatialObject) - self.radius
  3135. end
  3136.  
  3137. function Circle2:intersectionPoints(spatialObject)
  3138. local result = {}
  3139.  
  3140. dx = self.point.x - spatialObject.point.x
  3141. dy = self.point.y - spatialObject.point.y
  3142. dist = math.sqrt(dx * dx + dy * dy)
  3143.  
  3144. if dist > self.radius + spatialObject.radius then
  3145. return result
  3146. elseif dist < math.abs(self.radius - spatialObject.radius) then
  3147. return result
  3148. elseif (dist == 0) and (self.radius == spatialObject.radius) then
  3149. return result
  3150. else
  3151. a = (self.radius * self.radius - spatialObject.radius * spatialObject.radius + dist * dist) / (2 * dist)
  3152. h = math.sqrt(self.radius * self.radius - a * a)
  3153.  
  3154. cx2 = self.point.x + a * (spatialObject.point.x - self.point.x) / dist
  3155. cy2 = self.point.y + a * (spatialObject.point.y - self.point.y) / dist
  3156.  
  3157. intersectionx1 = cx2 + h * (spatialObject.point.y - self.point.y) / dist
  3158. intersectiony1 = cy2 - h * (spatialObject.point.x - self.point.x) / dist
  3159. intersectionx2 = cx2 - h * (spatialObject.point.y - self.point.y) / dist
  3160. intersectiony2 = cy2 + h * (spatialObject.point.x - self.point.x) / dist
  3161.  
  3162. table.insert(result, Point2(intersectionx1, intersectiony1))
  3163.  
  3164. if intersectionx1 ~= intersectionx2 or intersectiony1 ~= intersectiony2 then
  3165. table.insert(result, Point2(intersectionx2, intersectiony2))
  3166. end
  3167. end
  3168.  
  3169. return result
  3170. end
  3171.  
  3172. function Circle2:tostring()
  3173. return "Circle2(Point2(" .. self.point.x .. ", " .. self.point.y .. "), " .. self.radius .. ")"
  3174. end
  3175. -- }
  3176.  
  3177. --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--
  3178.  
  3179. class 'LineSegment2' -- {
  3180. function LineSegment2:__init(point1, point2)
  3181. uniqueId2 = uniqueId2 + 1
  3182. self.uniqueId2 = uniqueId2
  3183.  
  3184. self.points = {point1, point2}
  3185. end
  3186.  
  3187. function LineSegment2:__type()
  3188. return "LineSegment2"
  3189. end
  3190.  
  3191. function LineSegment2:__eq(spatialObject)
  3192. return spatialObject:__type() == "LineSegment2" and ((self.points[1] == spatialObject.points[1] and self.points[2] == spatialObject.points[2]) or (self.points[2] == spatialObject.points[1] and self.points[1] == spatialObject.points[2]))
  3193. end
  3194.  
  3195. function LineSegment2:getPoints()
  3196. return self.points
  3197. end
  3198.  
  3199. function LineSegment2:getLineSegments()
  3200. return {self}
  3201. end
  3202.  
  3203. function LineSegment2:direction()
  3204. return self.points[2] - self.points[1]
  3205. end
  3206.  
  3207. function LineSegment2:len()
  3208. return (self.points[1] - self.points[2]):len()
  3209. end
  3210.  
  3211. function LineSegment2:contains(spatialObject)
  3212. if spatialObject:__type() == "Point2" then
  3213. return spatialObject:distance(self) == 0
  3214. elseif spatialObject:__type() == "Line2" then
  3215. return false
  3216. elseif spatialObject:__type() == "Circle2" then
  3217. return spatialObject.point:distance(self) == 0 and spatialObject.radius == 0
  3218. elseif spatialObject:__type() == "LineSegment2" then
  3219. return spatialObject.points[1]:distance(self) == 0 and spatialObject.points[2]:distance(self) == 0
  3220. else
  3221. for i, point in ipairs(spatialObject:getPoints()) do
  3222. if point:distance(self) ~= 0 then
  3223. return false
  3224. end
  3225. end
  3226.  
  3227. return true
  3228. end
  3229.  
  3230. return false
  3231. end
  3232.  
  3233. function LineSegment2:insideOf(spatialObject)
  3234. return spatialObject:contains(self)
  3235. end
  3236.  
  3237. function LineSegment2:distance(spatialObject)
  3238. if spatialObject:__type() == "Circle2" then
  3239. return spatialObject.point:distance(self) - spatialObject.radius
  3240. elseif spatialObject:__type() == "Line2" then
  3241. return math.min(self.points[1]:distance(spatialObject), self.points[2]:distance(spatialObject))
  3242. else
  3243. local minDistance = nil
  3244. for i, point in ipairs(spatialObject:getPoints()) do
  3245. distance = point:distance(self)
  3246. if minDistance == nil or distance <= minDistance then
  3247. minDistance = distance
  3248. end
  3249. end
  3250.  
  3251. return minDistance
  3252. end
  3253. end
  3254.  
  3255. function LineSegment2:intersects(spatialObject)
  3256. return #self:intersectionPoints(spatialObject) >= 1
  3257. end
  3258.  
  3259. function LineSegment2:intersectionPoints(spatialObject)
  3260. if spatialObject:__type() == "LineSegment2" then
  3261. d = (spatialObject.points[2].y - spatialObject.points[1].y) * (self.points[2].x - self.points[1].x) - (spatialObject.points[2].x - spatialObject.points[1].x) * (self.points[2].y - self.points[1].y)
  3262.  
  3263. if d ~= 0 then
  3264. ua = ((spatialObject.points[2].x - spatialObject.points[1].x) * (self.points[1].y - spatialObject.points[1].y) - (spatialObject.points[2].y - spatialObject.points[1].y) * (self.points[1].x - spatialObject.points[1].x)) / d
  3265. ub = ((self.points[2].x - self.points[1].x) * (self.points[1].y - spatialObject.points[1].y) - (self.points[2].y - self.points[1].y) * (self.points[1].x - spatialObject.points[1].x)) / d
  3266.  
  3267. if ua >= 0 and ua <= 1 and ub >= 0 and ub <= 1 then
  3268. return {Point2 (self.points[1].x + (ua * (self.points[2].x - self.points[1].x)), self.points[1].y + (ua * (self.points[2].y - self.points[1].y)))}
  3269. end
  3270. end
  3271. end
  3272.  
  3273. return {}
  3274. end
  3275.  
  3276. function LineSegment2:draw(color, width)
  3277. drawLine(self, color or 0XFF00FF00, width or 4)
  3278. end
  3279. -- }
  3280.  
  3281. --~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--
  3282.  
  3283. class 'Polygon2' -- {
  3284. function Polygon2:__init(...)
  3285. uniqueId2 = uniqueId2 + 1
  3286. self.uniqueId2 = uniqueId2
  3287.  
  3288. self.points = {...}
  3289. end
  3290.  
  3291. function Polygon2:__type()
  3292. return "Polygon2"
  3293. end
  3294.  
  3295. function Polygon2:__eq(spatialObject)
  3296. return spatialObject:__type() == "Polygon2" -- TODO
  3297. end
  3298.  
  3299. function Polygon2:getPoints()
  3300. return self.points
  3301. end
  3302.  
  3303. function Polygon2:addPoint(point)
  3304. table.insert(self.points, point)
  3305. self.lineSegments = nil
  3306. self.triangles = nil
  3307. end
  3308.  
  3309. function Polygon2:getLineSegments()
  3310. if self.lineSegments == nil then
  3311. self.lineSegments = {}
  3312. for i = 1, #self.points, 1 do
  3313. table.insert(self.lineSegments, LineSegment2(self.points[i], self.points[(i % #self.points) + 1]))
  3314. end
  3315. end
  3316.  
  3317. return self.lineSegments
  3318. end
  3319.  
  3320. function Polygon2:contains(spatialObject)
  3321. if spatialObject:__type() == "Line2" then
  3322. return false
  3323. elseif #self.points == 3 then
  3324. for i, point in ipairs(spatialObject:getPoints()) do
  3325. corner1DotCorner2 = ((point.y - self.points[1].y) * (self.points[2].x - self.points[1].x)) - ((point.x - self.points[1].x) * (self.points[2].y - self.points[1].y))
  3326. corner2DotCorner3 = ((point.y - self.points[2].y) * (self.points[3].x - self.points[2].x)) - ((point.x - self.points[2].x) * (self.points[3].y - self.points[2].y))
  3327. corner3DotCorner1 = ((point.y - self.points[3].y) * (self.points[1].x - self.points[3].x)) - ((point.x - self.points[3].x) * (self.points[1].y - self.points[3].y))
  3328.  
  3329. if not (corner1DotCorner2 * corner2DotCorner3 >= 0 and corner2DotCorner3 * corner3DotCorner1 >= 0) then
  3330. return false
  3331. end
  3332. end
  3333.  
  3334. if spatialObject:__type() == "Circle2" then
  3335. for i, lineSegment in ipairs(self:getLineSegments()) do
  3336. if spatialObject.point:distance(lineSegment) <= 0 then
  3337. return false
  3338. end
  3339. end
  3340. end
  3341.  
  3342. return true
  3343. else
  3344. for i, point in ipairs(spatialObject:getPoints()) do
  3345. inTriangles = false
  3346. for j, triangle in ipairs(self:triangulate()) do
  3347. if triangle:contains(point) then
  3348. inTriangles = true
  3349. break
  3350. end
  3351. end
  3352. if not inTriangles then
  3353. return false
  3354. end
  3355. end
  3356.  
  3357. return true
  3358. end
  3359. end
  3360.  
  3361. function Polygon2:insideOf(spatialObject)
  3362. return spatialObject.contains(self)
  3363. end
  3364.  
  3365. function Polygon2:direction()
  3366. if self.directionValue == nil then
  3367. local rightMostPoint = nil
  3368. local rightMostPointIndex = nil
  3369. for i, point in ipairs(self.points) do
  3370. if rightMostPoint == nil or point.x >= rightMostPoint.x then
  3371. rightMostPoint = point
  3372. rightMostPointIndex = i
  3373. end
  3374. end
  3375.  
  3376. rightMostPointPredecessor = self.points[(rightMostPointIndex - 1 - 1) % #self.points + 1]
  3377. rightMostPointSuccessor = self.points[(rightMostPointIndex + 1 - 1) % #self.points + 1]
  3378.  
  3379. z = (rightMostPoint.x - rightMostPointPredecessor.x) * (rightMostPointSuccessor.y - rightMostPoint.y) - (rightMostPoint.y - rightMostPointPredecessor.y) * (rightMostPointSuccessor.x - rightMostPoint.x)
  3380. if z > 0 then
  3381. self.directionValue = 1
  3382. elseif z < 0 then
  3383. self.directionValue = -1
  3384. else
  3385. self.directionValue = 0
  3386. end
  3387. end
  3388.  
  3389. return self.directionValue
  3390. end
  3391.  
  3392. function Polygon2:triangulate()
  3393. if self.triangles == nil then
  3394. self.triangles = {}
  3395.  
  3396. if #self.points > 3 then
  3397. tempPoints = {}
  3398. for i, point in ipairs(self.points) do
  3399. table.insert(tempPoints, point)
  3400. end
  3401.  
  3402. triangleFound = true
  3403. while #tempPoints > 3 and triangleFound do
  3404. triangleFound = false
  3405. for i, point in ipairs(tempPoints) do
  3406. point1Index = (i - 1 - 1) % #tempPoints + 1
  3407. point2Index = (i + 1 - 1) % #tempPoints + 1
  3408.  
  3409. point1 = tempPoints[point1Index]
  3410. point2 = tempPoints[point2Index]
  3411.  
  3412. if ((((point1.x - point.x) * (point2.y - point.y) - (point1.y - point.y) * (point2.x - point.x))) * self:direction()) < 0 then
  3413. triangleCandidate = Polygon2(point1, point, point2)
  3414.  
  3415. anotherPointInTriangleFound = false
  3416. for q = 1, #tempPoints, 1 do
  3417. if q ~= i and q ~= point1Index and q ~= point2Index and triangleCandidate:contains(tempPoints[q]) then
  3418. anotherPointInTriangleFound = true
  3419. break
  3420. end
  3421. end
  3422.  
  3423. if not anotherPointInTriangleFound then
  3424. table.insert(self.triangles, triangleCandidate)
  3425. table.remove(tempPoints, i)
  3426. i = i - 1
  3427.  
  3428. triangleFound = true
  3429. end
  3430. end
  3431. end
  3432. end
  3433.  
  3434. if #tempPoints == 3 then
  3435. table.insert(self.triangles, Polygon2(tempPoints[1], tempPoints[2], tempPoints[3]))
  3436. end
  3437. elseif #self.points == 3 then
  3438. table.insert(self.triangles, self)
  3439. end
  3440. end
  3441.  
  3442. return self.triangles
  3443. end
  3444.  
  3445. function Polygon2:intersects(spatialObject)
  3446. for i, lineSegment1 in ipairs(self:getLineSegments()) do
  3447. for j, lineSegment2 in ipairs(spatialObject:getLineSegments()) do
  3448. if lineSegment1:intersects(lineSegment2) then
  3449. return true
  3450. end
  3451. end
  3452. end
  3453.  
  3454. return false
  3455. end
  3456.  
  3457. function Polygon2:distance(spatialObject)
  3458. local minDistance = nil
  3459. for i, lineSegment in ipairs(self:getLineSegment()) do
  3460. distance = point:distance(self)
  3461. if minDistance == nil or distance <= minDistance then
  3462. minDistance = distance
  3463. end
  3464. end
  3465.  
  3466. return minDistance
  3467. end
  3468.  
  3469. function Polygon2:tostring()
  3470. local result = "Polygon2("
  3471.  
  3472. for i, point in ipairs(self.points) do
  3473. if i == 1 then
  3474. result = result .. point:tostring()
  3475. else
  3476. result = result .. ", " .. point:tostring()
  3477. end
  3478. end
  3479.  
  3480. return result .. ")"
  3481. end
  3482.  
  3483. function Polygon2:draw(color, width)
  3484. for i, lineSegment in ipairs(self:getLineSegments()) do
  3485. lineSegment:draw(color, width)
  3486. end
  3487. end
  3488. -- }
Add Comment
Please, Sign In to add comment