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

[General] How to periodically damage units in a group?

Status
Not open for further replies.
Level 11
Joined
Oct 11, 2012
Messages
711
How to periodically damage units in a group? (Trigger posted)

How to periodically damage all the units in a group?
I have tried the ForGroup and FirstofGroup method, but both didn't work.
Any idea guys? Thanks.

Edit: I have posted the trigger below
 
Last edited:
Level 22
Joined
Sep 24, 2005
Messages
4,821
Use timers to periodically apply damage.
Post the code, we need script details to answer that kind of question.
 
Level 11
Joined
Oct 11, 2012
Messages
711
Use timers to periodically apply damage.
Post the code, we need script details to answer that kind of question.

Periodic timer with FirstOfGroup loop :p

I will post the trigger when I get home, its on my desktop.
The problem is with the periodic timer and the FirstOfGroup loop, the units are removed from the group when the loop is done for the fist time period, such as
JASS:
function CallBack takes nothing returns nothing
   .....
   loop
       set u = FirstOfGroup(udg_group)
       exitwhen u == null
       call GroupRemoveUnit(udg_group,u)
       do damage....
   endloop
   ....
endfunction

function Example takes nothing returns nothing
   local timer t = CreateTimer()
   call TimerStart(t,0.20,true,function CallBack)
   ......
endfunction

In this way, the udg_group is empty after the first 0.20 second (the first run of the timer "t" in this example). The periodic timer actually becomes a one-time timer in this example...
 
Last edited:
Level 11
Joined
Oct 11, 2012
Messages
711
FirstOfGroup doesn't work with if you need to save the group for a period of time, unless you add the units into another temp group before performing the loop. I think a ForGroup would be more efficient for this case.

Simply use ForGroup. Do you have the code for your ForGroup method?

Thanks. I don't have the ForGroup code now, but its bascially the same as the following:
JASS:
function Damage takes nothing returns nothing
   ...
   call UnitDamageTarget(caster,target,....)
   ....
endfunction

function CallBack takes nothing returns nothing
   ...
   call ForGroup(udg_group, function Damage)
   ...
endfunction

function Spell takes nothing returns nothing
   local timer t=CreateTimer()
   call TimerStart(t,0.20,true, function Callback)
   ...
endfunction

First question: do I use the ForGroup correctly?
Second question: Is this efficient?
 
Thanks. I don't have the ForGroup code now, but its bascially the same as the following:
JASS:
function Damage takes nothing returns nothing
   ...
   call UnitDamageTarget(caster,target,....)
   ....
endfunction

function CallBack takes nothing returns nothing
   ...
   call ForGroup(udg_group, function Damage)
   ...
endfunction

function Spell takes nothing returns nothing
   local timer t=CreateTimer()
   call TimerStart(t,0.20,true, function Callback)
   ...
endfunction

First question: do I use the ForGroup correctly?
Second question: Is this efficient?

1) Looks pretty much okay to me. The equivalent of "Picked Unit" in JASS is GetEnumUnit(). You can use that in your Damage function to refer to the units that are in the group and being enumerated. So in fact, your target variable in your UnitDamageTarget should be GetEnumUnit().

2) ForGroup is just fine for group enumeration.
 
Level 11
Joined
Oct 11, 2012
Messages
711
1) Looks pretty much okay to me. The equivalent of "Picked Unit" in JASS is GetEnumUnit(). You can use that in your Damage function to refer to the units that are in the group and being enumerated. So in fact, your target variable in your UnitDamageTarget should be GetEnumUnit().

2) ForGroup is just fine for group enumeration.

Ugh, I think my problem is because I forgot to change target to GetEnumunit() as you pointed out....-_-
Thanks a lot. +Rep

BTW:
Can you tell me about using ForGroup? Do I need to remove group after I use ForGroup? Moreover, if I use local group in ForGroup, do I have to remove the group and then setting it to null?

Many thanks!
 
Ugh, I think my problem is because I forgot to change target to GetEnumunit() as you pointed out....-_-
Thanks a lot. +Rep

BTW:
Can you tell me about using ForGroup? Do I need to remove group after I use ForGroup? Moreover, if I use local group in ForGroup, do I have to remove the group and then setting it to null?

Many thanks!

Depends on what you want to do. If you're using groups that need to be retained over a period of time, only destroy the group when you don't need the group anymore. So no, you don't need to destroy the group after doing a ForGroup; only destroy the group once you don't need it anymore. An example:
JASS:
globals
    real Duration = 2.0 // spell duration
    real Period = 0.2 // timer period
endglobals

function EnumFunc takes nothing returns nothing
    local unit u = GetEnumUnit() // the enumerated unit
    ...
endfunction

function Periodic takes nothing returns nothing
    ...
    if Duration <= 0 then
        // spell duration is over! Destroy the group!
        call GroupClear(MyGroup)
        call DestroyGroup(MyGroup)
    else
        // don't destroy the group yet! Duration of the spell isn't over!
        call ForGroup(MyGroup, function EnumFunc)
        set Duration = Duration - Period
    endif
    ...
endfunction

function Spell takes nothing returns nothing
    local timer t = CreateTimer()
    call TimerStart(t, Period, true, function Periodic)
    ...
endfunction

If you're handling a group at a local scale, you should be using FirstOfGroup loops. If you're planning to retain a group over a period of time, you shouldn't be using locals in the first place. But yes, if you're using ForGroup for a local group, you need to destroy it before nulling it.
 
Level 11
Joined
Oct 11, 2012
Messages
711
Depends on what you want to do. If you're using groups that need to be retained over a period of time, only destroy the group when you don't need the group anymore. So no, you don't need to destroy the group after doing a ForGroup; only destroy the group once you don't need it anymore. An example:
JASS:
globals
    real Duration = 2.0 // spell duration
    real Period = 0.2 // timer period
endglobals

function EnumFunc takes nothing returns nothing
    local unit u = GetEnumUnit() // the enumerated unit
    ...
endfunction

function Periodic takes nothing returns nothing
    ...
    if Duration <= 0 then
        // spell duration is over! Destroy the group!
        call GroupClear(MyGroup)
        call DestroyGroup(MyGroup)
    else
        // don't destroy the group yet! Duration of the spell isn't over!
        call ForGroup(MyGroup, function EnumFunc)
        set Duration = Duration - Period
    endif
    ...
endfunction

function Spell takes nothing returns nothing
    local timer t = CreateTimer()
    call TimerStart(t, Period, true, function Periodic)
    ...
endfunction

If you're handling a group at a local scale, you should be using FirstOfGroup loops. If you're planning to retain a group over a period of time, you shouldn't be using locals in the first place. But yes, if you're using ForGroup for a local group, you need to destroy it before nulling it.

Thanks for the detailed answer, it really helps a lot! :)
 
Status
Not open for further replies.
Top