• 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.

[JASS] Unit Group - Remove Allies

Status
Not open for further replies.
Level 4
Joined
Jun 8, 2007
Messages
89
I have a unit group generated from units being in a radius, however, I need the unit group to only contain enemy units. How would I go about removing the allied ones?

-Thanks
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
PS. Sorry for the lack of BBCode, but Spanish keyboards seem to have problems with square brackets.

If you want to enumerate ONLY using enemies in the first place:

function SomeFilter takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(),-owner of the player who the spell relates to-)
endfunction

...

call GroupEnumUnitsInRange(someGroup,x,y,radius,Filter(function SomeFilter))

---------------------------------------------------

If you want to remove the units from a preexisting group,

function SomeEnum takes nothing returns nothing
if IsUnitAlly(GetEnumUnit(),-the player mentioned above-) then
call GroupRemoveUnit(-the group-,GetEnumUnit()
endif
endfunction

...

call ForGroup(-the group-,function SomeEnum)
 
Level 4
Joined
Jun 8, 2007
Messages
89
Okay, so that's basically what I have, but the code freezes up the the line.
Is there something wrong with this code?

JASS:
function chainCast takes unit attacker, unit target, integer damage, boolean canCrit, integer bounces, integer minBounceForRebounce, integer bounceWait, string abilityOrder, integer buffcode, real damageReduction, real aoe returns nothing
    local unit dummycaster
    local integer dtype = lastDmgType
    local integer coeff = lastCoeff
    local integer currentBounce = 1
    local unit temp = attacker
    local location loc = GetUnitLoc(temp)
    local location locTarget = GetUnitLoc(target)
    local group unitGroup
    local player pl = GetOwningPlayer(attacker)
    
    loop
    call BJDebugMsg("in chain loop")
            // cast a spell that gives a buff but does no dmg
        set dummycaster = CreateUnitAtLoc(pl, 'Hpal', loc, AngleBetweenPoints(loc, locTarget))
        call UnitAddAbility(dummycaster, 'A001')
        call IssueTargetOrder(dummycaster, abilityOrder, target)
        call UnitApplyTimedLife(dummycaster, 'BTLF', 1)
        
        loop
            exitwhen (GetUnitAbilityLevel(target, buffcode) > 0)
            call TriggerSleepAction(.29)
        endloop
        
        call BJDebugMsg("made it through the loop")
        
        call damageUnit(attacker, target, damage, ATTACK_TYPE_HERO, dtype, coeff, canCrit)
        
        set temp = target
            // get unit group
        call RemoveLocation(loc)
        set loc = GetUnitLoc(temp)
        
        call BJDebugMsg("new loc")
        
        call GroupEnumUnitsInRangeOfLoc(unitGroup, loc, aoe, Filter(function enemyFilter))
        
        call BJDebugMsg("unit group created")
        
        set damage = R2I(damage * damageReduction)
        
        exitwhen currentBounce == bounces
            // find new target
        set target = GroupPickRandomUnit(unitGroup)
        
        call RemoveLocation(locTarget)
        set locTarget = GetUnitLoc(target)
        
        set currentBounce = currentBounce + 1
        
            // wait between bounces
        if (bounceWait > 0) then
            call TriggerSleepAction(bounceWait)
        endif
    endloop
    
    call RemoveLocation(loc)
    
    set locTarget = null
    set loc = null
    set attacker = null
    set target = null
endfunction

"new loc" is printed to the screen but not "unit group created"

JASS:
function enemyFilter takes nothing returns boolean
    local unit u = GetFilterUnit()
    
    return (IsUnitEnemy(u, GetOwningPlayer(u)) and (GetUnitState(u, UNIT_STATE_LIFE) > 0))
endfunction
 
Last edited:
Level 12
Joined
Apr 27, 2008
Messages
1,228
(IsUnitEnemy(u, GetOwningPlayer(u)) and (GetUnitState(u, UNIT_STATE_LIFE) > 0))
Two things.
1. (GetUnitState(u, UNIT_STATE_LIFE) > 0) use 0.405 to be more accurate.
2. IsUnitEnemy(u, GetOwningPlayer(u)) What, you are having personal dilemmas - are you an enemy of yourself?
 
Level 4
Joined
Jun 8, 2007
Messages
89
(IsUnitEnemy(u, GetOwningPlayer(u)) and (GetUnitState(u, UNIT_STATE_LIFE) > 0))
Two things.
1. (GetUnitState(u, UNIT_STATE_LIFE) > 0) use 0.405 to be more accurate.
2. IsUnitEnemy(u, GetOwningPlayer(u)) What, you are having personal dilemmas - are you an enemy of yourself?

Out of curiosity, why 0.405? Nice catch, we all get those personal dilemmas occasionally... hehe
-Thanks a bunch

*EDIT* Ok, well I'm still getting the same error, and I hope I'm not being an idiot again... None of the debug messages inside of the filter are shown.

JASS:
library ChainSystem requires DamageSys

globals
    player chainCast_castingPlayer
endglobals

struct chaindata
    integer bounces
    integer minBounceForRebounce
    integer buffcode
    
    real bounceWait
    real damageReduction
    real aoe
    
    string abilityOrder
endstruct

function enemyFilter takes nothing returns boolean
    local unit u = GetFilterUnit()
    local boolean bool
    
    call BJDebugMsg("In Filter")
    
    set bool = (IsUnitEnemy(u, chainCast_castingPlayer) and (GetUnitState(u, UNIT_STATE_LIFE) > .405))
    
    if (bool) then
        call BJDebugMsg("True")
    else
        call BJDebugMsg("False")
    endif
    
    set u = null
    
    return bool
endfunction

function chainCast takes damagedata dmgdata, chaindata chainData returns nothing
    local unit dummycaster
    local integer currentBounce = 1
    local unit temp = dmgdata.attacker
    local location loc = GetUnitLoc(temp)
    local location locTarget = GetUnitLoc(dmgdata.target)
    local group unitGroup
    local player plyr = GetOwningPlayer(dmgdata.attacker)
    
    loop
    call BJDebugMsg("in chain loop")
            // cast a spell that gives a buff but does no dmg
        set dummycaster = CreateUnitAtLoc(plyr, 'Hpal', loc, AngleBetweenPoints(loc, locTarget))
        call UnitAddAbility(dummycaster, 'A001')
        call IssueTargetOrder(dummycaster, chainData.abilityOrder, dmgdata.target)
        call UnitApplyTimedLife(dummycaster, 'BTLF', 1)
        
        loop
            exitwhen (GetUnitAbilityLevel(dmgdata.target, chainData.buffcode) > 0)
            call TriggerSleepAction(.29)
        endloop
        
        call BJDebugMsg("made it through the loop")
        
        call damageUnit(dmgdata)
        
        set temp = dmgdata.target
            // get unit group
        call RemoveLocation(loc)
        set loc = GetUnitLoc(temp)
        
        call BJDebugMsg("new loc")
        
        set chainCast_castingPlayer = GetOwningPlayer(dmgdata.attacker)
        call GroupEnumUnitsInRangeOfLoc(unitGroup, loc, chainData.aoe, Filter(function enemyFilter))
        
        call BJDebugMsg("unit group created")
        
        set dmgdata.damage = R2I(dmgdata.damage * chainData.damageReduction)
        
        exitwhen currentBounce == chainData.bounces
            // find new target
        set dmgdata.target = GroupPickRandomUnit(unitGroup)
        
        call RemoveLocation(locTarget)
        set locTarget = GetUnitLoc(dmgdata.target)
        
        set currentBounce = currentBounce + 1
        
            // wait between bounces
        if (chainData.bounceWait > 0) then
            call TriggerSleepAction(chainData.bounceWait)
        endif
    endloop
    
    call RemoveLocation(loc)
    call chainData.destroy()
    call dmgdata.destroy()
    
    set locTarget = null
    set loc = null
endfunction

endlibrary

Any ideas? And thanks in advance for your time. =/
 
Level 8
Joined
Jul 23, 2005
Messages
329
Out of curiosity, why 0.405?
Its for the newly dead. Just as soon as you kill a unit, its health goes down to something like 0.405 (I can't remember the exact number, and I don't htink that was it) as it begins to decay. From there, it goes to 0.404, 0.403, 0.402, 0.401, and then 0.
So... its just to exclude the newly-dead.
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
Ain't sure about decaying, but a unit dies at 0.405. If you set a unit's life to 0.406 it will not die. Anything below equals to death.
Say which messages appear, and which do not(more specifically the ones not in the filter).
 
Level 4
Joined
Jun 8, 2007
Messages
89
call BJDebugMsg("new loc") will display, but any BJDebugMsg() calls afterwards do not, including call BJDebugMsg("In Filter"), call BJDebugMsg("True"), and call BJDebugMsg("false").
This leads me to believe that there is something wrong with my function call maybe, but I have no idea what...
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
So it stops here:
JASS:
loop
            exitwhen (GetUnitAbilityLevel(dmgdata.target, chainData.buffcode) > 0)
            call TriggerSleepAction(.29)
        endloop
So I suppose the problem is in the other structures(which you have not posted, so it would be rather hard to help).
 
Level 4
Joined
May 17, 2008
Messages
75
You have to initialize unitGroup by setting it to CreateGroup(). You can't enum units into a group that hasn't been created.

And IIRC a unit with exactly 0.405 hp is alive, but any less will kill it.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Its for the newly dead. Just as soon as you kill a unit, its health goes down to something like 0.405 (I can't remember the exact number, and I don't htink that was it) as it begins to decay. From there, it goes to 0.404, 0.403, 0.402, 0.401, and then 0.
So... its just to exclude the newly-dead.
Actually, when a unit's life hits .405 or below, it dies and its health is set to 0.

Therefore, there's no real reason to use it in a check of this type... the only application I can think of using .405 for is with onDamage systems.
 
Level 9
Joined
Apr 14, 2008
Messages
192
function chainCast takes unit attacker, unit target, integer damage, boolean canCrit, integer bounces, integer minBounceForRebounce, integer bounceWait, string abilityOrder, integer buffcode, real damageReduction, real aoe returns nothing
local unit dummycaster
local integer dtype = lastDmgType
local integer coeff = lastCoeff
local integer currentBounce = 1
local unit temp = attacker
local location loc = GetUnitLoc(temp)
local location locTarget = GetUnitLoc(target)
local group unitGroup
local player pl = GetOwningPlayer(attacker)

loop
call BJDebugMsg("in chain loop")
// cast a spell that gives a buff but does no dmg
set dummycaster = CreateUnitAtLoc(pl, 'Hpal', loc, AngleBetweenPoints(loc, locTarget))
call UnitAddAbility(dummycaster, 'A001')
call IssueTargetOrder(dummycaster, abilityOrder, target)
call UnitApplyTimedLife(dummycaster, 'BTLF', 1)

loop
exitwhen (GetUnitAbilityLevel(target, buffcode) > 0)
call TriggerSleepAction(.29)
endloop

call BJDebugMsg("made it through the loop")

call damageUnit(attacker, target, damage, ATTACK_TYPE_HERO, dtype, coeff, canCrit)

set temp = target
// get unit group
call RemoveLocation(loc)
set loc = GetUnitLoc(temp)

call BJDebugMsg("new loc")

call GroupEnumUnitsInRangeOfLoc(unitGroup, loc, aoe, Filter(function enemyFilter))

call BJDebugMsg("unit group created")

set damage = R2I(damage * damageReduction)

exitwhen currentBounce == bounces
// find new target
set target = GroupPickRandomUnit(unitGroup)

call RemoveLocation(locTarget)
set locTarget = GetUnitLoc(target)

set currentBounce = currentBounce + 1

// wait between bounces
if (bounceWait > 0) then
call TriggerSleepAction(bounceWait)
endif
endloop

call RemoveLocation(loc)

set locTarget = null
set loc = null
set attacker = null
set target = null
endfunction
__________________________________________
Leaks =- // Let it runn if only true
__________________________________________
 
Status
Not open for further replies.
Top