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

[JASS] Picking Units within an Angle

Status
Not open for further replies.
Level 7
Joined
Jun 16, 2008
Messages
253
Hi, I'm working on a combat system which requires me to be be to find all units within a certain range of Hero and within between +10 to -110 of his facing angle.
At the moment I'm having issues because apparently circles are not made in 360 degrees, they are made in 180 and negative 180 degrees.

My combat system works fine as long as unit is facing a positive direction, but the trigger won't function if he maintains a negative disposition.

Can someone help me lift up this dude's energy? I don't know what to do, it's like a crisis.


Here's the little picker I use.

JASS:
function Trig_Combat_System_Jass_Func002001003001001 takes nothing returns boolean
    if( AngleBetweenPoints(GetUnitLoc(GetAttacker()), GetUnitLoc(GetFilterUnit())) <= GetUnitFacing(GetAttacker()) + 10.00 ) and ( AngleBetweenPoints(GetUnitLoc(GetAttacker()), GetUnitLoc(GetFilterUnit())) >= GetUnitFacing(GetAttacker()) - 110.00) then
    return true
    else
    return false
    endif
endfunction

It's hooked into a pick every unit on playable map, but it just has the aforementioned problem.

Could somebody please help me with this?

Cheers.
 
Level 7
Joined
Jun 16, 2008
Messages
253
Apparently not. I used a DisplayText to tell me what the unit facing angle was and it told me there was anything between -180 to +180. No 360. I don't know why.
I'm assuming that there's some kind of funny translation going on between the angles I'm getting, and the usual ones you see such as facing angle in unit properties.

It's really confusing me, and I'm very, very new at this. First mod/proper map I've done in my whole life. Certainly first map I've ever used or known of jass in, so I really need some help.
 

Rui

Rui

Level 41
Joined
Jan 7, 2005
Messages
7,550
Well, first and foremost you're leaking 2 locations it seems.
JASS:
function Trig_Combat_System_Jass_Func002001003001001 takes nothing returns boolean
    local location ap=GetUnitLoc(GetAttacker())
    local location fup=GetUnitLoc(GetFilterUnit())
    return ( AngleBetweenPoints(ap, fup <= GetUnitFacing(GetAttacker()) + 10.00 ) and ( AngleBetweenPoints(ap, fup >= GetUnitFacing(GetAttacker()) - 110.00)
    call RemoveLocation(ap)
    call RemoveLocation(fup)
    set ap=null
    set fup=null
endfunction
I don't know exactly how AngleBetweenPoints() works so I wouldn't know.
Are you sure there is no function like that which uses coordinates instead?
 
Level 7
Joined
Jun 16, 2008
Messages
253
Well I could create regions (or co-ordinate equivalents) if that's what you mean, using polar offsets. But it would be perfectly accurate for range of weapon.

If you meant something else, then I'm clueless, I'll have a squiz through the function list and see if it tells me anything.

Does things like GetUnitLoc really create... well I guess it would wouldn't it? Thank you very much. :D

Btw, that's one very distracting little avatar. I've been sitting here for about a minute trying to figure out what exactly it's doing in one of it's little dances.
o.O
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
Well, first and foremost you're leaking 2 locations it seems.
JASS:
function Trig_Combat_System_Jass_Func002001003001001 takes nothing returns boolean
    local location ap=GetUnitLoc(GetAttacker())
    local location fup=GetUnitLoc(GetFilterUnit())
    return ( AngleBetweenPoints(ap, fup <= GetUnitFacing(GetAttacker()) + 10.00 ) and ( AngleBetweenPoints(ap, fup >= GetUnitFacing(GetAttacker()) - 110.00)
    call RemoveLocation(ap)
    call RemoveLocation(fup)
    set ap=null
    set fup=null
endfunction
I don't know exactly how AngleBetweenPoints() works so I wouldn't know.
Are you sure there is no function like that which uses coordinates instead?

It will still leak. Why? Because whenever a "return" is encountered, the function is instantly terminated and the actions after the "return" will obviously not be executed. In other words: ap and fup will never be removed or nulled. For that reason, you must either do:

JASS:
function Trig_Combat_System_Jass_Func002001003001001 takes nothing returns boolean
    local location ap=GetUnitLoc(GetAttacker())
    local location fup=GetUnitLoc(GetFilterUnit())
    local boolean b = ( AngleBetweenPoints(ap, fup <= GetUnitFacing(GetAttacker()) + 10.00 ) and ( AngleBetweenPoints(ap, fup >= GetUnitFacing(GetAttacker()) - 110.00)
    call RemoveLocation(ap)
    call RemoveLocation(fup)
    set ap=null
    set fup=null
    return b
endfunction

or you can simply avoid locations in the first place and use:

JASS:
function Trig_Combat_System_Jass_Func002001003001001 takes nothing returns boolean
    return (bj_RADTODEG * Atan2(GetUnitY(GetFilterUnit()) - GetUnitY(GetAttacker()), GetUnitX(GetFilterUnit()) - GetUniX(GetAttacker())) <= GetUnitFacing(GetAttacker()) + 10.0 ) and ( bj_RADTODEG * Atan2(GetUnitY(GetFilterUnit()) - GetUNitY(GetAttacker()), GetUnitX(GetFilterUnit()) - GetUniX(GetAttacker())) >= GetUnitFacing(GetAttacker()) - 110.0 )
endfunction

EDIT: I just noticed that if you copy this in newgen, part of it falls off because the line is too long to be compiled. Simply do this:

JASS:
function Trig_Combat_System_Jass_Func002001003001001 takes nothing returns boolean
    local boolean b = (bj_RADTODEG * Atan2(GetUnitY(GetFilterUnit()) - GetUnitY(GetAttacker()), GetUnitX(GetFilterUnit()) - GetUniX(GetAttacker()))) <= (GetUnitFacing(GetAttacker()) + 10.0) ) 
    return b and ( (bj_RADTODEG * Atan2(GetUnitY(GetFilterUnit()) - GetUNitY(GetAttacker()), GetUnitX(GetFilterUnit()) - GetUniX(GetAttacker()))) >= (GetUnitFacing(GetAttacker()) - 110.0)
endfunction

-------------------------

AngleBetweenPoints does the following:
JASS:
function AngleBetweenPoints takes location locA, location locB returns real
    return bj_RADTODEG * Atan2(GetLocationY(locB) - GetLocationY(locA), GetLocationX(locB) - GetLocationX(locA))
endfunction

bj_RADTODEG is a constant which - when multiplied with an angle in radians - returns an angle in degrees. Atan2 is a function which returns an angle in radians, so it's logical that you need to multiply it with bj_RADTODEG in order to get degrees.
 
Level 7
Joined
Jun 16, 2008
Messages
253
EDIT: Wait. I'm confused again. the RADTODEG (just understood what that stood for lol, I just thought it was a nonsense name) was already in function thingy. Must have been the extra +10 and -110 that weren't getting translated proper.

EDITEDIT: It doesn't work. :( Syntax error. Would you just be able to do it on my latest update?
 
Level 13
Joined
Jun 5, 2008
Messages
504
EDIT: Wait. I'm confused again. the RADTODEG (just understood what that stood for lol, I just thought it was a nonsense name) was already in function thingy. Must have been the extra +10 and -110 that weren't getting translated proper.

EDITEDIT: It doesn't work. :( Syntax error. Would you just be able to do it on my latest update?

I dont know jass, but I would do it like this (in gui)
set units facing angle +360 +10
set units facing angle +360 -110

since you can work with 720angles or so....
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
Sorry, I typed a bit too fast and indeed made a few (obvious) syntax errors :p

JASS:
function Trig_Combat_System_Jass_Func002001003001001 takes nothing returns boolean
    local boolean b = (bj_RADTODEG * Atan2(GetUnitY(GetFilterUnit()) - GetUnitY(GetAttacker()), GetUnitX(GetFilterUnit()) - GetUnitX(GetAttacker()))) <= (GetUnitFacing(GetAttacker()) + 10.0)
    return b and (bj_RADTODEG * Atan2(GetUnitY(GetFilterUnit()) - GetUnitY(GetAttacker()), GetUnitX(GetFilterUnit()) - GetUnitX(GetAttacker()))) >= (GetUnitFacing(GetAttacker()) - 110.0)
endfunction

I don't understand what you're trying to achieve with the "+10" or "-110"... Care to explain what you need to know with this function?
 
Level 7
Joined
Jun 16, 2008
Messages
253
How to Pick all units within range of Hero's weapon range, and in his weapon swing path, which is between +10 and -110. Roughly.

Weapon range is pre-defined as are other stats. Weapon arc is temporary stand in for attack style. Check main thread. :D

EDIT: I thought I had fixed all the obvious ones. Must have missed a slightly less obvious one. Cheers, I'll see how it works.
 
Level 7
Joined
Jun 16, 2008
Messages
253
Okay, I understand the problem now, but I don't know the solution.

The problem lies in the fact that bj_RADTODED * Atan2( etc... will give me the 0 to +-180, and it's being compared to Unit Facing which is from 0-360.

The easiest one I can think of to do is the one you suggested somewhere Eleandor, which is is the number is negative then add 360. But I'm not sure how to even appropriately do this.

I know it's a hassle guys, but you all understand maths better than I do, so could you just give me something I can copy?

I dunno, maybe something that converts the bj_RADTODEG etc... into Unit Facing style degrees or vice versa, or just the +360 thing? I am well and truly buried under all the different maths stuff. I be dumb.
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
I would make it in coordinate way

First Group Units in X Range
then
forgroup
lets say A is facing angle of source unit B is sight angle x1 and y1 are coordinates of source unit and x2 and y2 are coordinates of picked unit

if not (y2-y1 > tan(A-B/2)*(x2-x1) and y2-y1 < tan(A+B/2)*(x2-x1)) then
Remove Picked Unit from Group
endif

Dont ever miss the math classes in school
 
Level 13
Joined
Jun 5, 2008
Messages
504
I would make it in coordinate way

First Group Units in X Range
then
forgroup
lets say A is facing angle of source unit B is sight angle x1 and y1 are coordinates of source unit and x2 and y2 are coordinates of picked unit

if not (y2-y1 > tan(A-B/2)*(x2-x1) and y2-y1 < tan(A+B/2)*(x2-x1)) then
Remove Picked Unit from Group
endif

Dont ever miss the math classes in school

doh...i would just pick angle between posittion of triggering unit and possition of picked unit. If its under or over something, then do nothing/remove the unit from group or whatever...much easier....

I know im bad at explaining things....so i hope you get it.
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
it will make problem at directions close to 0
coz
angle of an unit facing to 359 degrees isnt inside -15 and +15

I know im bad at explaining things....so i hope you get it.
 
Level 12
Joined
May 4, 2008
Messages
1,111
make a spell in a row meybe that makes the thing at the base of the spell able to pick every targeted unit?like. make a unit use a custom Shockwave at X angle and pick all units that are targeted or in the damaged area (even if no damage is required)
 
Level 7
Joined
Jun 16, 2008
Messages
253
Hey guys, thanks for all the replies. I'm just going to outline what it is I want to do with this specific trigger, just in case I haven't before.

Basically:

When Hero attacks a unit,
Pick every unit within range (200) of Hero matching the Hero's facing angle +10 and -110. (This should be a nice wide arc going from just behind right, to just to the left of the unit he is attacking)

And then damage them accordingly.

So every unit within the supposed path of his swing, Facing +10 to Facing -110 will be damaged.

As mentioned before, the current problem in trigger is that I don't know how to convert Atan2BJ style degrees, to Facing Angle degrees.

I supose it is possible just to use Atan2BJ, which would give me the angle of the Attacked Unit's position, and just make the damage arc based on that instead of specific facing angle. But I want to take the unit's current facing angle into account, for various reasons.

I'm sorry, but I'm having a little trouble understanding anyone's answer. I would be grateful for an actual jass code that I could substitute the function with, and wiggle around to see if it fits. Puh-lease? Big cookeh if you do!

In meantime, I'll still scrutinise your guys answers to see if there's anything I need in them. I really just want a way to convert the -180 to + 180 style to 0 - 360 style or viceversa.

If anyone did in fact answer that, sorry but I must be missing it.

I understand the problem you're talking about O2, I was wondering about that myself. If your code addresses that then I'll definitely try to use it.
And I would NEVER miss a maths class. I was a growing boy, I needed my sleep, I would never miss an opportunity to reclaim a restful hour. :D
(Maybe your code solves all my problems, I dunno, I'll have to play with it a bit first.)


EDIT: I've just put in a stop-gap which seems to be fairly bugless, just doing like I said before, just using angle of position rather than facing angle, maybe later I can find out how to convert the different kinds of angle values. Thanks fellas!
 
Last edited:
Level 7
Joined
Jun 16, 2008
Messages
253
I would, but I don't know how getting the angle between the two direction angles would help me. I can do pythagoras and all that (after a lot of hasty remembering), but I can't see the application for getting that particular angle. That's why I (now) have basically a If 'angle of position of unit' is <= 'angle from Hero to unit' and If 'angle of position of unit' is >= 'angle from Hero to unit'. I can't see a one shot all purpose function to just say in a region between these two angles.

Obviously not in that terminoloy or syntax.

Unless there is some way to say, Pick Every unit in 'region' Acos(cos(A-B)) * Weapon reach. I mean, can you do anything like that? Or what did you have in mind?

Huh. Actually I wonder, if you could get the lines for the two angles and then the end could you create basically a triangular (or near enough) region. In some strange way that could work couldn't it?
 
Level 13
Joined
Jun 5, 2008
Messages
504
this is what i meant and I dont havent got any problems with this
  • Actions
    • Set Posstion[1] = (Position of (Triggering unit))
    • Set group = (Units within 200.00 of (Position of (Triggering unit)) matching (((Triggering unit) is A structure) Equal to True))
    • Unit Group - Pick every unit in group and do (Actions)
      • Loop - Actions
        • Set Posstion[2] = (Position of (Picked unit))
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Angle from Posstion[1] to Posstion[2]) Less than or equal to ((Facing of (Triggering unit)) + (360.00 + 10.00))
            • (Angle from Posstion[1] to Posstion[2]) Greater than or equal to ((Facing of (Triggering unit)) + (360.00 - 100.00))
          • Then - Actions
          • Else - Actions
 
Level 19
Joined
Aug 24, 2007
Messages
2,888
oh more simple way
if Cos(Your Facing - Angle Between Points) < Cos (sight angle/2)
then its in your facing

How Couldnt I think of that that is %100 more simple
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Alakon, the entire point is...

You want +10 and -100.

This means the centre angle is -35, so you have +45 and -45.

Angle A is the facing of the target, -35 degrees, converted to radians.

Angle B is the angle from the caster to the target, in radians.

Acos(Cos(A-B)) being less than or equal to PI/4 (45 degrees in radians) gives you your solution.
 
Level 7
Joined
Jun 16, 2008
Messages
253
Wouldn't the centre angle be -45?

-45 + 55 = 10
-45 - 55 = -100

(I actually originally wanted -110, but that's irrelevant, perhaps - 100 is better *shrug*)

That's very interesting PP, I hadn't know that about radians and PI, and I can see good uses for Acos angle finding.

I'm not sure why exactly you have facing -35 sort of thing. I'm sure there's a good reason to do with centre angle. And you do realise that it is +10 and -110 from facing of Hero? Just in case you misunderstood.

I'm assuming the target can be replaced with EnumUnit(), because this is a Pickevery unit that matches condition within the angle kinda thing.

But other than that still very useful info, cheers.

kewlthis: Cheers for the trigger, I can see that you just +360'd everything, I'm assuming that you checked these to see what values are returned facing positive and negative angles etc...? I'll have a play with it anyway and see if it works.
 
Level 7
Joined
Jun 16, 2008
Messages
253
I'LL NEVA TRUST YOU AGAIN!

:D

Okay, I now fully understand your suggestion PP and it's great! I'm still curious as to a way to get from the +-180 to 0-360 thing, but I suppose converting to radians does the same job.

I see now, basically takes the angle between hero and unit and see if it is within (<) the 120 (using my numbers) angle, or the 60 angle in either direction, the 120 angle nicely centred on an angle offest of Hero facing so it covers +10 and =110 of Hero appropriately.

This will be gerat because it will also allow me to easily extend the sweep arc to a full 360 if I want!

Cheers! I'd rep ya, but my rep isn't worth anything till I hit 10 I think. Rest assured when I hit 10 I'll pepper you with rep.

Thanks for patiently explaining that to me. :D
 
Status
Not open for further replies.
Top