HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Backstab ability?

12-19-2006, 12:07 AM#1
Don0ndrew
How do you make it so if the unit is behind another unit it'll do extra dmg, such as Stealh Assasin in DotA.

If possible i would love it to be in GUI if not then thanks anyways! =]]
12-19-2006, 12:18 AM#2
xombie
Well, think about it. When somebody is behind you, you cannot see them, why? Because you are not FACING them.

Say a unit's facing is 40°. Would you not agree that the angle from this unit to an attacking unit (that is behind it) would be 40°-180°? This would be -140°, which is equivalent to 220°. This angle would have to be the facing of the attacking unit (± 30° so that he does not have to be EXACTLY behind him.)

An example of this in GUI is:
Trigger:
Untitled Trigger 001
Collapse Events
Unit - A unit Is attacked
Conditions
Collapse Actions
Set temp1 = (Facing of (Attacking unit))
Set temp2 = (Facing of (Triggering unit))
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
temp1 Greater than or equal to (temp2 - 20.00)
temp1 Less than or equal to (temp2 + 20.00)
Collapse Then - Actions
Custom script: B A C K S T A B T I M E ! ! !
Else - Actions
This represents 20° as the leniency (remember that its ±20°, so its 'actually' 40°.
12-19-2006, 12:22 AM#3
Don0ndrew
OMG DUDE YOU DONT KNOW HOW GREATFUL I AM! THANKS SO FREAKIN MUCH... =]] i appreciate it
12-19-2006, 12:25 AM#4
wyrmlord
Couldn't you just get the angle that the attacker is facing? I think it would be easier because the attacker and the unit being attacked would be facing about the same angle. (+- a few degrees)
12-19-2006, 12:36 AM#5
xombie
Yea thats right, I was trying to get him to understand WHY the math worked, but this code is more efficient. Anyways, I've updated the GUI Don0ndrew this way you won't need the use of Custom Script.
12-19-2006, 04:38 AM#6
PipeDream
Greater/lesser are designed for the entire real line, not the -pi to pi segment used for the circle. So, if the attacker is at 359deg, attacked at 1deg, backstab will not trigger even though they're only two degrees apart. You can juggle them together with if/then/else or do something really bizarre like:
Collapse JASS:
    set dmax = (1-CosBJ(40))*(1-CosBJ(40)) + SinBJ(40)*SinBJ(40) //precompute this number
    set dx = CosBJ(temp1)-CosBJ(temp2)
    set dy = SinBJ(temp1)-SinBJ(temp2)
    if dx*dx+dy*dy < dmax then
        //backstab
    endif
12-19-2006, 04:57 AM#7
xombie
What you say is true; I will PM him and get it all sorted out.

Edit: Are you POSITIVE? I remember making a backstab this way and it's worked perfectly..
12-19-2006, 06:20 AM#8
Captain Griffen
Yours won't work perfectly. When facing roughly east, it will sometimes bug.
12-19-2006, 06:34 AM#9
xombie
Hmm... well the thing is I've done debugging and I noticed that instead of 270°, it brought up -90°. However, when subtracting from say... 90°, it returns an answer of -90°. This doesn't make logical sense unless it first takes 270° and converts it to a range of (0, pi) and (0, -pi).

After running a few debugs, using a loop and GetUnitFacing, I have found that if a unit is facing 270°, GetUnitFacing returns 270.00, instead of -90. Therefore, this should work properly. Right now I'm trying to figure out where I've seen negative numbers on the interval from pi to 2pi (0 to -pi in their terms).

My code should do something like the following if one unit is facing 340° and the other is facing 330°:
Collapse JASS:
    local boolean b1
    local boolean b2 //these booleans are just for clarity.

    set udg_temp1 = GetUnitFacing( <unit> ) //this will return 340.00 -- attacking unit
    set udg_temp2 = GetUnitFacing( <unit> ) //this will return 330.00 -- attacked unit

    set b1 = ( udg_temp1 - 20.00 ) <= ( udg_temp2 ) // 340.00 - 20.00 = 320.00, therefore this is true.
    set b2 = ( udg_temp2 + 20.00 ) >= ( udg_temp2 ) // 340.00 + 20.00 = 360.00, therefore this is true.

    if ( b1 ) and ( b2 ) then //both of the conditions put together enclose an arc of the 360° circle at which the attacker may score backstab damage.
        call Backstab()
    endif

This is all from the knowledge that GetUnitFacing returns a real from 0.00 to 360.00. (Once it gets past 360.00, it resets excluding 0 since it's been accounted for by 360°)
12-19-2006, 11:01 AM#10
Thunder_Eye
not that a units attack occurs before the actual damage, so for example a unit with hover (lich) could stand infront of a unit with its back against it, and make backstab dmg while turning around to face the unit.
12-19-2006, 12:02 PM#11
Anitarf
That's right, Thunder_Eye, that's why you should get the angle between the position of attacking unit and the position of attacked unit instead of the facing angle of attacking unit. The problem with angle between points is that it's return value is between -180 and 180 instead of 0 and 360, so you have to be careful about that.

Here's what I use:
Collapse JASS:
function FlankFactor takes unit att, unit def returns real
    local real array r
    set r[1] = GetUnitX( att )
    set r[2] = GetUnitY( att )
    set r[3] = GetUnitX( def )
    set r[4] = GetUnitY( def )
    set r[5] = Atan2BJ( ( r[4] - r[2] ), ( r[3] - r[1] ) )
    set r[6] = GetUnitFacing( def )
    
    if r[5] < 0.0 then
        set r[5] = r[5] + 360.0
    endif
    set r[7] = RAbsBJ( r[6] - r [5] )
    if r[7] > 180 then
        set r[7] = 360 - r[7]
    endif
    
    return r[7]
    // return value is between 0 and 180
    // 0 means perfect backstab, 180 means frontal attack
endfunction
12-19-2006, 10:14 PM#12
xombie
Lol, I knew I did it that way for a reason. I don't know why wyrmlord had to come 'n mess everything up =(

Anyways, could you tell me how the period on this looks? I know it goes from 0.0, to 180.0. But after that does it go from 0 to -180 or vice versa?