Dirac
22710180
- Reaction score
- 147
The fastest, easiest and with more flexible way to retrieve the nearest unit from a point
JASS:
library GetNearestUnit /* v1.1.1
*/uses/*
*/ MergeSort /* thehelper.net/forums/showthread.php/168621-MergeSort
*/ LinkedListModule /* thehelper.net/forums/showthread.php/168775-LinkedListModule
***********************************************************************
*
* function GetNearestUnit takes real x, real y, boolexpr filter returns unit
* function GetFarthestUnit takes real x, real y, boolexpr filter returns unit
*
* function GetNearestUnitEx takes real x, real y, real range, boolexpr filter, integer i returns unit
* function GetFarthestUnitEx takes real x, real y, real range, boolexpr filter, integer i returns unit
* - The extra integer argument skips that many units in the
* - list of near units.
* - Ex: If takes "2" then it would return the second nearest
* - unit.
*
***********************************************************************
*
* HOW TO USE:
*
* function SomeFilter takes nothing returns boolean
* return GetUnitTypeId(GetFilterUnit())=='hfoo'
* endfunction
*
* call GetNearestUnit(0,0,Filter(function SomeFilter)
*
* - In the example above the script would only pick the closest
* - footman from the point 0,0
*
**********************************************************************/
globals
//*********************************************************************
// Default circumference pick range for non extended functions.
private constant real DEFAULT_RANGE = 2000
endglobals
private struct List extends array
implement LinkedList
unit unit
real distance
//! runtextmacro MERGE_SORT("sort","v1.distance>v2.distance")
static method for takes real x, real y, real r, boolexpr c returns nothing
local List node
local unit e
call GroupEnumUnitsInRange(bj_lastCreatedGroup,x,y,r,c)
loop
set e = FirstOfGroup(bj_lastCreatedGroup)
exitwhen e==null
set node = List.allocate()
set node.unit = e
set node.distance = (GetUnitX(e)-x)*(GetUnitX(e)-x)+(GetUnitY(e)-y)*(GetUnitY(e)-y)
call base.insertNode(node)
call GroupRemoveUnit(bj_lastCreatedGroup,e)
endloop
call sort(base)
set e = null
endmethod
endstruct
function GetNearestUnitEx takes real x, real y, real r, boolexpr c, integer i returns unit
local List this = List.base
call List.for(x,y,r,c)
loop
set this = this.next
set i = i-1
exitwhen i==0 or this.head
endloop
call List.base.clearNode()
return this.unit
endfunction
function GetFarthestUnitEx takes real x, real y, real r, boolexpr c, integer i returns unit
local List this = List.base
call List.for(x,y,r,c)
loop
set this = this.prev
set i = i-1
exitwhen i==0 or this.head
endloop
call List.base.clearNode()
return this.unit
endfunction
function GetNearestUnit takes real x, real y, boolexpr c returns unit
return GetNearestUnitEx(x,y,DEFAULT_RANGE,c,1)
endfunction
function GetFarthestUnit takes real x, real y, boolexpr c returns unit
return GetFarthestUnitEx(x,y,DEFAULT_RANGE,c,1)
endfunction
endlibrary