HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Detecting a "Backstab" (GUI)

03-21-2007, 05:12 AM#1
Pyrogasm
What A "Backstab" Is

There appears to be a desire with people these days to make spells and/or systems based off of "backstabbing". Essentially, a backstab is a check that goes off when a unit is attacked which compares each unit's facings to see if it is within a specific angle.

The Procedure

In order to get our backstab working, we must understand the general steps behind doing so. I will be doing this as though I am detecting when a unit with some passive backstab ability attacks, and will do 50*Level damage and display a text message.

The procedure:
  1. Register the Event
  2. Check to make sure the unit has the ability
  3. Get the units' angles
  4. Get the difference between the angles
  5. Check to see if that difference is within the specific range
  6. Do our other actions

What You'll Need

We will be using a JASS function to get the angle difference (it is possible in GUI alone; see bottom of tutorial), thus we will need this function. Here is the function by Vexorian, with a description of each line by Ammorth:
Quote:
Originally Posted by Ammorth
Collapse JASS:
function Backstab_GetAngleDifference takes real a1, real a2 returns real
     local real x
        // The Modulo will get the co-terminal angle if the angle is less than -360 or greater than 360.
        set a1=ModuloReal(a1,360)
        set a2=ModuloReal(a2,360)
        // makes sure angle 1 is the smaller angle.  If it isn't it switches them.
        if a1>a2 then
            set x=a1
            set a1=a2
            set a2=x
        endif
        // Subtracts 360, to get the first negative co-terminal angle, this is then used in a comparison to check if the angle is greater than 180
        set x=a2-360
        if a2-a1 > a1-x then
            //  If it is, use the negative angle instead
            set a2=x
        endif
        //  Now, get the difference between the 2 angles.
        set x=a1-a2
        //  If the difference is negative, make it positive and return it.  If its positive, return it.
        if (x<0) then
            return -x
        endif
     return x
    endfunction
Next, we'll need our trigger; let's call it "Backstab Test". Then, we'll add our events and conditions to it:
Trigger:
Backstab Test
Collapse Events
Unit - A unit is attacked
Collapse Conditions
(Level of (Backstab Test Ability) for (Attacking Unit)) greater than 0
Actions
Finally, this will require a variable; we'll call it "Backstab_Angle". It should look like this:

Zoom (requires log in)

Setting Up The Check

The first thing to do is import the JASS code into the map. Put it in the "custom script" section of the map header (click on the thing where it says "Your Map Name (Whatever it is).w3x" in the trigger editor). It should look like this:

Zoom (requires log in)

Next, we'll need to set up the angle checking part of our trigger, we'll do this by using the local variable GUI bug, as discussed in "Method 3" in this tutorial. Then, we'll call our new JASS script, and set the variable equal to that, by adding these lines to the top of the trigger:
Trigger:
Custom script: local real udg_Backstab_Angle
Custom script: set udg_Backstab_Angle = Backstab_GetAngleDifference(GetUnitFacing(GetTriggerUnit()), GetUnitFacing(GetAttacker()))
Note: the "udg_" is required before the variable name! If you leave it out, you'll get compile errors.

Last, we'll need an If/Then/Else that compares "Backstab_Angle" to the allowed angle range and executes our actions if it's within the range. Let's say our range is 60*. It should look like this:
Trigger:
If (All Conditions are true) then do (Then actions) else do (Else actions)
Collapse If - Conditions
Backstab_Angle less than or equal to 60.00
Collapse Then - Actions
Unit - Cause (Attacking unit) to damage (Triggering unit) dealing (50 * (Level of (Backstab Test Ability) for (Attacking Unit))) damage of attack type Normal and damage type Universal
Floating Text - Create floating text that reads |cff6600Backstab!|r above (Attacking Unit) with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
Floating Text - Change (Last created floating text): Disable permenance
Floating Text - Set the lifespan of (Last created floating text) to 2.25 seconds
Else - Actions

Putting It Together

All put together, the whole trigger would look like this:
Trigger:
Backstab Test
Collapse Events
Unit - A unit is attacked
Collapse Conditions
(Level of (Backstab Test Ability) for (Attacking Unit)) greater than 0
Collapse Actions
Custom script: local real udg_Backstab_Angle
Custom script: set udg_Backstab_Angle = Backstab_GetAngleDifference(GetUnitFacing(GetTriggerUnit()), GetUnitFacing(GetAttacker()))
Collapse If (All Conditions are true) then do (Then actions) else do (Else actions)
Collapse If - Conditions
Backstab_Angle less than or equal to 60.00
Collapse Then - Actions
Unit - Cause (Attacking unit) to damage (Triggering unit) dealing (50 * (Level of (Backstab Test Ability) for (Attacking Unit))) damage of attack type Normal and damage type Universal
Floating Text - Create floating text that reads |cff6600Backstab!|r above (Attacking Unit) with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
Floating Text - Set the velocity of (Last created floating text) to 64.00 towards 90.00 degrees
Floating Text - Change (Last created floating text): Disable permenance
Floating Text - Set the lifespan of (Last created floating text) to 2.25 seconds
Else - Actions

Backstab_GetAngleDifference re-written in GUI


For all you hardcore GUIers, you can eliminate the JASS script alltogether by creating variables "x", "a1", and "a2", and putting this in lieu of the 2nd custom script call.
Trigger:
Set a1 = (Facing of (Triggering unit))
Set a2 = (Facing of (Attacking unit))
Set a1 = (a1 mod 360.00)
Set a2 = (a2 mod 360.00)
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
a1 Greater than a2
Collapse Then - Actions
Set x = a1
Set a1 = a2
Set a2 = x
Else - Actions
Set x = (a2 - 360.00)
If ((a2 - a1) Greater than (a1 - x)) then do (Set a2 = x) else do (Do nothing)
Set x = (a1 - a2)
If (x Less than 0.00) then do (Set Backstab_Angle = (x x -1.00)) else do (Set Backstab_Angle = x)



And there you have it! A simple, passive backstab spell! This same method can be used, for instance, to deal extra damage when a unit uses a spell, etc.

Coming next:
  • Demo map
  • JASS function re-written in GUI Done.
  • Non-broken pictures Done.
  • How to have a unit deal extra % damage on an attack (will require JASS and dynamic triggers)

Thanks to emjl3r for informing me of the lines I forgot.
Attached Images
File type: pngPicture 1.png (5.4 KB)
File type: pngPicture 2.png (70.9 KB)
03-21-2007, 06:26 AM#2
wyrmlord
Seems like this topic would be more suited as a sample due to how specific it is. But, the tutorial is written fairly well so I think it's fine. However, I might suggest attaching a map using the back-stab as an example as well. +Rep for the nice (even if it seems a bit too specific) tutorial.

EDIT: Post number 333!
03-21-2007, 10:18 AM#3
Av3n
broken links make a demo for this

-Av3n
03-21-2007, 04:59 PM#4
emjlr3
in your put it all togther, you left out that part that actually sets the real's value in the first place, and why use a local real? I don't see the need to do that
03-21-2007, 07:30 PM#5
Pyrogasm
emjlr3, I'm using a local real just because it makes the code more sound (it would be fine to do it without the local, though), and thanks for letting me know I forgot a few lines!


Off-topic: How much rep do I have? I thought I had 175ish, but I no longer have a blue gem, and it says I have 131. I am on a school computer, so it could just be retarded.
03-23-2007, 04:20 AM#6
Pyrogasm
Allrighty, I fixed those pictures and re-wrote the code in GUI for those who cannot comprehend JASS scripts.

Aside from a demo map, what else should I have to get this approved?
04-28-2007, 08:31 AM#7
PitzerMike
A demo map will be more than sufficient.
Well done!
I'll approve this, but if you can, a demo would still be nice.
04-28-2007, 06:05 PM#8
Dark.Revenant
I managed to get the "backstab" effect working with much simpler triggers. I wonder why mine worked if it needs to be this complex...
04-29-2007, 10:27 PM#9
Pyrogasm
Well, Dark.Revenant, what did you do?

Oh, and this is a bit buggy. If you spam the attack button when behind some unit, you can deal bonus damage without actually attacking. The smart thing to do would be to use JASS and Dynamic triggers to detect the actual damage.

Maybe I'll do that tutorial sometime.

Demo map on the way.
04-30-2007, 06:34 AM#10
Zwan
ya pyro, wtf, why dont you just use

Trigger:
((Attacking unit) is behind (Attacked unit) Equal to True


/sarcasm off
04-30-2007, 05:08 PM#11
Pyrogasm
Quote:
Originally Posted by Zwan
ya pyro, wtf, why dont you just use

Trigger:
((Attacking unit) is behind (Attacked unit) Equal to True


/sarcasm off
:)

Really, Dark.Revenant, what did you do?
05-02-2007, 02:10 AM#12
Dark.Revenant
It was roughly 20 GUI lines total. It works perfectly. Unfortunately, it is map specific and is used to calculate rear hits and side hits from tank shells in Tank Blitz II.

Trigger:
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
Collapse Or - Any (Conditions) are true
Collapse Conditions
Collapse And - All (Conditions) are true
Collapse Conditions
(Abs(((Facing of TempTank) - (Facing of TempShot)))) Less than or equal to 225.00
(Abs(((Facing of TempTank) - (Facing of TempShot)))) Greater than or equal to 135.00
zOptimizer[(Player number of (Owner of TempTank))] Equal to True
Collapse Then - Actions
Set TempHit = 1
Collapse Else - Actions
Collapse If (All Conditions are True) then do (Then Actions) else do (Else Actions)
Collapse If - Conditions
Collapse Or - Any (Conditions) are true
Collapse Conditions
Collapse And - All (Conditions) are true
Collapse Conditions
(Abs(((Facing of TempTank) - (Facing of TempShot)))) Less than 135.00
(Abs(((Facing of TempTank) - (Facing of TempShot)))) Greater than or equal to 45.00
Collapse And - All (Conditions) are true
Collapse Conditions
(Abs(((Facing of TempTank) - (Facing of TempShot)))) Greater than 225.00
(Abs(((Facing of TempTank) - (Facing of TempShot)))) Less than or equal to 315.00
Collapse Then - Actions
Set PiercingValue = (PiercingValue + 2)
Set TempHit = 2
Collapse Else - Actions
Set PiercingValue = (PiercingValue + 4)
Set TempHit = 3
08-28-2007, 01:16 AM#14
Pyrogasm
Glad to see you contributed to this thread.
09-12-2007, 06:36 PM#15
Juliano
Nice, but I really hate JASS and custom script, EVERY TIME that I attemp to do something with them theres a error!Graaaah this is driving me crazy!

Why this isn't working?
set udg_Backstab_Angle = Backstab_GetAngleDifference(GetUnitFacing(GetAttackedUnit()), GetUnitFacing(GetAttacker()))