Kain2030

Collision.lua

Sep 9th, 2013
667
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.08 KB | None | 0 0
  1. --[[
  2.     Collision 1.1.1 by Klokje
  3.     ========================================================================
  4.  
  5.    
  6.  
  7.     -- Class -----------------------------------------------------------
  8.     Collision(sRange, projSpeed, sDelay, sWidth)
  9.    
  10.  
  11.     -- Operations ------------------------------------------------------
  12.     GetMinionCollision(pStart, pEnd)
  13.     GetHeroCollision(pStart, pEnd, mode)
  14.     GetCollision(pStart, pEnd)
  15.     DrawCollision(pStart, pEnd)
  16.  
  17.     Changelog
  18.     ~~~~~~~~~
  19.  
  20.     1.0     - Initial release with Minion Collision and Hero Collision
  21.  
  22.     1.1     - Fixed bug with range check
  23.             - Inceased range for minions witdh 10
  24.  
  25.     1.1.1    - Fixed bug what some people had that minions not updated
  26. ]]
  27.  
  28. -- Load required libraries -----------------------------------------------------
  29. -- require "2DGeometry"
  30.  
  31.  
  32. -- Globals ---------------------------------------------------------------------
  33.  
  34. uniqueId = 0
  35.  
  36.  
  37. -- Code ------------------------------------------------------------------------
  38.  
  39. class 'Collision' -- {
  40.     HERO_ALL = 1
  41.     HERO_ENEMY = 2
  42.     HERO_ALLY = 3
  43.  
  44.  
  45.     function Collision:__init(sRange, projSpeed, sDelay, sWidth)
  46.         uniqueId = uniqueId + 1
  47.         self.uniqueId = uniqueId
  48.  
  49.         self.sRange = sRange
  50.         self.projSpeed = projSpeed
  51.         self.sDelay = sDelay
  52.         self.sWidth = sWidth/2
  53.  
  54.         self.enemyMinions = minionManager(MINION_ENEMY, 2000, myHero, MINION_SORT_HEALTH_ASC)
  55.         self.minionupdate = 0
  56.     end
  57.  
  58.     function Collision:GetMinionCollision(pStart, pEnd)
  59.         self.enemyMinions:update()
  60.  
  61.         local distance =  GetDistance(pStart, pEnd)
  62.         local prediction = TargetPredictionVIP(self.sRange, self.projSpeed, self.sDelay, self.sWidth)
  63.         local mCollision = {}
  64.  
  65.         if distance > self.sRange then
  66.             distance = self.sRange
  67.         end
  68.  
  69.         local V = Vector(pEnd) - Vector(pStart)
  70.         local k = V:normalized()
  71.         local P = V:perpendicular2():normalized()
  72.  
  73.         local t,i,u = k:unpack()
  74.         local x,y,z = P:unpack()
  75.  
  76.         local startLeftX = pStart.x + (x *self.sWidth)
  77.         local startLeftY = pStart.y + (y *self.sWidth)
  78.         local startLeftZ = pStart.z + (z *self.sWidth)
  79.         local endLeftX = pStart.x + (x * self.sWidth) + (t * distance)
  80.         local endLeftY = pStart.y + (y * self.sWidth) + (i * distance)
  81.         local endLeftZ = pStart.z + (z * self.sWidth) + (u * distance)
  82.        
  83.         local startRightX = pStart.x - (x * self.sWidth)
  84.         local startRightY = pStart.y - (y * self.sWidth)
  85.         local startRightZ = pStart.z - (z * self.sWidth)
  86.         local endRightX = pStart.x - (x * self.sWidth) + (t * distance)
  87.         local endRightY = pStart.y - (y * self.sWidth) + (i * distance)
  88.         local endRightZ = pStart.z - (z * self.sWidth)+ (u * distance)
  89.  
  90.         local startLeft = WorldToScreen(D3DXVECTOR3(startLeftX, startLeftY, startLeftZ))
  91.         local endLeft = WorldToScreen(D3DXVECTOR3(endLeftX, endLeftY, endLeftZ))
  92.         local startRight = WorldToScreen(D3DXVECTOR3(startRightX, startRightY, startRightZ))
  93.         local endRight = WorldToScreen(D3DXVECTOR3(endRightX, endRightY, endRightZ))
  94.        
  95.         local poly = Polygon(Point(startLeft.x, startLeft.y),  Point(endLeft.x, endLeft.y), Point(startRight.x, startRight.y),   Point(endRight.x, endRight.y))
  96.  
  97.          for index, minion in pairs(self.enemyMinions.objects) do
  98.             if minion ~= nil and minion.valid and not minion.dead then
  99.                 if GetDistance(pStart, minion) < distance then
  100.                     local pos, t, vec = prediction:GetPrediction(minion)
  101.                     local lineSegmentLeft = LineSegment(Point(startLeftX,startLeftZ), Point(endLeftX, endLeftZ))
  102.                     local lineSegmentRight = LineSegment(Point(startRightX,startRightZ), Point(endRightX, endRightZ))
  103.                     local toScreen, toPoint
  104.                     if pos ~= nil then
  105.                         toScreen = WorldToScreen(D3DXVECTOR3(minion.x, minion.y, minion.z))
  106.                         toPoint = Point(toScreen.x, toScreen.y)
  107.                     else
  108.                         toScreen = WorldToScreen(D3DXVECTOR3(minion.x, minion.y, minion.z))
  109.                         toPoint = Point(toScreen.x, toScreen.y)
  110.                     end
  111.  
  112.  
  113.                     if poly:contains(toPoint) then
  114.                         table.insert(mCollision, minion)
  115.                     else
  116.                         if pos ~= nil then
  117.                             distance1 = Point(pos.x, pos.z):distance(lineSegmentLeft)
  118.                             distance2 = Point(pos.x, pos.z):distance(lineSegmentRight)
  119.                         else
  120.                             distance1 = Point(minion.x, minion.z):distance(lineSegmentLeft)
  121.                             distance2 = Point(minion.x, minion.z):distance(lineSegmentRight)
  122.                         end
  123.                         if (distance1 < (getHitBoxRadius(minion)*2+10) or distance2 < (getHitBoxRadius(minion) *2+10)) then
  124.                             table.insert(mCollision, minion)
  125.                         end
  126.                     end
  127.                 end
  128.             end
  129.         end
  130.         if #mCollision > 0 then return true, mCollision else return false, mCollision end
  131.     end
  132.  
  133.     function Collision:GetHeroCollision(pStart, pEnd, mode)
  134.         if mode == nil then mode = HERO_ENEMY end
  135.         local heros = {}
  136.  
  137.         for i = 1, heroManager.iCount do
  138.             local hero = heroManager:GetHero(i)
  139.             if (mode == HERO_ENEMY or mode == HERO_ALL) and hero.team ~= myHero.team then
  140.                 table.insert(heros, hero)
  141.             elseif (mode == HERO_ALLY or mode == HERO_ALL) and hero.team == myHero.team and not hero.isMe then
  142.                 table.insert(heros, hero)
  143.             end
  144.         end
  145.  
  146.         local distance =  GetDistance(pStart, pEnd)
  147.         local prediction = TargetPredictionVIP(self.sRange, self.projSpeed, self.sDelay, self.sWidth)
  148.         local hCollision = {}
  149.  
  150.         if distance > self.sRange then
  151.             distance = self.sRange
  152.         end
  153.  
  154.         local V = Vector(pEnd) - Vector(pStart)
  155.         local k = V:normalized()
  156.         local P = V:perpendicular2():normalized()
  157.  
  158.         local t,i,u = k:unpack()
  159.         local x,y,z = P:unpack()
  160.  
  161.         local startLeftX = pStart.x + (x *self.sWidth)
  162.         local startLeftY = pStart.y + (y *self.sWidth)
  163.         local startLeftZ = pStart.z + (z *self.sWidth)
  164.         local endLeftX = pStart.x + (x * self.sWidth) + (t * distance)
  165.         local endLeftY = pStart.y + (y * self.sWidth) + (i * distance)
  166.         local endLeftZ = pStart.z + (z * self.sWidth) + (u * distance)
  167.        
  168.         local startRightX = pStart.x - (x * self.sWidth)
  169.         local startRightY = pStart.y - (y * self.sWidth)
  170.         local startRightZ = pStart.z - (z * self.sWidth)
  171.         local endRightX = pStart.x - (x * self.sWidth) + (t * distance)
  172.         local endRightY = pStart.y - (y * self.sWidth) + (i * distance)
  173.         local endRightZ = pStart.z - (z * self.sWidth)+ (u * distance)
  174.  
  175.         local startLeft = WorldToScreen(D3DXVECTOR3(startLeftX, startLeftY, startLeftZ))
  176.         local endLeft = WorldToScreen(D3DXVECTOR3(endLeftX, endLeftY, endLeftZ))
  177.         local startRight = WorldToScreen(D3DXVECTOR3(startRightX, startRightY, startRightZ))
  178.         local endRight = WorldToScreen(D3DXVECTOR3(endRightX, endRightY, endRightZ))
  179.        
  180.         local poly = Polygon(Point(startLeft.x, startLeft.y),  Point(endLeft.x, endLeft.y), Point(startRight.x, startRight.y),   Point(endRight.x, endRight.y))
  181.  
  182.         for index, hero in pairs(heros) do
  183.             if hero ~= nil and hero.valid and not hero.dead then
  184.                 if GetDistance(pStart, hero) < distance then
  185.                     local pos, t, vec = prediction:GetPrediction(hero)
  186.                     local lineSegmentLeft = LineSegment(Point(startLeftX,startLeftZ), Point(endLeftX, endLeftZ))
  187.                     local lineSegmentRight = LineSegment(Point(startRightX,startRightZ), Point(endRightX, endRightZ))
  188.                     local toScreen, toPoint
  189.                     if pos ~= nil then
  190.                         toScreen = WorldToScreen(D3DXVECTOR3(pos.x, hero.y, pos.z))
  191.                         toPoint = Point(toScreen.x, toScreen.y)
  192.                     else
  193.                         toScreen = WorldToScreen(D3DXVECTOR3(hero.x, hero.y, hero.z))
  194.                         toPoint = Point(toScreen.x, toScreen.y)
  195.                     end
  196.  
  197.  
  198.                     if poly:contains(toPoint) then
  199.                         table.insert(hCollision, hero)
  200.                     else
  201.                         if pos ~= nil then
  202.                             distance1 = Point(pos.x, pos.z):distance(lineSegmentLeft)
  203.                             distance2 = Point(pos.x, pos.z):distance(lineSegmentRight)
  204.                         else
  205.                             distance1 = Point(hero.x, hero.z):distance(lineSegmentLeft)
  206.                             distance2 = Point(hero.x, hero.z):distance(lineSegmentRight)
  207.                         end
  208.                         if (distance1 < (getHitBoxRadius(hero)*2+10) or distance2 < (getHitBoxRadius(hero) *2+10)) then
  209.                             table.insert(hCollision, hero)
  210.                         end
  211.                     end
  212.                 end
  213.             end
  214.         end
  215.         if #hCollision > 0 then return true, hCollision else return false, hCollision end
  216.     end
  217.  
  218.     function Collision:GetCollision(pStart, pEnd)
  219.         local b , minions = self:GetMinionCollision(pStart, pEnd)
  220.         local t , heros = self:GetHeroCollision(pStart, pEnd, HERO_ENEMY)
  221.  
  222.         if not b then return t, heros end
  223.         if not t then return b, minions end
  224.  
  225.         local all = {}
  226.  
  227.         for index, hero in pairs(heros) do
  228.             table.insert(all, hero)
  229.         end
  230.  
  231.         for index, minion in pairs(minions) do
  232.             table.insert(all, minion)
  233.         end
  234.  
  235.         return true, all
  236.     end
  237.  
  238.     function Collision:DrawCollision(pStart, pEnd)
  239.        
  240.         local distance =  GetDistance(pStart, pEnd)
  241.  
  242.         if distance > self.sRange then
  243.             distance = self.sRange
  244.         end
  245.  
  246.         local color = 4294967295
  247.  
  248.         local V = Vector(pEnd) - Vector(pStart)
  249.         local k = V:normalized()
  250.         local P = V:perpendicular2():normalized()
  251.  
  252.         local t,i,u = k:unpack()
  253.         local x,y,z = P:unpack()
  254.  
  255.         local startLeftX = pStart.x + (x *self.sWidth)
  256.         local startLeftY = pStart.y + (y *self.sWidth)
  257.         local startLeftZ = pStart.z + (z *self.sWidth)
  258.         local endLeftX = pStart.x + (x * self.sWidth) + (t * distance)
  259.         local endLeftY = pStart.y + (y * self.sWidth) + (i * distance)
  260.         local endLeftZ = pStart.z + (z * self.sWidth) + (u * distance)
  261.        
  262.         local startRightX = pStart.x - (x * self.sWidth)
  263.         local startRightY = pStart.y - (y * self.sWidth)
  264.         local startRightZ = pStart.z - (z * self.sWidth)
  265.         local endRightX = pStart.x - (x * self.sWidth) + (t * distance)
  266.         local endRightY = pStart.y - (y * self.sWidth) + (i * distance)
  267.         local endRightZ = pStart.z - (z * self.sWidth)+ (u * distance)
  268.  
  269.         local startLeft = WorldToScreen(D3DXVECTOR3(startLeftX, startLeftY, startLeftZ))
  270.         local endLeft = WorldToScreen(D3DXVECTOR3(endLeftX, endLeftY, endLeftZ))
  271.         local startRight = WorldToScreen(D3DXVECTOR3(startRightX, startRightY, startRightZ))
  272.         local endRight = WorldToScreen(D3DXVECTOR3(endRightX, endRightY, endRightZ))
  273.  
  274.         local colliton, objects = self:GetCollision(pStart, pEnd)
  275.        
  276.         if colliton then
  277.             color = 4294901760
  278.         end
  279.  
  280.         for i, object in pairs(objects) do
  281.             DrawCircle(object.x,object.y,object.z,getHitBoxRadius(object)*2+20,4294901760)
  282.         end
  283.  
  284.         DrawLine(startLeft.x, startLeft.y, endLeft.x, endLeft.y, 1, color)
  285.         DrawLine(startRight.x, startRight.y, endRight.x, endRight.y, 1, color)
  286.  
  287.     end
  288.  
  289.     function getHitBoxRadius(target)
  290.         return GetDistance(target, target.minBBox)/2
  291.     end
  292. -- }
Advertisement
Add Comment
Please, Sign In to add comment