• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

ForUnitsInRange

Level 7
Joined
Apr 27, 2011
Messages
272
Here you go, yet another wrapper.

JASS:
library ForUnitsInRange
//===========================================================================
//	ForUnitsInRange by Alain.Mark
//
//  -Info-
//	 -Just a snippet to make units in range enumeration easier.
//
//	-How to Use-
//	 x: x-coordinate of source point
//	 y: y-coordinate of source point
//	 r: enumeration range
//	 "//! runtextmacro ForUnitsInRange("x","y","r")
//		(your code here, use "U" for the unit in range being evaluated)
//		ex: call KillUnit(U)
//	  //! runtextmacro EndForUnitsInRange()"
//
//===========================================================================
	globals
		unit  U
		group G=CreateGroup()
	endglobals
	
//===========================================================================
	//! textmacro ForUnitsInRange takes X, Y, R
		call GroupEnumUnitsInRange(G,$X$,$Y$,$R$,null)
		loop
			set U=FirstOfGroup(G)
			exitwhen U==null
	//! endtextmacro
	//! textmacro EndForUnitsInRange
			call GroupRemoveUnit(G,U)
		endloop
		
	//! endtextmacro
	
//===========================================================================
endlibrary
 
Last edited:
Here's a perfect version of your system:

JASS:
/***************************************
*
*   ForUnitsInRange
*   v1.0.0.0
*
*   - Efficient group enumeration made easier.
*   - Allows nested group enumerations.
*
*   API:
*   ----
*
*       - //! textmacro ForUnitsInRange takes x, y, range
*           - Used to iterate through units in range of a certain point.
*       - //! textmacro EndForUnitsInRange
*           - Used to end a ForUnitsInRange block.
*
*       - function GetEnumUnitEx takes nothing returns unit
*           - Returns the current unit.
*       - function GetEnumGroup takes nothing returns group
*           - Returns the enumerated group.
*       - function GetEnumX takes nothing returns real
*           - Returns the x-coordinate given in the textmacro.
*           - This could be useful incase you passed in a function call.
*           - That way, you wont have to cache it, you can just call this.
*       - function GetEnumY takes nothing returns real
*           - Returns the y-coordinate given in the textmacro.
*           - This could be useful incase you passed in a function call.
*           - That way, you wont have to cache it, you can just call this.
*       - function GetEnumRange takes nothing returns real
*           - Returns the range given in the textmacro.
*           - This could be useful incase you passed in a function call.
*           - That way, you wont have to cache it, you can just call this.
*
***************************************/
library ForUnitsInRange

    globals
        public constant real MAX_COLLISION_SIZE = 197.
        private group array g
        private unit array u
        private real array x
        private real array y
        private real array range
        private integer current = 0
    endglobals
    
    //! textmacro ForUnitsInRange takes x, y, range
        call StartEnumLoop($x$, $y$, $range$)
        call GroupEnumUnitsInRange(GetEnumGroup(), GetEnumX(), GetEnumY(), GetEnumRange() + ForUnitsInRange_MAX_COLLISION_SIZE, null)
        loop
            call SetEnumUnitEx(FirstOfGroup(GetEnumGroup()))
            exitwhen GetEnumUnitEx() == null
            call GroupRemoveUnit(GetEnumGroup(), GetEnumUnitEx())
            if IsUnitInRangeXY(GetEnumUnitEx(), GetEnumX(), GetEnumY(), GetEnumRange()) then
    //! endtextmacro
    
    //! textmacro EndForUnitsInRange
            endif
        endloop
        call EndEnumLoop()
    //! endtextmacro
    
    function GetEnumUnitEx takes nothing returns unit
        return u[current]
    endfunction
    
    function SetEnumUnitEx takes unit w returns nothing
        set u[current] = w
    endfunction
    
    function GetEnumGroup takes nothing returns group
        return g[current]
    endfunction
    
    function StartEnumLoop takes real v1, real v2, real v3 returns nothing
        set current = current + 1
        set x[current] = v1
        set y[current] = v2
        set range[current] = v3
        if g[current] == null then
            set g[current] = CreateGroup()
        endif
    endfunction
    
    function EndEnumLoop takes nothing returns nothing
        set current = current - 1
    endfunction
    
    function GetEnumX takes nothing returns real
        return x[current]
    endfunction
    
    function GetEnumY takes nothing returns real
        return y[current]
    endfunction
    
    function GetEnumRange takes nothing returns real
        return range[current]
    endfunction
    
endlibrary

And here's some demo code:

JASS:
struct Demo extends array
    
    private static location loc = Location(0,0)
    private static method getZ takes real x, real y returns real
        call MoveLocation(loc, x, y)
        return GetLocationZ(loc)
    endmethod
    
    private static method onInit takes nothing returns nothing
        local integer count = 0
        local unit u = null
        local lightning l
        local real x
        local real y
        local real z
        local integer lightnings = 0
        local integer i = 0
        
        loop
            call CreateUnit(Player(0), 'hpea', GetRandomReal(-1200, 1200), GetRandomReal(-1200, 1200), 270)
            set i = i + 1
            exitwhen i == 20
        endloop
        
        //! runtextmacro ForUnitsInRange("0", "0", "2048")
            set count = count + 1
        //! runtextmacro EndForUnitsInRange()
        
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "Number of units on the map: " + I2S(count))
        
        //! runtextmacro ForUnitsInRange("0", "0", "2048")
            set u = GetEnumUnitEx()
            set x = GetUnitX(u)
            set y = GetUnitY(u)
            set z = getZ(x, y)
            //! runtextmacro ForUnitsInRange("0", "0", "2048")
                if u != GetEnumUnitEx() then
                    set l = AddLightningEx("CLPB", false, x, y, z, GetUnitX(GetEnumUnitEx()), GetUnitY(GetEnumUnitEx()), getZ(GetUnitX(GetEnumUnitEx()), GetUnitY(GetEnumUnitEx())))
                    set lightnings = lightnings + 1
                endif
            //! runtextmacro EndForUnitsInRange()
        //! runtextmacro EndForUnitsInRange()
        
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, I2S(lightnings) + " lightnings have been created.")
        
        if lightnings == ((count*count)-count) then
            call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "The enumeration process is working perfectly.")
        else
            call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "There is a problem with the system. Either too many or too few lightnings have been created.")
        endif
        
        set l = null
        set u = null
    endmethod
endstruct

:3
 
Last edited:
Top