Miscellaneous Snippets

Status
Not open for further replies.

wonderpriest

New Member
Reaction score
18
GetNearestUnitMatching()

Here is a function I made earlier for some spells I was doing, and thought how it could be helpful to some people. YES, it does require JASS (a bit of custom script), but I did add a little extra feature to be nice to GUI users.

Use:
Pass it the correct parameters, and it will group units within a range, then sort them to find the one closest to the location you want. I used it in a few spells, and it's useful, at least to me. Also could be very useful in chain-spells, to find the next target.


Just stick the code into your custom script section, and call it through "custom script" actions (you can paste the comments in too if you're too lazy to remove them =P)
Here is the (heavily-commented) script here:
Code:
[COLOR=DimGray]//sourceX and sourceY are the cooridinates of the location (point in gui) that
 you'd like to be the center of our "selection circle"

//range is how far from the center (location defined by sourceX and sourceY)
 the function will reach to group units

//cond is the condition for grouping the units, for example you would make a 
condition that the enum("picked") unit is owned by player one, so that this 
function will only consider a unit that is owned by player one

//considerdead is a boolean that I need that I figured I'd add. If passed as 
true, a dead unit can be returned, and if false, dead units will not be 
considered. just pass this as false unless you know what you are doing, otherwise it could mess things up
[/COLOR]
function GetNearestUnitMatching takes real sourceX, real sourceY, real range, boolexpr cond, boolean considerdead returns unit
 local group g=CreateGroup()  [COLOR=DimGray]//create our group, that we will fill later[/COLOR]
 local unit current  [COLOR=DimGray] //used to reference our current cycle unit[/COLOR]
 local unit nearest  [COLOR=DimGray]//we'll set this unit to current unit when we need to[/COLOR]
 local real currentX   [color=dimgray]//[/color]
 local real currentY  [color=dimgray]//[/color]
 local real dist     [color=dimgray]//our locals to keep track of current cycle distance[/color]
 
   call GroupEnumUnitsInRange(g,sourceX,sourceY,range,cond)  [color=dimgray]//fill our group, according to our cond boolexpr[/color]
    
    loop                          [color=dimgray]//our cycle[/color]
     set current=FirstOfGroup(g) [color=dimgray]//new cycle unit (removed later)[/color]
      exitwhen current==null [color=dimgray]   //stop the cycle when no units are in the group[/color]
      
        set currentX=GetWidgetX(current)-sourceX                   [color=dimgray] // [/color]
        set currentY=GetWidgetY(current)-sourceY                [color=dimgray]   //[/color]
        set dist=SquareRoot(currentX*currentX+currentY*currentY)  [color=dimgray]//calculate our unit's distance from the source[/color]
       
         if dist<=range then [color=dimgray]//if our unit's distance is less than the max distance, then...[/color]
          
           if GetWidgetLife(current)>0.405 or considerdead then[color=dimgray] //0.405 is the cut-off for a dead unit, not zero as people would think[/color]
           
            set nearest=current[color=dimgray] //
                               //[/color]
            set range=dist   [color=dimgray] //if current unit is closer and meets our condition, set us up to compare the next cycle current[/color]

           endif 
        
         endif
       
          call GroupRemoveUnit(g,current)  [color=dimgray]//remove current so we don't consider him again[/color]
     endloop 
     
     set bj_lastHauntedGoldMine=nearest  [color=dimgray]//this is where i am nice to gui users. 
                                        //you must use a custom script action to call this function,
                                          // but instead of having to use more custom script to use the unit, 
                                         //you can select it in gui by using "Last Haunted Gold Mine"[/color]
     
     call DestroyGroup(g) [color=dimgray] //
                          //[/color]
     set g=null          [color=dimgray]//[/color]
     set current=null   [color=dimgray]//[/color]
     set nearest=null  [color=dimgray]// clean-up[/color]
     
      return bj_lastHauntedGoldMine [color=dimgray]//so you can apply the unit directly if not using gui, or instead of using "Last Haunted Gold Mine"[/color]
        
endfunction

EDIT: Okay I'm done. I wrote a whole tutorial down here about boolexprs and parameters and how to use custom script, but I figure it's better to keep it out :p
If you need help using this function or have any other question, don't hesitate to PM me.

ADD: Making the comments all gray was a pain in the arse =P WE NEED JASS TAGS!!!! And trigger tags I guess...
 

Andrewgosu

The Silent Pandaren Helper
Reaction score
716
A few JASS sniplets, if You are tired of messing with locations and removing the leaks, just to get the angle or distance between 2 units. Use "Custom script" action to call them. (Place the functions into Your maps header)

Basically the same as "Math - Angle Between Points", but it takes units as arguments instead of locations.

JASS:
function AngleBetweenUnits takes unit unitA, unit unitB returns real
    return bj_RADTODEG * Atan2(GetUnitY(unitB) - GetUnitY(unitA), GetUnitX(unitB) - GetUnitX(unitA))
endfunction


e.g, to find angle between the "Triggering unit" and "Target unit of ability being cast".

udg_tmpReal - global variable named tmpReal, real type.

"Custom Script: set udg_tmpreal = AngleBetweenUnits( GetTriggerUnit(), GetSpellTargetUnit() )"

"Math - Distance Between Points", but it takes units as arguments, thus, no need to mess with locations(points).

JASS:
function DistanceBetweenUnits takes unit unitA, unit unitB returns real
    local real xPos = GetUnitX(unitB) - GetUnitX(unitA)
    local real yPos = GetUnitY(unitB) - GetUnitY(unitA)
    return SquareRoot( xPos * xPos + yPos * yPos )
endfunction


e.g, to find the distance between "Triggering unit" and "Target unit of ability being cast".

"Custom script: set udg_tmpReal = DistanceBetweenUnits( GetTriggerUnit(), GetSpellTargetUnit() )"
 
Status
Not open for further replies.
General chit-chat
Help Users

      The Helper Discord

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top