• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

least health

Status
Not open for further replies.
Level 2
Joined
Oct 5, 2008
Messages
7
is there a way to select a unit from a group that has the least health in that group

i tried making it, but i couldnt get it to work, and it got really messy
im not very good with jass, so that might be the reason it didnt work



example if it was a function

set u = GetLowestHealth( g )

GetLowestHealth( g ) would return a unit that had the least amounth of health of the units in that group
 
Level 7
Joined
Oct 14, 2008
Messages
340
something like this?
JASS:
function GetLowestHealth takes unit group g returns unit
    local real a
    local unit u
    local unit returned_u
    loop
        exitwhen FirstOfGroup(g) == null
        set u = FirstOfGroup(g)
        if GetUnitLifePercent(u) < a then
            set a = GetUnitLifePercent(u)
            set returned_u = u
        endif
        call GroupRemoveUnit(g, u)
    endloop
    call DestroyGroup(g)
    set g = null
    return returned_u
endfunction
 
Level 6
Joined
Sep 5, 2007
Messages
264
JASS:
function DuplicateGroupEnum takes nothing returns nothing
    local unit u = GetEnumUnit()
    call GroupAddUnit(bj_groupAddGroupDest, u)
    set u = null
endfunction

function GetLowestHealth takes group g returns unit
    local unit u
    local real life
    local group ug = CreateGroup()
    
    local unit lowest_unit = null
    local real lowest_life = -1
    
    set bj_groupAddGroupDest = ug
    call ForGroup(g, function DuplicateGroupEnum)
    
    loop
        set u = FirstOfGroup(ug)
        exitwhen (u == null)
        
        set life = GetUnitState(u, UNIT_STATE_LIFE)
        if (life > 0) then
            if (life < lowest_life or lowest_life < 0) then
                set lowest_unit = u
                set lowest_life = life
            endif
        endif
        
        call GroupRemoveUnit(ug, u)
    endloop
    
    set u = null
    
    call DestroyGroup(ug)
    set ug = null
    
    return lowest_unit
endfunction
This particular example duplicates the group, then finds the unit in that group with the lowest health.

The reason that it copies the group is because this method of scanning removes units from the group as it goes. I take it that you'd want to keep the original group intact.

If not, remove the DuplicateGroupEnum() function and just change a few lines...

Remove these lines:
JASS:
local group ug = CreateGroup()

set bj_groupAddGroupDest = ug
call ForGroup(g, function DuplicateGroupEnum)

call DestroyGroup(ug)
set ug = null

Change these lines:
JASS:
set u = FirstOfGroup(ug)
// to
set u = FirstOfGroup(g)

call GroupRemoveUnit(ug, u)
// to
call GroupRemoveUnit(g, u)

I hope this is what you were after... :thumbs_up:

EDIT: Maximilianx, your's wouldn't quite work as it is...
JASS:
if GetUnitLifePercent(u) < a then
Won't ever activate if "a" is never set to anything... Like that "a" starts as 0. Therefore, the only value that could pass the GetUnitLifePercent() check must have less than 0 health. IE: they're already dead.
 
Level 6
Joined
Sep 5, 2007
Messages
264
It'd be better if you put it OVER 100, say 101... That way, if there's only 1 unit in the group and it has full health it'd still register.

Even if you wanted percentages, you'd be better off doing it my way, then converting to a percentage. The unit with the lowest health, is still going to have the lowest health in %.

Using GetUnitLifePercent(): :thumbs_down:
JASS:
function GetUnitLifePercent takes unit whichUnit returns real
    return GetUnitStatePercent(whichUnit, UNIT_STATE_LIFE, UNIT_STATE_MAX_LIFE)
endfunction

function GetUnitStatePercent takes unit whichUnit, unitstate whichState, unitstate whichMaxState returns real
    local real value    = GetUnitState(whichUnit, whichState)
    local real maxValue = GetUnitState(whichUnit, whichMaxState)

    // Return 0 for null units.
    if (whichUnit == null) or (maxValue == 0) then
        return 0.0
    endif

    return value / maxValue * 100.0
endfunction

My way: :thumbs_up:
JASS:
    local real life = GetUnitState(<unit>, UNIT_STATE_LIFE)

After the group has been scanned through, THEN convert to percentage using CURRENT LIFE / MAX LIFE.

Doing it that way would be MUCH faster, a lot less function calls. :thumbs_up:
 
Status
Not open for further replies.
Top