>Because then you don't have to declare a local, create the group, destroy the group, and null the local.
I suppose, but it's not like it'd make a difference. It just makes it easier to implement, since you just paste it in and don't have to track a variable.
>The biggest problem with this method is the horribly long parameter list.
Here, with smaller functions:
I don't see how Silv's function is better. Ours are basically the same except mine does more. I can see where mine might look large and sloppy but it's very fast, especially if you use the range parameter to cut down the number of possible units to consider (much better to group units in, say, a 1000 distance than to pick out of the whole map).
I suppose, but it's not like it'd make a difference. It just makes it easier to implement, since you just paste it in and don't have to track a variable.
>The biggest problem with this method is the horribly long parameter list.
Here, with smaller functions:
JASS:
//***************************
//----GetUnitSomewhere by Quraji----
//***************************
//
// To use in your map simply paste this whole code into your custom script
// section, or an empty trigger (above all functions that will use this code)
//
//
// Contains two functions:
//
// SubtractGroupFromGroup takes group source, group todestroy...
// This function removes all units in a reference group (todestroy)from a
// source group (source).
// You must include it for GetUnitSomewhere(), but also feel free to use it for
// other functions
//
//
//
// GetUnitSomewhere takes real sourceX, real sourceY, real range, boolean outsiderange, boolean nearest, boolean considerdead, boolexpr cond returns unit
// Don't let the number of parameters scare you, this is easy to use. This
// function allows you to select the nearest or farthest unit inside or outside
// a designated circle.
//
// Parameters:
//
// real sourceX and real sourceY
// these are the X and Y coordinates of the point at the center of the area
// to be considered.
//
// real range
// this is the range of the function, or the radius of the area to be considered
// (a circle).
//
// boolean outsiderange
// if false, the function will consider units inside the circle, if true it will
// consider all units selected BUT the ones in the circle.
// (remember that the circle's radius is decided by the range parameter)
//
// boolean nearest
// if true, the function will select the nearest unit to the center point inside
// the area to be considered (as you'd expect a normal GetClosestUnit()
// function to do. if false, however, it will select the farthest unit
//
// boolean considerdead
// if false the function will ignore dead units.
// (leave this at false unless you need the function to select recently killed
// units)
//
// boolexpr cond
// finally, this is where you add your own conditions if you need them by
// using a boolexpr.
//
//
// Extra feature:
//
// This function sets the bj_lastHauntedGoldMine game variable to the unit
// it selects, as well as returning the unit. This enables JASS users to use
// the function as normal, but provides a convenience for GUI users, as they
// can simply select the unit from the drop down menu for any unit field by
// selecting "Last Haunted Gold Mine". This also allows all variables to be
// nulled.
//**********************
function SubtractGroupFromGroup takes group source, group todestroy returns group
local unit current
loop
set current = FirstOfGroup(todestroy)
exitwhen current==null
call GroupRemoveUnit(source, current)
call GroupRemoveUnit(todestroy, current)
endloop
set current = null
return source
endfunction
function GetUnitSomewhere takes real sourceX, real sourceY, real range, boolean outsiderange, boolean nearest, boolean considerdead, boolexpr cond returns unit
local group g=CreateGroup()
local group tempg=CreateGroup()
local unit current
local unit winner
local real currentX
local real currentY
local real dist
call GroupEnumUnitsInRange(g,sourceX,sourceY,range,cond)
if not nearest then
set range=.0
endif
if outsiderange then
call GroupEnumUnitsInRect(tempg,bj_mapInitialPlayableArea,cond)
set g = SubtractGroupFromGroup(tempg,g)
endif
loop
set current=FirstOfGroup(g)
exitwhen current==null
if GetWidgetLife(current)>0.405 or considerdead then
set currentX=GetWidgetX(current)-sourceX
set currentY=GetWidgetY(current)-sourceY
set dist=SquareRoot(currentX*currentX+currentY*currentY)
if outsiderange then
set range=dist
set outsiderange = not outsiderange
endif
if (nearest and dist<=range) or (not nearest and dist>=range) then
set winner=current
set range=dist
endif
endif
call GroupRemoveUnit(g,current)
endloop
call DestroyGroup(g)
call DestroyGroup(tempg)
set tempg=null
set g=null
set current=null
set bj_lastHauntedGoldMine=winner
set winner=null
return bj_lastHauntedGoldMine
endfunction
function GetUnitSomewhereEx takes real x, real y, real range returns unit
return GetUnitSomewhere(x,y,range,false,true,false,null)
endfunction
function GetUnitSomewhereExCond takes real x, real y, real range, boolexpr cond returns unit
return GetUnitSomewhere(x,y,range,false,true,false,cond)
endfunction
I don't see how Silv's function is better. Ours are basically the same except mine does more. I can see where mine might look large and sloppy but it's very fast, especially if you use the range parameter to cut down the number of possible units to consider (much better to group units in, say, a 1000 distance than to pick out of the whole map).