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

Help me with this function

Status
Not open for further replies.
I want to make every unit in range of the archmage ethereal, but I wonder what will be the right way...

  • For each (Integer A) from 1 to (Number of units in (Units within 500.00 of (Position of Archmage))), do (Actions)
    • Loop - Actions
      • Unit Group - Pick every unit in (Units within 500.00 of (Position of Archmage)) and do (Actions)
        • Loop - Actions
          • Unit - Add Banish self hero to (Picked unit)
          • Unit - Order (Picked unit) to Human Blood Mage - Banish (Picked unit)
          • Unit - Remove Banish self hero from (Picked unit)
?
 
Level 13
Joined
Mar 24, 2013
Messages
1,105
set temppoint = position of triggering unit
create a dummy at temppoint
set tempunit = last created unit
add expiration timer to tempunit
add banish to tempunit
set level of banish for tempunit if needed
set group = units within 500 of temppoint
pick every unit in group
set tempunit2 = picked unit
if tempunit2 == alive
any other conditions
then
Order tempunit to banish tempunit2

call RemoveLocation(udg_temppoint)
call DestroyGroup(udg_group)

You're currently leaking a lot, also there is no reason to do for each integer because you're picking every unit in the group.
 
Level 28
Joined
Sep 26, 2009
Messages
2,520
What you have there is that you pick every unit in 500 range of Archmage not once, but X times, where X is number of units in 500 range of Archmage.

so if there is only 1 unit, you will pick that unit once; if you have 16 units around him, you will pick each unit 16 times.

You still leak locations, look here: http://www.hiveworkshop.com/forums/triggers-scripts-269/things-leak-35124/

Lastly, I would do it via a dummy unit which casts Banish on all picked units.
 
set temppoint = position of triggering unit
create a dummy at temppoint
set tempunit = last created unit
add expiration timer to tempunit
add banish to tempunit
set level of banish for tempunit if needed
set group = units within 500 of temppoint
pick every unit in group
set tempunit2 = picked unit
if tempunit2 == alive
any other conditions
then
Order tempunit to banish tempunit2

call RemoveLocation(udg_temppoint)
call DestroyGroup(udg_group)

You're currently leaking a lot, also there is no reason to do for each integer because you're picking every unit in the group.

I posted my trigger not seriously. What I see from you is..ugh... why would I want to create dummy if it's already on the map? Ok, I have a dummy with the spell with cast range 99999 and Just need a way to pick every unit in range of 500 and cast banish on it. The banish itself has 30 sec duration.
here
  • Unit Group - Pick every unit in (Units within 500.00 of (Position of Archmage)) and do (Actions)
    • Loop - Actions
      • Unit - Order Dummy Rooter 0044 <gen> to Human Blood Mage - Banish (Picked unit)
but this dont seem to work
 
Level 11
Joined
Nov 15, 2007
Messages
800
I posted my trigger not seriously. What I see from you is..ugh... why would I want to create dummy if it's already on the map? Ok, I have a dummy with the spell with cast range 99999 and Just need a way to pick every unit in range of 500 and cast banish on it. The banish itself has 30 sec duration.
here
  • Unit Group - Pick every unit in (Units within 500.00 of (Position of Archmage)) and do (Actions)
    • Loop - Actions
      • Unit - Order Dummy Rooter 0044 <gen> to Human Blood Mage - Banish (Picked unit)
but this dont work

The dummy unit's order will be interrupted repeatedly because you're ordering it to cast on every unit in the area, and it will only be able to cast on the last unit in the group.

Most people create a dummy unit for every unit in the area with a timed life to solve this, but there's a much better way. To use a single dummy unit, you need to set its Movement - Type to "None" and Art - Cast Point to 0. This causes it to cast spells instantly removes the delay involved in the unit turning to face its target.

Your trigger still leaks like a broken faucet and doesn't filter out targets, though, which makes it less efficient and potentially less accurate.
 
The dummy unit's order will be interrupted repeatedly because you're ordering it to cast on every unit in the area, and it will only be able to cast on the last unit in the group.

Most people create a dummy unit for every unit in the area with a timed life to solve this, but there's a much better way. To use a single dummy unit, you need to set its Movement - Type to "None" and Art - Cast Point to 0. This causes it to cast spells instantly removes the delay involved in the unit turning to face its target.

Your trigger still leaks like a broken faucet and doesn't filter out targets, though, which makes it less efficient and potentially less accurate.

What do you mean? If I change the art - cast point the dummy will cast on every unit?

edit: What I want to to is to make the units untargetable physically, so will this do?
  • Unit Group - Pick every unit in (Units within 500.00 of (Position of Archmage)) and do (Actions)
    • Loop - Actions
      • Unit - Add classification of Ethereal to (Picked unit)
?
 
Level 28
Joined
Sep 26, 2009
Messages
2,520
Art - Cast Point is a time it takes since the start of cast to actual start of the spell's effect.

You ever saw that when for example orc Far Seer casts Chain Lightning, the lightning will shoot forth when he is in specific part of animation? It's not immediate... That is "Art - Cast Point".

If you were to set Art- Cast Point to 0.00, then before the unit would "wave its hands", the spell would be already over.

Same with movement type. Whenever you cast spell, the unit tries to face the targeted unit/point - this creates a small delay.

----
Setting movement type to none and Art - Cast Point to 0 will remove both delays and enable you to make 1 dummy unit to cast spell on X units immediately.
 
Level 10
Joined
Apr 18, 2009
Messages
601
My suggestion is this: for every unit within range, create a dummy with the banish ability and issue that dummy to banish its corresponding target. So if there were 3 units plus the archmage within range, our loop would create 4 dummy units. Each dummy unit would cast Banish on exactly one of the 4 units within range (because as you stated the question, the Archmage is within range of himself).

Here's that idea in triggers:
  • Banish Units Within Range
    • Events
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units within 500.00 of (Position of Archmage 0000 <gen>)) and do (Actions)
        • Loop - Actions
          • Unit - Create 1 Banish Caster (Dummy) for (Owner of (Picked unit)) at (Position of (Picked unit)) facing Default building facing degrees
          • Unit - Order (Last created unit) to Human Blood Mage - Banish (Picked unit)
          • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
Without memory leaks and with tweeks I personally would've wanted:
  • Banish Units Within Range Fixed
    • Events
    • Conditions
    • Actions
      • Set Temp_Point_A = (Position of Archmage 0000 <gen>)
      • Set Temp_Group_A = (Units within 516.00 of Temp_Point_A matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) is Mechanical) Equal to False)))
      • Custom script: call RemoveLocation(udg_Temp_Point_A)
      • Unit Group - Pick every unit in Temp_Group_A and do (Actions)
        • Loop - Actions
          • Set Temp_Point_A = (Position of (Picked unit))
          • Unit - Create 1 Banish Caster (Dummy) for (Owner of (Picked unit)) at Temp_Point_A facing Default building facing degrees
          • Custom script: call RemoveLocation(udg_Temp_Point_A)
          • Unit - Order (Last created unit) to Human Blood Mage - Banish (Picked unit)
      • Custom script: call DestroyGroup(udg_Temp_Group_A)
  • Banish Dummy Removal
    • Events
      • Unit - A unit enters (Playable map area)
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Banish Caster (Dummy)
    • Actions
      • Unit - Add a 2.00 second Generic expiration timer to (Triggering unit)
What the "Pick every unit in Unit Group" loop is saying is this:
1) Take a unit group.
2) For each iteration of the loop (for each lap), do this: pick a unit, which hasn't already been picked, from the unit group. "Picked Unit" will refer to this unit in this specific iteration of the loop.
So for example the loop would run 6 times if there were 6 units in the provided unit group. Right before each loop iteration started, "Picked Unit" would be set to refer to the next unpicked unit in the unit group. If there was no unpicked unit left in the group, the loop would terminate.

EDIT: Sorry mate, I understand from your first code example that you well enough know how the loop works, I must be tired to have putten that explanation in there. Anyway I'll leave the explanation in there if anybody less knowledgeable would come across this example.
 

Attachments

  • Banish Units Within Range Example Map.w3x
    17.1 KB · Views: 35
As a Map Maker I prefer to use the easiest way to do my job, and I don't like calculating variables much and complicated stuff, so I came with my own solution. Thank you for the answers anyway. Here it is and the topic is solved...

  • Unit Group - Pick every unit in (Units within 500.00 of (Position of Archmage) matching (((Matching unit) is A Hero) Equal to True)) and do (Actions)
    • Loop - Actions
      • Unit - Add Ethereal to (Picked unit)
 
Status
Not open for further replies.
Top