• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Trigger] Problem with Unit Group Spells

Status
Not open for further replies.
Level 9
Joined
Feb 15, 2013
Messages
372
After i made this spell, i tested with an enemy unit, then i put some allies nearby it and tested it... It do damaged nearby allies
The Area Damage is only unlock at Level 3 of the abilities

Here's the trigger
[trigger="Slice a Piece"]
Slice a Piece
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Slice a Piece
Actions
Set Slice_X = (Slice_X + 1)
Set Slice_Caster[Slice_X] = (Triggering unit)
Set Slice_Target[Slice_X] = (Target unit of ability being cast)
Set Slice_Damage[1] = (75.00 + ((25.00 + (15.00 x (Real((Hero level of Slice_Caster[Slice_X]))))) + (1.75 x (Real(((Owner of Slice_Caster[Slice_X]) Current gold))))))
Set Slice_Damage[2] = (100.00 + ((25.00 + (15.00 x (Real((Hero level of Slice_Caster[Slice_X]))))) + (1.75 x (Real(((Owner of Slice_Caster[Slice_X]) Current gold))))))
Set Slice_Damage[3] = (125.00 + ((25.00 + (15.00 x (Real((Hero level of Slice_Caster[Slice_X]))))) + (1.75 x (Real(((Owner of Slice_Caster[Slice_X]) Current gold))))))
Set Slice_Level = (Level of (Ability being cast) for Slice_Caster[Slice_X])
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
Slice_Level Equal to 3
Then - Actions
Set Slice_Group[Slice_X] = (Units within 380.00 of (Position of Slice_Target[Slice_X]) matching ((((Matching unit) is A structure) Equal to False) or ((((Matching unit) is alive) Equal to True) or (((Matching unit) belongs to an enemy of (Owner of Slice_Caster[Slice_X])) Equal to True)
Unit Group - Pick every unit in Slice_Group[Slice_X] and do (Actions)
Loop - Actions
Set Slice_GroupTarget[Slice_X] = (Picked unit)
Unit - Cause Slice_Caster[Slice_X] to damage Slice_GroupTarget[Slice_X], dealing 85.00 damage of attack type Spells and damage type Normal
Special Effect - Create a special effect attached to the origin of Slice_Target[Slice_X] using Abilities\Spells\Human\Thunderclap\ThunderClapCaster.mdl
Unit - Cause Slice_Caster[Slice_X] to damage Slice_Target[Slice_X], dealing Slice_Damage[Slice_Level] damage of attack type Magic and damage type Lightning
Special Effect - Destroy (Last created special effect)
Else - Actions
Special Effect - Create a special effect attached to the origin of Slice_Target[Slice_X] using Abilities\Spells\Human\Thunderclap\ThunderClapCaster.mdl
Unit - Cause Slice_Caster[Slice_X] to damage Slice_Target[Slice_X], dealing Slice_Damage[Slice_Level] damage of attack type Magic and damage type Lightning
Special Effect - Destroy (Last created special effect)
Wait 0.50 seconds
Set Slice_Caster[Slice_X] = No unit
Set Slice_Target[Slice_X] = No unit
Set Slice_GroupTarget[Slice_X] = No unit
Custom script: call DestroyGroup(udg_Slice_Group[udg_Slice_X])
Set Slice_X = (Slice_X - 1)
[/Trigger]
 
Level 12
Joined
Oct 16, 2010
Messages
680
  • Set Slice_Group[Slice_X] = (Units within 380.00 of (Position of Slice_Target[Slice_X]) matching ((((Matching unit) is A structure) Equal to False) or ((((Matching unit) is alive) Equal to True) or (((Matching unit) belongs to an enemy of (Owner of Slice_Caster[Slice_X])) Equal to True)
replace all the "or" with "and"
 

Deleted member 219079

D

Deleted member 219079

I had problems with arrayed unit groups in my GUI days too.
Have you tried setting the initial size of 8190?
 
Level 9
Joined
Feb 15, 2013
Messages
372
  • Set Slice_Group[Slice_X] = (Units within 380.00 of (Position of Slice_Target[Slice_X]) matching ((((Matching unit) is A structure) Equal to False) or ((((Matching unit) is alive) Equal to True) or (((Matching unit) belongs to an enemy of (Owner of Slice_Caster[Slice_X])) Equal to True)
replace all the "or" with "and"

I will try it later
Thanks for telling
EDIT: Hey! i tested it, and it is fixed! thanks +rep!
 
Level 25
Joined
Sep 26, 2009
Messages
2,381
What lender wrote. ANDs between conditions mean that all conditions have to return true for the unit to pass.
ORs between conditions mean that any condition has to return true for the unit to pass.
Your allied units are definitely not buildings - or they're not dead, so the condition block lets them pass.

If this is the only trigger for the spell, then you don't need any of those variables you used, except some generic (= temporal) variables that just basically make the code more efficient.
The reason is because you don't save anything and you don't need to save anything.
Saving anything is required if you need some stuff saved for any amount of time (be it as small as 0.01, etc.). You don't. In your trigger you take care of everything before using delay (in this case, the delay is the "wait" action).

Thanks to that, you can get rid of any kind of indexing and thus deindexing. Also, in your case, the deindexing would not even work properly. In the 0.5 second wait, the value in "Slice_X" variable may not be constant! Some other unit may be deindexed, or some new unit may cast the spell in the 0.5 second wait time.

You're also using way too many variables and way too many arrays for things that you can automatize.

For example:
  • Set Slice_Damage[1] = (75.00 + ((25.00 + (15.00 x (Real((Hero level of Slice_Caster[Slice_X]))))) + (1.75 x (Real(((Owner of Slice_Caster[Slice_X]) Current gold))))))
  • Set Slice_Damage[2] = (100.00 + ((25.00 + (15.00 x (Real((Hero level of Slice_Caster[Slice_X]))))) + (1.75 x (Real(((Owner of Slice_Caster[Slice_X]) Current gold))))))
  • Set Slice_Damage[3] = (125.00 + ((25.00 + (15.00 x (Real((Hero level of Slice_Caster[Slice_X]))))) + (1.75 x (Real(((Owner of Slice_Caster[Slice_X]) Current gold))))))
Why do it like that? Sure, if the damage is constant (e.g. level 1 always deals 100 damage, level 2 for example 150 damage and level 3 300 damage), then cool, you can set those values at map initialization and leave it.
However in your case the damage will always be dynamic (since we don't know what level our hero has and how much gold player has).

However what changes in those 3 levels? Each level's basic damage is higher by 25 than the previous one. Can't you simply calculate this? You even know the function!Look in the Hidden tabs
  • Actions
    • Set Gold = ((Owner of Caster) Current gold)
    • Set Hero_Level = (Hero level of Caster)
    • Set Ability_Level = (Level of (Ability being cast) for Caster)
    • -------- -------------------------------------------------------------------------------- --------
    • -------- -------------------------------------------------------------------------------- --------
    • -------- The first part ((50.00 + (25.00 x (Real(Ability_Level)))) will: --------
    • -------- return 75 for level 1 (50 + (25*1)) --------
    • -------- return 100 for level 1 (50 + (25*2)) --------
    • -------- return 125 for level 1 (50 + (25*3)) --------
    • Set DMG = ((50.00 + (25.00 x (Real(Ability_Level)))) + (25.00 + ((15.00 x (Real(Hero_Level))) + (1.75 x (Real(Gold))))))
    • -------- -------------------------------------------------------------------------------- --------
    • -------- Can be simplified into the below --------
    • Set DMG = ((75.00 + (25.00 x (Real(Ability_Level)))) + ((15.00 x (Real(Hero_Level))) + (1.75 x (Real(Gold)))))
Instead of doing calculation "50 + (25*x) + 25 +..." I simplified it into "75 + (25*x) + ..."

Do note!
In the trigger I posted above, I used variables Gold, Hero_level and Ability_level just so the final calculation is easier to understand for you. It has no effect on efficiency or anything else!


You're using way too many arrays. All for no reason as I stated at the start of this post.
Your unit group leaks location. You create unit group around "(position of Slice_Target)" <- this needs to be in "point" variable and destroyed at the end of your trigger.

The part of the ITE where you create special effect and attach it to Slice_Target, then damage Slice_Target, and lastly destroy the special effect, should be outside the ITE, because it happens no matter what.

I took the liberty of fixing your trigger. Look in the hidden tabs
  • Slice a piece
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Animate Dead
    • Actions
      • Set Caster = (Triggering unit)
      • Set Target = (Target unit of ability being cast)
      • Set Ability_Level = (Level of (Ability being cast) for Caster)
      • Set DMG = ((75.00 + (25.00 x (Real(Ability_Level)))) + ((15.00 x (Real((Hero level of Caster)))) + (1.75 x (Real(((Owner of Caster) Current gold))))))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Ability_Level Equal to 3
        • Then - Actions
          • Set Loc = (Position of Target)
          • Custom script: set bj_wantDestroyGroup = true //this makes the next created unit group to be destroyed after it's been used. Thus it prevents memory leak
          • Unit Group - Pick every unit in (Units within 380.00 of Loc matching ((((Matching unit) is alive) Equal to True) and ((((Matching unit) is A structure) Equal to False) and (((Matching unit) belongs to an enemy of (Owner of Caster)) Equal to True)))) and do (Actions)
            • Loop - Actions
              • Unit - Cause Caster to damage (Picked unit), dealing 85.00 damage of attack type Spells and damage type Normal
          • Custom script: call RemoveLocation(udg_Loc)
          • Custom script: set udg_Loc = null
        • Else - Actions
      • Special Effect - Create a special effect attached to the origin of Target using Abilities\Spells\Human\Thunderclap\ThunderClapCaster.mdl
      • Special Effect - Destroy (Last created special effect)
      • Unit - Cause Caster to damage Target, dealing DMG damage of attack type Spells and damage type Lightning
      • Set Caster = No unit
      • Set Target = No unit
As you can see, all variables I used are "Caster", "Target", "Loc", "Ability_level" and "DMG". The way I used them (without any delay) and their names suggest they're generic (temporal) variables, meaning if you have other triggers that require no delays, you can use them in there as well.
 
Level 12
Joined
Oct 16, 2010
Messages
680
Owh thank you so much! this is still MUI right the skill
EDIT: hey, if i want to... can I used custom script to set udg_caster = null? do this works?

indeed

  • 75.00 + (25.00 x (Real(Ability_Level)))
this will be 100,125,150 damage for levels1-3
should be
  • 50.00 + (25.00 x (Real(Ability_Level)))
just correcting


but Nichilus made a good point , tinker with it:)
 
Last edited:
Level 25
Joined
Sep 26, 2009
Messages
2,381
  • 75.00 + (25.00 x (Real(Ability_Level)))
this will be 100,125,150 damage for levels1-3
should be
  • 50.00 + (25.00 x (Real(Ability_Level)))
just correcting
Not sure if I understand correctly, but the first one is correct.

Calculation is:
(75.00 + ((25.00 + (15.00 x *Hero Level* + (1.75 x *Gold*)))))"
I changed 75.00 into (50.00 + (25.00 x *Ability level*)), thus it got changed into:
((50.00 + (25.00 x *Ability level*)) + ((25.00 + (15.00 x *Hero Level* + (1.75 x *Gold*)))))

Now I focused on the red numbers:
((50.00 + (25.00 x *Ability level*)) + ((25.00 + (15.00 x *Hero Level* + (1.75 x *Gold*)))))
Everything in the equation is just a sum (everything that is multiplied is in its own brackets, so it won't interfere with final calculation). Hence I sum "static" numbers together, since it doesn't interfere with the calculation and they will never get different value anyway.
And that gives me:
((75.00 + (25.00 x (Real(Ability_Level)))) + ((15.00 x (Real(Hero_Level))) + (1.75 x (Real(Gold)))))

Basically, what I did is I have equation "A + B + C + D" and I know that "X = A + C", then I can simply change the original into "X + B + D".
 
Status
Not open for further replies.
Top