• 🏆 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!

Cone-Like Spell using Math Angle from Point to Point

Status
Not open for further replies.
Level 5
Joined
Sep 29, 2016
Messages
43
Greetings,

as i continue to learn the World Editor mechanics with my first map, i tried to implement a Custom Cone-like Spell to damage enemies in front of the hero with a custom amount of damage.

But there is one thing that's kinda odd. Every time the Unit Group runs through to check if the units are inside the angle, usually there is 1 unit that is and all the others have some weird fked up angles instead.

If ingame looking at it, the spellcaster to unit angles are around 110° 100° 90° 80° 70° (summon angle 90°, boundaries 45°) the game tells me it was able to attack the one with 70° and lists all others with spellcaster to unit angles around 20°-30°.

  • Events
  • Conditions
  • Actions
  • -------- Position of Caster --------
  • Set Tmp_Point = (Position of (Casting unit))
  • -------- Target Point --------
  • Set Tmp_Point2 = (Target point of ability being cast)
  • -------- All Units in Circle Range --------
  • Set Tmp_UnitGroup = (Units within 500.00 of Tmp_Point matching (((Owner of (Matching unit)) is an enemy of (Owner of (Triggering unit))) Equal to True))
  • -------- Angle between Spellcaster and targetted Point --------
  • Set Tmp_Real = (Angle from Tmp_Point to Tmp_Point2)
  • Game - Display to (All players) the text: Angle Spellcaster->Target...
  • Game - Display to (All players) the text: (String(Tmp_Real))
  • Unit Group - Pick every unit in Tmp_UnitGroup and do (Actions)
    • Loop - Actions
      • -------- Position of the picked unit --------
      • Set Tmp_Point3 = (Position of (Picked unit))
      • -------- Angle between Spellcaster and targetted Point --------
      • Set Tmp_Real2 = (Angle from Tmp_Point to Tmp_Point3)
      • Game - Display to (All players) the text: Angle Spellcaster->Unit
      • Game - Display to (All players) the text: (String(Tmp_Real2))
      • Set Tmp_Real3 = (Tmp_Real2 - Tmp_Real)
      • Game - Display to (All players) the text: Angle Difference of 1&2
      • Game - Display to (All players) the text: (String(Tmp_Real3))
      • If (Tmp_Real3 Less than -180.00) then do (Set Tmp_Real3 = (Tmp_Real3 + 360.00)) else do (Do nothing)
      • Game - Display to (All players) the text: Angle Difference of 1&2, maybe increased by 360
      • Game - Display to (All players) the text: (String(Tmp_Real3))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Abs(Tmp_Real3)) Less than or equal to 45.00
        • Then - Actions
          • Game - Display to (All players) the text: Worked
          • -------- Unit inside cone --------
          • Unit - Cause (Triggering unit) to damage (Picked unit), dealing 100.00 damage of attack type Normal and damage type Normal
          • Special Effect - Create a special effect attached to the overhead of (Picked unit) using Abilities\Spells\Demon\DarkPortal\DarkPortalTarget.mdl
          • Special Effect - Destroy (Last created special effect)
        • Else - Actions
          • Game - Display to (All players) the text: Didn't Work
          • -------- Unit not inside cone --------
          • Special Effect - Create a special effect attached to the overhead of (Picked unit) using Abilities\Spells\Undead\CarrionSwarm\CarrionSwarmDamage.mdl
          • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation(udg_Tmp_Point)
  • Unit Group - Remove all units from Tmp_UnitGroup
  • Custom script: call RemoveLocation(udg_Tmp_Point2)
  • Custom script: call RemoveLocation(udg_Tmp_Point3)
Since i didn't upload a map to test it, i made a pic showing the situation ingame and what the game messages tell me when i use the spell.

You guys got any idea what i did wrong and what has to be changed to make that angle calculation work for every picked unit correctly?
 

Attachments

  • Math-Angle-Problem.png
    Math-Angle-Problem.png
    849.6 KB · Views: 60
Level 39
Joined
Feb 27, 2007
Messages
5,010
A simple google search would bring up literally tens of threads with solutions for this. Check your method against the methods used/suggested in these threads:

(Honestly it's much harder to read/parse your trigger with all the Game - Display lines in it, but that's just my opinion. Also don't use single-line If blocks, there's no reason to use them over the ones with multiple actions, which are also more readable.)

[Trigger] - Picking all units in front of another unit
Cone Shape
[Trigger] - How to select units within a cone ?
How to make a unit damage a cone-shaped area in front?
[Solved] - Get units in sector (Cone)
Pick units in a cone shape
[Trigger] - 60 Degree cone damage spell, how?
Selecting units in a cone
 
Level 5
Joined
Sep 29, 2016
Messages
43
Thanks for the hints, including the readability of triggers posted. I already checked lots of threads about this. Usually they go for solutions using the cos function and i know they work. But i'm also pretty sure that my idea is correct.

The thing that kinda bothers me (because i can't understand it) is, why the Math - Angle function only works for the first Unit in the Unit Group and gets weird values for the next ones. I checked up the positions of the units in the unit groups and they were okay. The target point the spell is summoned stays the same too, so why the math angle formula gives weird values...

To summarize my question: Why this Trigger is giving me wrong values in Tmp_Real2 for the other units in the Unit Group?
  • Events
  • Conditions
  • Actions
  • Set Tmp_Point = (Position of (Casting unit))
  • Set Tmp_Point2 = (Target point of ability being cast)
  • Set Tmp_UnitGroup = (Units within 500.00 of Tmp_Point matching (((Owner of (Matching unit)) is an enemy of (Owner of (Triggering unit))) Equal to True))
  • Set Tmp_Real = (Angle from Tmp_Point to Tmp_Point2)
  • Unit Group - Pick every unit in Tmp_UnitGroup and do (Actions)
    • Loop - Actions
      • Set Tmp_Unit = (Picked unit)
      • Set Tmp_Point3 = (Position of Tmp_Unit)
      • -------- V This one V --------
      • Set Tmp_Real2 = (Angle from Tmp_Point to Tmp_Point3)
      • -------- --------
      • Set Tmp_Real3 = (Tmp_Real2 - Tmp_Real)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Abs(Tmp_Real3)) Less than or equal to 45.00
        • Then - Actions
Do you guys have any idea why it happens?
 
Level 39
Joined
Feb 27, 2007
Messages
5,010
You're removing Tmp_Point inside the Unit Group - Pick loop, when you should be removing Tmp_Point3 instead. Then the point doesn't exist and it's checking the angle between Tmp_Point3 and (0,0). Remove Tmp_Point and Tmp_Point2 after the loop and Tmp_Point3 inside the loop.
 
Level 8
Joined
May 21, 2019
Messages
435
(Honestly it's much harder to read/parse your trigger with all the Game - Display lines in it, but that's just my opinion. Also don't use single-line If blocks, there's no reason to use them over the ones with multiple actions, which are also more readable.)
The game display messages are clearly test related, and it shows us that he has tried to diagnose the issue himself.
As for single-line vs multiline, I honestly don't agree. I think too many indentations makes it a total nightmare to read certain triggers. Assigning a variable is a pretty good example of something that's totally okay to do in a single-line in my opinion. :D
 
Level 39
Joined
Feb 27, 2007
Messages
5,010
I know perfectly well what the Display lines are for and what they indicate.

Single line ifs require double-clicking on them to change the condition, action, or action. That alone puts another window between you and editing the code you want to change, and GUI is 'windows within windows within windows' hell as it is already. Single line-ifs also force you to use Do Nothing since you can't leave the Else blank there like you can with the multi-line if; this introduces unnecessary additional function calls (though you would be hard-pressed to notice a performance hit from this alone).
 
Level 8
Joined
May 21, 2019
Messages
435
Single line ifs require double-clicking on them to change the condition, action, or action. That alone puts another window between you and editing the code you want to change, and GUI is 'windows within windows within windows' hell as it is already. Single line-ifs also force you to use Do Nothing since you can't leave the Else blank there like you can with the multi-line if; this introduces unnecessary additional function calls (though you would be hard-pressed to notice a performance hit from this alone).

I personally find the indentation stuff to be worse than the window hell, but both are pretty awful for sure. But regardless, it's still entirely subjective. :)
 
Status
Not open for further replies.
Top