Advertisement
oli414

[CC] 3D A* Pathfinding API

Jun 21st, 2015
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.17 KB | None | 0 0
  1. --CC Pathfinding API by Oli414 - V0.9
  2.  
  3. local generatedPath = {}
  4. local checkPath = {}
  5. local map = {}
  6.  
  7. local function _getDistance(vec1, vec2)
  8.     return math.sqrt(math.pow(vec1.x - vec2.x, 2) + math.pow(vec1.y - vec2.y, 2) + math.pow(vec1.z - vec2.z, 2))
  9. end
  10.  
  11. local function _setDynamicTable(table, pos, value)
  12.     if table == nil then
  13.         table = {}
  14.     end
  15.     if table[pos.x] == nil then
  16.         table[pos.x] = {}
  17.     end
  18.     if table[pos.x][pos.y] == nil then
  19.         table[pos.x][pos.y] = {}
  20.     end
  21.     table[pos.x][pos.y][pos.z] = value
  22. end
  23.  
  24. local function _getDynamicTable(table, pos, value)
  25.     local returnValue = false
  26.     if value == nil then
  27.         returnValue = true
  28.     end
  29.     if table == nil then
  30.         return returnValue
  31.     end
  32.     if table[pos.x] == nil then
  33.         return returnValue
  34.     end
  35.     if table[pos.x][pos.y] == nil then
  36.         return returnValue
  37.     end
  38.     if table[pos.x][pos.y][pos.z] == nil then
  39.         return returnValue
  40.     end
  41.     if table[pos.x][pos.y][pos.z] == value then
  42.         return true
  43.     end
  44.     return false
  45. end
  46.  
  47. local function _getDynamicTableValue(table, pos)
  48.     if table == nil then
  49.         return nil
  50.     end
  51.     if table[pos.x] == nil then
  52.         return nil
  53.     end
  54.     if table[pos.x][pos.y] == nil then
  55.         return nil
  56.     end
  57.     if table[pos.x][pos.y][pos.z] == nil then
  58.         return nil
  59.     else
  60.         return table[pos.x][pos.y][pos.z]
  61.     end
  62. end
  63.  
  64. function setMapValue(position, value)
  65.     _setDynamicTable(map, position, value)
  66. end
  67.  
  68. function getMapValue(position)
  69.     return _getDynamicTableValue(map, position)
  70. end
  71.  
  72. function getMap()
  73.     return map
  74. end
  75.  
  76. function generatePath(from, to)
  77.     local checked = 1
  78.     local setCheck = 1
  79.     local distance = 0
  80.     local distances = {}
  81.     local distanceIndex = {}
  82.     generatedPath = {}
  83.     checkPath = {}
  84.    
  85.     checkPath[setCheck] = to
  86.     distances[setCheck] = _getDistance(to, from)
  87.     distanceIndex[setCheck] = 0
  88.    
  89.     setCheck = setCheck + 1
  90.    
  91.     while checked < setCheck do
  92.         os.queueEvent("randomEvent")
  93.         os.pullEvent()
  94.         local previousSetCheck = setCheck
  95.         local closest = nil
  96.         local minDistance = -1
  97.         for i = checked, previousSetCheck do
  98.             if distances[i] ~= nil then
  99.                 if distances[i] < minDistance or minDistance == -1 then
  100.                     closest = i
  101.                     minDistance = distances[i]
  102.                 end
  103.             end
  104.         end
  105.         if closest == nil then
  106.             return false
  107.         end
  108.         distance = distance + 1
  109.         if _getDynamicTable(map, checkPath[closest], nil) or _getDynamicTable(map, checkPath[closest], false) then
  110.             print(setCheck)
  111.             _setDynamicTable(generatedPath, checkPath[closest], distanceIndex[closest])
  112.             distances[closest] = nil
  113.             if checkPath[closest].x == from.x and checkPath[closest].y == from.y and checkPath[closest].z == from.z then
  114.                 return true
  115.             end
  116.             if _getDynamicTable(generatedPath, {x = checkPath[closest].x - 1, y = checkPath[closest].y, z = checkPath[closest].z}, nil) and (_getDynamicTable(map, {x = checkPath[closest].x - 1, y = checkPath[closest].y, z = checkPath[closest].z}, false) or _getDynamicTable(map, {x = checkPath[closest].x - 1, y = checkPath[closest].y, z = checkPath[closest].z}, nil)) then
  117.                 checkPath[setCheck] = {x = checkPath[closest].x - 1, y = checkPath[closest].y, z = checkPath[closest].z}
  118.                 distances[setCheck] = _getDistance(checkPath[setCheck], from)
  119.                 distanceIndex[setCheck] = distanceIndex[closest] + 1
  120.                 setCheck = setCheck + 1
  121.             end
  122.             if _getDynamicTable(generatedPath, {x = checkPath[closest].x + 1, y = checkPath[closest].y, z = checkPath[closest].z}, nil) and (_getDynamicTable(map, {x = checkPath[closest].x + 1, y = checkPath[closest].y, z = checkPath[closest].z}, false) or _getDynamicTable(map, {x = checkPath[closest].x + 1, y = checkPath[closest].y, z = checkPath[closest].z}, nil)) then
  123.                 checkPath[setCheck] = {x = checkPath[closest].x + 1, y = checkPath[closest].y, z = checkPath[closest].z}
  124.                 distances[setCheck] = _getDistance(checkPath[setCheck], from)
  125.                 distanceIndex[setCheck] = distanceIndex[closest] + 1
  126.                 setCheck = setCheck + 1
  127.             end
  128.             if _getDynamicTable(generatedPath, {x = checkPath[closest].x, y = checkPath[closest].y - 1, z = checkPath[closest].z}, nil) and (_getDynamicTable(map, {x = checkPath[closest].x, y = checkPath[closest].y - 1, z = checkPath[closest].z}, false) or _getDynamicTable(map, {x = checkPath[closest].x, y = checkPath[closest].y - 1, z = checkPath[closest].z}, nil)) then
  129.                 checkPath[setCheck] = {x = checkPath[closest].x, y = checkPath[closest].y - 1, z = checkPath[closest].z}
  130.                 distances[setCheck] = _getDistance(checkPath[setCheck], from)
  131.                 distanceIndex[setCheck] = distanceIndex[closest] + 1
  132.                 setCheck = setCheck + 1
  133.             end
  134.             if _getDynamicTable(generatedPath, {x = checkPath[closest].x, y = checkPath[closest].y + 1, z = checkPath[closest].z}, nil) and (_getDynamicTable(map, {x = checkPath[closest].x, y = checkPath[closest].y + 1, z = checkPath[closest].z}, false) or _getDynamicTable(map, {x = checkPath[closest].x, y = checkPath[closest].y + 1, z = checkPath[closest].z}, nil)) then
  135.                 checkPath[setCheck] = {x = checkPath[closest].x, y = checkPath[closest].y + 1, z = checkPath[closest].z}
  136.                 distances[setCheck] = _getDistance(checkPath[setCheck], from)
  137.                 distanceIndex[setCheck] = distanceIndex[closest] + 1
  138.                 setCheck = setCheck + 1
  139.             end
  140.             if _getDynamicTable(generatedPath, {x = checkPath[closest].x, y = checkPath[closest].y, z = checkPath[closest].z - 1}, nil) and (_getDynamicTable(map, {x = checkPath[closest].x, y = checkPath[closest].y, z = checkPath[closest].z - 1}, false) or _getDynamicTable(map, {x = checkPath[closest].x, y = checkPath[closest].y, z = checkPath[closest].z - 1}, nil)) then
  141.                 checkPath[setCheck] = {x = checkPath[closest].x, y = checkPath[closest].y, z = checkPath[closest].z - 1}
  142.                 distances[setCheck] = _getDistance(checkPath[setCheck], from)
  143.                 distanceIndex[setCheck] = distanceIndex[closest] + 1
  144.                 setCheck = setCheck + 1
  145.             end
  146.             if _getDynamicTable(generatedPath, {x = checkPath[closest].x, y = checkPath[closest].y, z = checkPath[closest].z + 1}, nil) and (_getDynamicTable(map, {x = checkPath[closest].x, y = checkPath[closest].y, z = checkPath[closest].z + 1}, false) or _getDynamicTable(map, {x = checkPath[closest].x, y = checkPath[closest].y, z = checkPath[closest].z + 1}, nil)) then
  147.                 checkPath[setCheck] = {x = checkPath[closest].x, y = checkPath[closest].y, z = checkPath[closest].z + 1}
  148.                 distances[setCheck] = _getDistance(checkPath[setCheck], from)
  149.                 distanceIndex[setCheck] = distanceIndex[closest] + 1
  150.                 setCheck = setCheck + 1
  151.             end
  152.             checkPath[closest] = nil
  153.         end
  154.     end
  155. end
  156.  
  157. function getPath(from)
  158.     if _getDynamicTableValue(generatedPath, from) ~= nil then
  159.         if _getDynamicTableValue(generatedPath, {x = from.x - 1, y = from.y, z = from.z}) ~= nil and _getDynamicTableValue(generatedPath, {x = from.x - 1, y = from.y, z = from.z}) < _getDynamicTableValue(generatedPath, from) then
  160.             return {x = from.x - 1, y = from.y, z = from.z}
  161.         elseif _getDynamicTableValue(generatedPath, {x = from.x + 1, y = from.y, z = from.z}) ~= nil and _getDynamicTableValue(generatedPath, {x = from.x + 1, y = from.y, z = from.z}) < _getDynamicTableValue(generatedPath, from) then
  162.             return {x = from.x + 1, y = from.y, z = from.z}
  163.         elseif _getDynamicTableValue(generatedPath, {x = from.x, y = from.y - 1, z = from.z}) ~= nil and _getDynamicTableValue(generatedPath, {x = from.x, y = from.y - 1, z = from.z}) < _getDynamicTableValue(generatedPath, from) then
  164.             return {x = from.x, y = from.y - 1, z = from.z}
  165.         elseif _getDynamicTableValue(generatedPath, {x = from.x, y = from.y + 1, z = from.z}) ~= nil and _getDynamicTableValue(generatedPath, {x = from.x, y = from.y + 1, z = from.z}) < _getDynamicTableValue(generatedPath, from) then
  166.             return {x = from.x, y = from.y + 1, z = from.z}
  167.         elseif _getDynamicTableValue(generatedPath, {x = from.x, y = from.y, z = from.z - 1}) ~= nil and _getDynamicTableValue(generatedPath, {x = from.x, y = from.y, z = from.z - 1}) < _getDynamicTableValue(generatedPath, from) then
  168.             return {x = from.x, y = from.y, z = from.z - 1}
  169.         elseif _getDynamicTableValue(generatedPath, {x = from.x, y = from.y, z = from.z + 1}) ~= nil and _getDynamicTableValue(generatedPath, {x = from.x, y = from.y, z = from.z + 1}) < _getDynamicTableValue(generatedPath, from) then
  170.             return {x = from.x, y = from.y, z = from.z + 1}
  171.         else
  172.             return nil
  173.         end
  174.     end
  175.     return nil
  176. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement