Get Nearest Destructible To Unit (MUI)

gref

New Member
Reaction score
33
This is a function that returns the nearest destructable in <radius> to a given <unit>.
Code:
GetNearestDestructableToUnit(<unit>, <radius>)

It works fine, and I'm using it to power the AI that makes a Night Elf Ancient Protector eat a tree when they are low on health. However, it's not MUI and I don't know of a way to make it MUI.
I tried attaching variables to GetTriggeringTrigger() but they didn't carry through (I'm assuming because this function is called, not directly in a trigger), and short of using arrays up to X units, and recycling (which aren't infintely MUI anyway, I'm lost on a solution).

Can someone please help?

(This would all be far easier if they were units and I could use unit groups)


Global variables:
Code:
globals
    real a_x
    real a_y
    real a_nearest_distance
    destructable a_nearest
endglobals

Function called on each destructable in range:
Code:
function CompareDestructableDistance takes nothing returns nothing
    local real nearest_distance = GetAttachedReal(GetTriggeringTrigger(), "cdd_nearest_distance")
    local real x
    local real y    
    local real x2
    local real y2
    
    local real current_distance    

    set nearest_distance = a_nearest_distance
    set x = a_x
    set y = a_y
                                               
    set x2 = GetDestructableX(GetEnumDestructable()) - x
    set y2 = GetDestructableY(GetEnumDestructable()) - y

    set current_distance = SquareRoot(x2*x2 + y2*y2)

    if (current_distance < nearest_distance)and(GetDestructableLife(GetEnumDestructable()) > 0) then   
        set a_nearest = GetEnumDestructable()
        set a_nearest_distance = current_distance
    endif

endfunction

Function calling the loop of destructables:
Code:
function GetNearestDestructableToUnit takes unit focus, real radius returns destructable
    local real centerX = GetUnitX(focus)
    local real centerY = GetUnitY(focus)
    local destructable nearest
    local rect r
    
    set a_nearest = null
    set a_nearest_distance = radius
    set a_x = centerX
    set a_y = centerY
    
    if (radius >= 0) then
        set bj_enumDestructableCenter = GetUnitLoc(focus)
        set bj_enumDestructableRadius = radius
        set r = Rect(centerX - radius, centerY - radius, centerX + radius, centerY + radius)
        call EnumDestructablesInRect(r, filterEnumDestructablesInCircleBJ, function CompareDestructableDistance)
        call RemoveRect(r)
    endif
    
    set nearest = a_nearest
            
    return nearest                         
endfunction
 

Pyrogasm

There are some who would use any excuse to ban me.
Reaction score
134
What are you fretting about with "MUI"?! It's a function call. Without waits. There's nothing to bug out about.

And you shouldn't need attaching, just a few globals, like so:
JASS:
library NearestDestructible initializer Init
    globals
        private destructable Nearest
        private real X
        private real Y
        private real NearestDistance
        private boolexpr BOOLEXPR_TRUE
    endglobals

    private function True takes nothing returns boolean
        return true
    endfunction

    private function Enum takes nothing returns nothing
        local destructable D = GetEnumDestructable()
        local real DX = GetDestructableX(D)
        local real DY = GetDestructableY(D)
        local real Distance = (X-DX)*(X-DX)+(Y-DY)*(Y-DY)

        if Distance &lt;= NearestDistance then
            set NearestDistance = Distance
            set Nearest = D
        endif

        set D = null
    endfunction

    function GetNearestDestructableToUnit takes unit Focus, real Radius returns destructable
        local rect R

        set X = GetUnitX(Focus)
        set Y = GetUnitY(Focus)
        set NearestDistance = Radius*Radius
        set Nearest = null

        set R = CreateRect(X-Radius, Y-Radius, X+Radius, Y+Radius)
        call EnumDestructablesInRect(R, BOOLEXPR_TRUE, function Enum)
        call RemoveRect(R)
        set R = null

        return Nearest
    endfunction

    private function Init takes nothing returns nothing
        set BOOLEXPR_TRUE = Condition(function True)
    endfunction
endlibrary
 

gref

New Member
Reaction score
33
Ok thanks... I had assumed that the amount of time taken by the function would be infinitessimaly small, however I don't know how multithreading or whatnot would affect it, so I wanted to be sure.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top