Problem with angle based ability

Solu9

You can change this now in User CP.
Reaction score
216
The trigger:

Trigger:
  • Cleave
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Cleave
    • Actions
      • Set Sweeping_CastUnit = (Position of (Triggering unit))
      • Set Sweeping_TargetUnit = ((Position of (Casting unit)) offset by 300.00 towards (Facing of (Triggering unit)) degrees)
      • Set TempUnitGroup_1 = (Units within 300.00 of Sweeping_TargetUnit matching ((((Matching unit) is alive) Equal to True) and ((Owner of (Matching unit)) Equal to Neutral Hostile)))
      • Unit Group - Pick every unit in TempUnitGroup_1 and do (Actions)
        • Loop - Actions
          • Set Sweeping_Loc = (Position of (Picked unit))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Integer((Angle from Sweeping_CastUnit to Sweeping_Loc))) Greater than or equal to (Integer(((Angle from Sweeping_CastUnit to Sweeping_TargetUnit) - 90.00)))
              • (Integer((Angle from Sweeping_CastUnit to Sweeping_Loc))) Less than or equal to (Integer(((Angle from Sweeping_CastUnit to Sweeping_TargetUnit) + 90.00)))
            • Then - Actions
              • Unit - Cause (Triggering unit) to damage (Picked unit), dealing ((Real((Strength of (Triggering unit) (Include bonuses)))) + ((Real((Level of Cleave for (Triggering unit)))) x 20.00)) damage of attack type Normal and damage type Normal
              • Special Effect - Create a special effect attached to the chest of (Picked unit) using Objects\Spawnmodels\Human\HumanBlood\HumanBloodFootman.mdl
              • Special Effect - Destroy (Last created special effect)
              • Custom script: call DestroyGroup (udg_TempUnitGroup_1)
              • Custom script: call RemoveLocation (udg_Sweeping_TargetUnit)
              • Custom script: call RemoveLocation (udg_Sweeping_CastUnit)
              • Custom script: call RemoveLocation (udg_Sweeping_Loc)
            • Else - Actions
              • Custom script: call RemoveLocation (udg_Sweeping_Loc)
              • Custom script: call DestroyGroup (udg_TempUnitGroup_1)
              • Custom script: call RemoveLocation (udg_Sweeping_CastUnit)
              • Custom script: call RemoveLocation (udg_Sweeping_TargetUnit)


The ability:
Based on channel. Instant no target.


The problem:
Depending on the positioning on the map this ability either work as intended (hits every enemy in a 180 angle) or only hits 1 enemy.
If the ability is used on the left portion of the map it hits only 1.
If the ability is used on the right portion of the map it hits every enemy in 180 degrees.

What is wrong with the trigger?
 

Tharius

Occasionally Around
Reaction score
39
Keep in mind that the game is looking for an angle value, i.e. a real number between 0 and 360. Unless the facing angle of the triggering unit is exactly 180 degrees (facing directly left), some of the damaging area will be cut off because the comparison will fall either less than 0 or greater than 360.

For example, say that the facing angle of the unit is 350 degrees (facing just below directly to the right), and there is a unit standing 100 yards away to the northeast (thus the angle between the triggering unit and the target is 45 degrees). The target should be hit by the spell, because the actual difference in angles is only 55 degrees, but it won't detect a hit because 45 isn't between 260 (350 degrees - 90 degrees) and 440 (350 degrees + 90 degrees)

To get around this, you can use the modulo function, with (Facing of Triggering Unit + 90) or (Facing of Triggering Unit - 90) as the dividend, and 360 as the divisor. This will always return a number between 0 and 360. Disregard this part and see later post.


You also have a problem where you're deleting TempUnitGroup_1, Sweeping_CastUnit and Sweeping_TargetUnit before you're done using them. You want those cleanups to be after the Pick Every Unit loop is finished, not at the end of the first iteration.


Your spell, by the way, isn't actually trying to damage targets in a 180 degree arc in front of the caster. It's actually picking a location 300 yards away from the caster, in the direction the caster is facing, and attempting to damage everything in a 300 yard radius circle centered on that point (I say "attempting" because of the other issues outlined above). Striking something 600 yards away with what I'm assuming is a melee attack is a rather long distance even for a large model.
 

Solu9

You can change this now in User CP.
Reaction score
216
Your spell, by the way, isn't actually trying to damage targets in a 180 degree arc in front of the caster. It's actually picking a location 300 yards away from the caster, in the direction the caster is facing, and attempting to damage everything in a 300 yard radius circle centered on that point (I say "attempting" because of the other issues outlined above). Striking something 600 yards away with what I'm assuming is a melee attack is a rather long distance even for a large model.

Aye I saw that myself. I changed the "Set TempUnitGroup_1" to "units within 300 of CASTING UNIT" instead of Sweeping_TargetUnit.

Still working on the modulo function.
 

Solu9

You can change this now in User CP.
Reaction score
216
Hmm actually about the removal of the group and point don't seem to be a problem since all of the enemies loses hp.

I have tried fizzling with the modulo, hard when I don't really know how it works. I remade the trigger to fit somewhat what you described. However now none of the surrounding enemies take damage.

Here is the trigger:

Trigger:
  • Cleave Copy
    • Events
    • Unit - A unit Starts the effect of an ability
    • Conditions
    • (Ability being cast) Equal to Cleave
    • Actions
    • Set Sweeping_CastUnit = (Position of (Triggering unit))
    • Set Sweeping_TargetUnit = ((Position of (Casting unit)) offset by 300.00 towards (Facing of (Triggering unit)) degrees)
    • Set TempUnitGroup_1 = (Units within 300.00 of Sweeping_CastUnit matching ((((Matching unit) is alive) Equal to True) and ((Owner of (Matching unit)) Equal to Neutral Hostile)))
    • Unit Group - Pick every unit in TempUnitGroup_1 and do (Actions)
    • Loop - Actions
    • Set Sweeping_Loc = (Position of (Picked unit))
    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
    • (Integer((Angle from Sweeping_CastUnit to Sweeping_Loc))) Greater than or equal to (Integer((((Facing of (Triggering unit)) + 90.00) mod 360.00)))
    • (Integer((Angle from Sweeping_CastUnit to Sweeping_Loc))) Less than or equal to ((Integer(((Facing of (Triggering unit)) - 90.00))) mod 360)
    • Then - Actions
    • Unit - Cause (Triggering unit) to damage (Picked unit), dealing ((Real((Strength of (Triggering unit) (Include bonuses)))) + ((Real((Level of Cleave for (Triggering unit)))) x 20.00)) damage of attack type Normal and damage type Normal
    • Special Effect - Create a special effect attached to the chest of (Picked unit) using Objects\Spawnmodels\Human\HumanBlood\HumanBloodFootman.mdl
    • Special Effect - Destroy (Last created special effect)
    • Custom script: call DestroyGroup (udg_TempUnitGroup_1)
    • Custom script: call RemoveLocation (udg_Sweeping_TargetUnit)
    • Custom script: call RemoveLocation (udg_Sweeping_CastUnit)
    • Custom script: call RemoveLocation (udg_Sweeping_Loc)
    • Else - Actions
    • Custom script: call RemoveLocation (udg_Sweeping_Loc)
    • Custom script: call DestroyGroup (udg_TempUnitGroup_1)
    • Custom script: call RemoveLocation (udg_Sweeping_CastUnit)
    • Custom script: call RemoveLocation (udg_Sweeping_TargetUnit)


Edit: I noticed a flaw in the modulo. So I changed it to:
(Integer((Angle from Sweeping_CastUnit to Sweeping_Loc))) Greater than or equal to (Integer((((Facing of (Triggering unit)) + 90.00) mod 360.00)))
and
(Integer((Angle from Sweeping_CastUnit to Sweeping_Loc))) Greater than or equal to (Integer((((Facing of (Triggering unit)) - 90.00) mod 360.00)))
Im not sure its correct use of the modulo cause it does not work :)
 

Tharius

Occasionally Around
Reaction score
39
Edit: I noticed a flaw in the modulo. So I changed it to:
(Integer((Angle from Sweeping_CastUnit to Sweeping_Loc))) Greater than or equal to (Integer((((Facing of (Triggering unit)) + 90.00) mod 360.00)))
and
(Integer((Angle from Sweeping_CastUnit to Sweeping_Loc))) Greater than or equal to (Integer((((Facing of (Triggering unit)) - 90.00) mod 360.00)))
Im not sure its correct use of the modulo cause it does not work :)

You want the first part of that to be:

(Integer((Angle from Sweeping_CastUnit to Sweeping_Loc))) Less than or equal to (Integer((((Facing of (Triggering unit)) + 90.00) mod 360.00)))
 

Solu9

You can change this now in User CP.
Reaction score
216
Right, completely missed that. But, that was not the problem. No damage is dealt.
 

Tharius

Occasionally Around
Reaction score
39
Right, completely missed that. But, that was not the problem. No damage is dealt.

Actually, disregard my previous posts on the topic, I read it too quickly and thought it was an identical problem to something I posted on, a few weeks ago.

You want the if statement to be:

Trigger:
  • If - Conditions
    • Or - Any Conditions are True
      • Conditions
        • (Abs(Facing of (Triggering Unit) - (Angle from Sweeping_CastUnit to Sweeping_Loc))) Greater than or equal to 270.00
        • (Abs(Facing of (Triggering Unit) - (Angle from Sweeping_CastUnit to Sweeping_Loc))) Less than or equal to 90.00


Not sure what I was thinking when I suggested using modulo.
 

Solu9

You can change this now in User CP.
Reaction score
216
Hmm. I take that your example is handwritten because the closest I can get is this:
Trigger:
  • (Abs(((Integer((Facing of (Triggering unit)))) - (Integer((Angle from Sweeping_CastUnit to Sweeping_Loc)))))) Greater than or equal to 270


Which does not work :)

Edit: Actually I think you were right about using modulo. I have read in another thread that it should work. But that is a targeted ability and I can't convert it to an instant/no target cast.
 

Tharius

Occasionally Around
Reaction score
39
Hmm. I take that your example is handwritten because the closest I can get is this:
Trigger:
  • (Abs(((Integer((Facing of (Triggering unit)))) - (Integer((Angle from Sweeping_CastUnit to Sweeping_Loc)))))) Greater than or equal to 270


Which does not work :)

Edit: Actually I think you were right about using modulo. I have read in another thread that it should work. But that is a targeted ability and I can't convert it to an instant/no target cast.

Nope, it's actually copy-pasted from a test map that I made specifically to check my coding on this particular problem. I made a cleave ability, gave it to a footman, and it works perfectly.

You seem to be using an integer comparison rather than a real comparison, and you don't have an OR statement in there as far as I can tell. That might be part of the problem.

The other thread you were reading probably included my post. It's not exactly the same situation as the other one, though. The reason I originally suggested modulo was because I thought this situation was identical and I pretty much copy-pasted from my other post.
 

Solu9

You can change this now in User CP.
Reaction score
216
I would like to quote Polo2005: "omfg its working hahahahaha lol zomg.... ty"

And Tharius you are completely right, thats why I couldn't make it work in the first place.
The example in the link by Juggernaut did prove to be what tipped the balance.

I would like to thank all three of you. Especially you Tharius for keeping it up :)

And now Ill post the trigger for future reference for myself

Trigger:
  • Cleave
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Cleave
    • Actions
      • Set TempUnitGroup_1 = (Units within 300.00 of (Position of (Triggering unit)) matching ((((Triggering unit) is alive) Equal to True) and ((Owner of (Matching unit)) Equal to Neutral Hostile)))
      • Set TempReal_1 = (Facing of (Triggering unit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TempReal_1 Less than 0.00
        • Then - Actions
          • Set TempReal_1 = (TempReal_1 + 360.00)
        • Else - Actions
      • Unit Group - Pick every unit in TempUnitGroup_1 and do (Actions)
        • Loop - Actions
          • Set TempReal_2 = (Angle from (Position of (Triggering unit)) to (Position of (Picked unit)))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • TempReal_2 Less than 0.00
            • Then - Actions
              • Set TempReal_2 = (TempReal_2 + 360.00)
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • TempReal_2 Less than or equal to (TempReal_1 + 90.00)
              • TempReal_2 Greater than or equal to (TempReal_1 - 90.00)
            • Then - Actions
              • Unit - Cause (Triggering unit) to damage (Picked unit), dealing (20.00 x ((Real((Level of Cleave for (Triggering unit)))) + (Real((Intelligence of (Triggering unit) (Include bonuses)))))) damage of attack type Normal and damage type Normal
              • Special Effect - Create a special effect attached to the chest of (Picked unit) using Objects\Spawnmodels\Human\HumanBlood\HumanBloodFootman.mdl
              • Special Effect - Destroy (Last created special effect)
              • Custom script: call DestroyGroup (udg_TempUnitGroup_1)
            • Else - Actions


It leaks at the moment, but thats easily fixed.

Thanks again.

Edit: The trigger should now be correct.
 

vypur85

Hibernate
Reaction score
803
In essence, TempReal_1 is not needed. Because the facing angle of a unit will never return a negative value. But since it's working now, just leave it be, to avoid further confusion. :)
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top