• 🏆 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 AoE Spell Bugs

Status
Not open for further replies.
Level 8
Joined
Jun 13, 2010
Messages
344
Hi,

I have made this simple Target Area spell that deals damage to enemies caught within. (Bottom)
But it leaks somehow. It deals the damage to enemies within the area. But if a enemy unit dies from the trigger, the others caught will not take damage.
Is it something with the arrangements of the trigger?
How would you suggest it then?

  • Ice Nova
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Apprentice (Ice Nova)
    • Actions
      • Set ASpell_Caster = (Triggering unit)
      • Set ASpell_Point = (Target point of ability being cast)
      • Unit Group - Pick every unit in (Units within 300.00 of ASpell_Point) and do (Actions)
        • Loop - Actions
          • Set ASpell_AreaTarget_Enemy = (Picked unit)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (ASpell_AreaTarget_Enemy is A structure) Equal to False
              • (ASpell_AreaTarget_Enemy belongs to an enemy of (Owner of ASpell_Caster)) Equal to True
              • (ASpell_AreaTarget_Enemy is Magic Immune) Equal to False
              • (ASpell_AreaTarget_Enemy is dead) Equal to False
            • Then - Actions
              • Unit - Cause ASpell_Caster to damage ASpell_AreaTarget_Enemy, dealing (0.90 x (Real((Intelligence of ASpell_Caster (Include bonuses))))) damage of attack type Spells and damage type Normal
            • Else - Actions
      • Custom script: call RemoveLocation (udg_ASpell_Point)
 
Level 13
Joined
Jan 2, 2016
Messages
973
The only leak I see is from the unit group. Add a custom script "set bj_wantDestroyGroup = true" before creating the unit group and it should be leak free.
As for the not working part... I can't see a reason why wouldn't it be working after killing an enemy.
 
Level 8
Joined
Jun 13, 2010
Messages
344
The only leak I see is from the unit group. Add a custom script "set bj_wantDestroyGroup = true" before creating the unit group and it should be leak free.
As for the not working part... I can't see a reason why wouldn't it be working after killing an enemy.

Can I remove a group when I haven't even made one?
 
Level 11
Joined
Jun 2, 2013
Messages
613
Depending on how you try to remove the leak, you don't necessarily have to set a unit group variable.

Instead of setting a variable to picked unit, why not just use "picked unit" in the conditions and action in the if/then/else block? Also, The Condition that checks if a target is dead is probably the culprit behind why it isn't working.
 
Level 8
Joined
Jun 13, 2010
Messages
344
Depending on how you try to remove the leak, you don't necessarily have to set a unit group variable.

Instead of setting a variable to picked unit, why not just use "picked unit" in the conditions and action in the if/then/else block? Also, The Condition that checks if a target is dead is probably the culprit behind why it isn't working.

Well, how can the dead condition mess it up? :/
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
@PublishedShadow
The variable instead of Picked Unit is for performance efficiency.
Function calls in JASS are pretty heavy so it is better to store the unit in a variable instead of calling that function every single time.

@SnowYell
The problem is about 99% from another trigger.
Try search for a trigger that runs when a unit dies.
Upload all those triggers.
You probably have one that sets "ASpell_Caster" to any value thus overwriting the caster (damage source) of your spell with a non-hero unit causing the intelligence to be 0 and multiplying 0 bt 0.9... which is 0 damage.

(Owner of ASpell_Caster) could also be in a variable because you are calling that function for every unit in your group... and yes that group is an existing object that you create and never destroy. So for that reason, you leak data storage.
 
Level 8
Joined
Jun 13, 2010
Messages
344
@PublishedShadow
The variable instead of Picked Unit is for performance efficiency.
Function calls in JASS are pretty heavy so it is better to store the unit in a variable instead of calling that function every single time.

@SnowYell
The problem is about 99% from another trigger.
Try search for a trigger that runs when a unit dies.
Upload all those triggers.
You probably have one that sets "ASpell_Caster" to any value thus overwriting the caster (damage source) of your spell with a non-hero unit causing the intelligence to be 0 and multiplying 0 bt 0.9... which is 0 damage.

(Owner of ASpell_Caster) could also be in a variable because you are calling that function for every unit in your group... and yes that group is an existing object that you create and never destroy. So for that reason, you leak data storage.

Damn there is a whole lot of them I guess. But most are abilities with conditions matching this one, to each individual ability.

I believe I found it tho. Another spell i never finished had no condition for A unit dies and follows with actions set caster = none.

Some other strange thing is, I use blizzard ability to damage a target area. I have set it to 195 area of effect.
The trigger is set to picking units in 200 area. But still even though some units are marked with green (as in they are in the ability radius) they do not take damage from triggering. That is without any units even dies.
But the problem with dying units is gone. So it seems.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
The problem you are now facing is the problem of the difference between AoE and Pick units in range.

AoE from spells target all units that collide with the spell's AoE.
Pick units in range picks all units which center is inside that circle.
So you get a rough 31 unit distance difference between them (because that is often used for collision size).

You can solve this by picking units in a slightly larger area (lets say +31).
You can also solve this better by picking units in a much larger area and checking if the distance between the center of the unit and the target point of the spell are smaller than (AoE + collision).
There is also a native IsUnitInRangeXY() that seems to be taking collision into effect as well. (However, collision is not exactly the value you put in the object editor.)
You can also extract that data using the Object Data Extractor and write the condition yourself.
 
Level 8
Joined
Jun 13, 2010
Messages
344
You can solve this by picking units in a slightly larger area (lets say +31).

So there IS a difference between the Object Editor ability center (special effect area) and the Trigger Editor (Unit Group - In Range) "scale"?

But what you're saying is the fact that I have to have the enemy units' collision size in mind, when I do the Unit Group - Range trigger in the Trigger Editor?
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
I said that the Pick units in range uses the origin of the unit and that the area of effect of spells use the collision of the target.

Someone uploaded a JASS script picking all units in range with collision... dunno where it was though.
 
Level 8
Joined
Jun 13, 2010
Messages
344
You do have a Unit Group.
"Unit Group - Pick every unit in (Units within 300.00 of ASpell_Point) and do (Actions)"
It is leaking because you have no variable set to it.
You should read this and this (like I did yesterday). It explains a lot.

So according to the turtorials, this should be leak free?

  • Ice Nova
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Apprentice (Ice Nova)
    • Actions
      • Set ASpell_Caster = (Triggering unit)
      • Set ASpell_Point = (Target point of ability being cast)
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 300.00 of ASpell_Point) and do (Actions)
        • Loop - Actions
          • Set ASpell_AreaTarget_Enemy = (Picked unit)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (ASpell_AreaTarget_Enemy is A structure) Equal to False
              • (ASpell_AreaTarget_Enemy belongs to an enemy of (Owner of ASpell_Caster)) Equal to True
              • (ASpell_AreaTarget_Enemy is Magic Immune) Equal to False
              • (ASpell_AreaTarget_Enemy is dead) Equal to False
            • Then - Actions
              • Unit - Cause ASpell_Caster to damage ASpell_AreaTarget_Enemy, dealing (0.90 x (Real((Intelligence of ASpell_Caster (Include bonuses))))) damage of attack type Spells and damage type Normal
            • Else - Actions
      • Custom script: call RemoveLocation (udg_ASpell_Point)
 
Level 8
Joined
Jun 13, 2010
Messages
344
I don't get how leaks work I think, even though I read the turtorials.. Does it course lag problems?
I've tried a test here. Nothing happend.

  • Crash test
    • Events
      • Time - Every 0.01 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units within 512.00 of (Center of (Playable map area))) and do (Actions)
        • Loop - Actions
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
I don't get how leaks work I think, even though I read the turtorials.. Does it course lag problems?
I've tried a test here. Nothing happend.

  • Crash test
    • Events
      • Time - Every 0.01 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units within 512.00 of (Center of (Playable map area))) and do (Actions)
        • Loop - Actions

You won't be able to notice just sitting there staring at nothing. In a game where there are units moving, loops running, If/Then/Elses being checked, leaks will eventually cause the game to crash if they are unaccounted for.

It's worth looking into leaks. You only need 2-3 trigger lines to greatly improve your chances of the game not crashing, so why not learn it?
 
Level 13
Joined
Jan 2, 2016
Messages
973
I had a trigger:
Player (1) writes "-build" as an exact match
Create 1 Huntress Hall for (Triggering Player) at Center of Huntress Hall Reg
Create 1 Altar for (Triggering Player) at Center of Altar Reg
..............
Create 1 Moon Well for Player (Triggering Player) at Center of Moon Well Reg

Was building 13 buildings like that.
When I was writing "-build" in the game - the game was freezing for ~1sec

Now I've replaced the Actions with:
Set Temp_Player to (Triggering Player)
Set Temp_Point to center of Huntress Hall Reg
Create 1 Huntress Hall for Temp_Player at Temp_Point
call RemoveLocation(udg_Temp_Point)
Set Temp_Point to center of Altar Reg
Create 1 Altar for Temp_Player at Temp_Point
call RemoveLocation(udg_Temp_Point)
...........

Now the trigger still freezes the game, but it's for about 0,1 sec :p
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
I had a trigger:
Player (1) writes "-build" as an exact match
Create 1 Huntress Hall for (Triggering Player) at Center of Huntress Hall Reg
Create 1 Altar for (Triggering Player) at Center of Altar Reg
..............
Create 1 Moon Well for Player (Triggering Player) at Center of Moon Well Reg

Was building 13 buildings like that.
When I was writing "-build" in the game - the game was freezing for ~1sec

Now I've replaced the Actions with:
Set Temp_Player to (Triggering Player)
Set Temp_Point to center of Huntress Hall Reg
Create 1 Huntress Hall for Temp_Player at Temp_Point
call RemoveLocation(udg_Temp_Point)
Set Temp_Point to center of Altar Reg
Create 1 Altar for Temp_Player at Temp_Point
call RemoveLocation(udg_Temp_Point)
...........

Now the trigger still freezes the game, but it's for about 0,1 sec :p
It could be because you aren't preloading the structures.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
Try making a trigger like this:
  • Leak
    • Events
      • Time - Every 0.01 seconds of game time
    • Conditions
    • Actions
      • For each (Integer I) from 1 to 1000, do (Actions)
        • Loop - Actions
          • Set Location = (Point(0.00, 0.00))
No matter what, your game will lagg right from the start... I wouldnt expect less from 100,000 locations per second.
However, that means that with only 1000 per second, your game will lagg after ~1 minute and 40 seconds.
And with 100 location leaks per second, you will be leaking after ~16 minutes.
Lets say you play a game for 30-40 minutes... you will need like 30-40 leaks per second.
(Ofcourse this was tested on my pc.)

Unit group leaks may be bigger, because they also stores the data of what units it contains.
But if you have a 0.1s loop with a leak in it, you already have 10 per second... make 3 or 4 of those triggers and you will definately see it eventually.
 
Level 12
Joined
May 22, 2015
Messages
1,051
I said that the Pick units in range uses the origin of the unit and that the area of effect of spells use the collision of the target.

Someone uploaded a JASS script picking all units in range with collision... dunno where it was though.

It was in a thread I created:
http://www.hiveworkshop.com/forums/world-editor-help-zone-98/collision-range-274310/#post2773769

JASS:
function GroupAddUnitsInRangeWithCollision takes group whichGroup, real x, real y, real radius, real bounds returns group
    local unit FoG
    local group g = CreateGroup()
    call GroupEnumUnitsInRange(g, x, y, radius+bounds, null)
    
    loop
        set FoG = FirstOfGroup(g)
        exitwhen FoG == null
        call GroupRemoveUnit(g, FoG)
        
        if IsUnitInRangeXY(FoG, x, y, radius)
            call GroupAddUnit(whichGroup, FoG)
        endif
    endloop
    
    call DestroyGroup(g)
    set g = null
    return whichGroup
endfunction
 
Status
Not open for further replies.
Top