Tutorial Making a Backstab Spell (GUI)

gref

New Member
Reaction score
33
Making a Backstab Spell (GUI)

Demo16.jpg


This tutorial will teach you how to make one of the most commonly requested spells on any Warcraft III forum, and in doing so will show you how to tackle one of the largest troubles blizzard left us with: Damage detection.
First things first, here is what you will need to participate in this tutorial:
1. A vJass preprocessor.
2. The Attack Detection system.


The vJass preprocessor:

Jass is the underlying language of Warcraft III. When you save your map, your triggers made in the GUI trigger editor are converted into Jass, and then compiled. What vJass is, is a better way of structuring Jass so that it loses some of it's inherent limitiations, and gives developers more freedom. What a vJass preprocessor does, is allow you to structure your code in the new vJass style, and then goes and converts it to oldschool Jass. We need the vJass engine, because the Attack Detection system uses it.
So download one of these programs:
- NewGen (This is the most recent and arguably best vJass engine at the moment) http://www.wc3campaigns.net/showthread.php?t=90999
- WEU (World Editor Unlimited)(Also has some other cool features) http://www.wc3campaigns.net/showthread.php?t=81731
- World Editor Helper ( The most like a normal World Editor, this just mods it so it can use vJass as well ) http://www.wc3campaigns.net/showthread.php?t=88535

They are all fairly easy to use, and small and fast to download, but I would probably recommend NewGen, as it is the latest and greatest, and both WEU and World Editor Helper have limitations.

Once you have a vJass preprocessor, you'll need the Attack Detection system.

The Attack Detection System
For this tutorial you can just use the attached map with the Attack Detection system in it, and if you want to use the system in your map, follow the steps in the Readme to copy it in.
If you want to check out more about the system later, for other spells, go here: http://www.thehelper.net/forums/showthread.php?t=80006

Why do we need the Attack Detection system? Because Blizzard decided in all their wisdom not to include a generic Unit Takes Damage event in the World Editor. For a generic unit, the only option you are given is Unit Is Attacked. This causes 2 problems:
A) The unit is attacked event occurs when a unit begins an attack, and doesn't take into account whether a unit misses, or some other action occurs to prevent the attack.
B) Any player can repeatedly attack and cancel, to exploit any bugs if a move is based off this. If you made a Backstab with just the Unit Is Attacked event, they could repeatedly do damage without even landing a hit!

You can get around that by adding all the units specifically to a trigger that detects each particular units damage taken, but what happens when a unit dies? Triggers just add up and lag the map.
Also, how do we know if the unit was damaged by a spell, or by an attack?

This system takes care of that, and allows us an easy way to detect whether it was a spell or attack that caused the damage, and makes sure there are no leaks. Now, lets learn to use it.


The Problems with Backstab

What stops most people making a backstab move are two things: damage detection, and the maths.

We've got past one, lets take a look at the other:
To make a backstab move, the first thing you have to think about is what are the conditions required for this attack to happen. The obvious one is the attacker has to be behind the target.
But is that enough?
Demo1.jpg

This Archer is behind this paladin. Should it be able to backstab it?
No. So only melee units should be able to backstab.

How do we even check that the attacker is behind the target?
Lets look at it. There are two main approaches, both of which require a similar amount of effort in the end.

Way 1 (Using distances):


How will we tell if a unit is behind the paladin? How about we put a point in front of the paladin, and check that unit is further away than the paladin from that point?
Demo2.jpg


Wait...What if the unit is further away on the other side?
Demo3.jpg


Ok ... Why don't we use two points. One directly in front of the paladin, and one directly behind.

Then we can check that the blademaster is closer to the one behind, and the paladin to the one in front.
Demo4.jpg


Ok: As long as the Backstabber is melee, and hes close to the point behind than the paladin, and the paladin is closer to the point in front than the blademaster, we know it's got backstab potential.

Wait a second...that's so complicated it's foolish.


Here is the easy way.
Way 2 (Using angles):


Demo5.jpg

OK, the Paladin is facing to the angle of the green line. Let's call that angle P.
We know that there are 360 degrees in a circle, so directly behind him is P + 180. Realistically for a backstab to occur we want the attacker to be somewhere near that 180, but really anywhere between the 2 red lines is good. That is about 120 degrees between those lines.
Because 120 is a third of 360, P + 120 = one red line, and P - 120 = the other.

So to make sure the blademaster is in the right area, we have to check that: The Angle from the paladin, to the blademaster, is between P - 120 and P + 120.
Another way of saying it:
The absolute value of the difference in angles is greater than 120.


Now we know to detect if a unit is in the right area to backstab, and if it is melee. But no unit should backstab unless it has an ability, or an item that allows it to.
Lets make an ability for that now.

The Backstab Ability


Go to the Object Editor.
Go to Abilities.
Demo6.jpg


Since the actual ability will be completely triggered, we are going to use a Dummy ability so that hero can level it, and so that we can detect whether the unit has this ability when it attacks.

We're going to use Night Elf unit ability Hardened Skin, because is an ability where you can easily deactivate the original effect, and it isn't used very often, so it shouldn't conflict in any map. It also doesn't give our hero any buffs, which can be annoying to players.
Right click on Hardened Skin and click New Custom Ability.
Demo7.jpg


Change the fields:
Code:
Data - Chance to Reduce Damage (%) to 0.00
Data - Ignored Damage to 0.00
Data - Include Melee Damage to False
Data - Include Ranged Damage to False
Data - Minimum Damage to 0.00
Stats - Hero Abilty to True
Stats - Levels to 3
Techtree - Requirements to Nothing
Text - Name to Backstab

And then fill out the Tooltips as you'd like.

I chose Sacrifice as the icon, because you won't get a smoother looking backstab icon.
Demo8.jpg

Make sure you remember to fill out the Learn tooltips, and set the Research Icon to Sacrifice as well.

Now that you have made the ability, the next step is to add it to your hero.
I chose the Blademaster, because he is your stock standard Agility hero, but you can obviously pick anyone.
Go to Units, your hero, and edit Abilities - Hero to add it in.

Now we have our hero set up with his new Backstab dummy ability, lets get to triggering this badboy.
I'm going to go with Way 2, because it's easier (at least in theory), and effort is for people who didn't read this tutorial.


The Backstab Trigger


Go to Trigger Editor.
Make a new Folder called Backstab or something if you haven't already, and then make a new trigger called Backstab.
Demo9.jpg


Completely ignore the Events section, and create a new condition.
Make it Integer Comparison => Unit - Level of Ability For Unit
And set the unit as AD_Attacker (This is a variable you got from the Attack Detection system) and the ability is the Backstab ability we just made. Press enter and change "Equal to 0" to Greater than 0.

That has made it so that only people with the backstab ability will go any further into the trigger.
Demo10.jpg


Now make 2 new variables: point1 and point2, both points.
Demo11.jpg


And make 2 Set Variable Actions:
Code:
Set point1 = (Position of AD_Defender)
Set point2 = (Position of AD_Attacker)
We have set the points where the attacker and defender are so we can use them later and not have memory leaks.

Now make a new action: If / Then / Else, Multiple Functions
Demo12.jpg


Add 1 Condition to the If / Then / Else
Code:
(AD_Attacker is A melee attacker) Equal to True
That's the easy one.

Now add 2 more Conditions to the If / Then /Else
This is where we check if the unit is in the right angle range to backstab.
Go to Real Comparison => Math - Abs => Math - Modulo to find the functions.
Demo13.jpg


Because angles continue in a circle from 0 to 360 and repeat, we have to check not only that the angle is greater than Facing + 120 degrees but also that it is less than Facing + 240 degrees (The 120 degree window). The Absolute value function allows us to do check both +120 and -120 in one function.

Once you have done the conditions, it time for the important bit. The damage and the effects.
Add an action in the actions section of the If \ Then \ Else.
Make it Special Effect - Create Special Effect On Unit
Change "overhead" to "chest", "(Triggering Unit)" to "AD_Defender" and "Abilities\Spells...." to "Abilities => Stampede <Special>."
Code:
Special Effect - Create a special effect attached to the chest of AD_Defender using Abilities\Spells\Other\Stampede\StampedeMissileDeath.mdl

Make another action "Special Effect - Destroy Special Effect" and press enter. We do this so that the effect we just made doesn't sit on the map forever and lag the map.
Code:
Special Effect - Destroy (Last created special effect)

Now make another action: "Unit - Damage Target", and change "(Triggering Unit)" to "AD_Attacker", the second "(Triggering Unit)" to AD_Defender", attack type to "Hero", damage type to "Normal", and the damage to:
Code:
(0.50 x (Real((Level of Backstab  for AD_Attacker)))) x (Real((Agility of AD_Attacker (Include bonuses))))
Demo14.jpg



Lastly, after the If \ Then \ Else statement add 2 custom script actions:
Code:
Custom script:   call RemoveLocation(udg_point1)
Custom script:   call RemoveLocation(udg_point2)

These clean up our point variables from before so that there are no leaks.

We have now finished that trigger, but we still have to make sure that something gives it events so that it runs.


The AD Initialization Trigger


Go to the AD Initialization trigger that you got with the AD System.

Now add the action:
Code:
Set AD_AttackTriggers[0] = Backstab <gen>

This tells the system to run the Backstab trigger when a unit gets damaged. If you already have some triggers in the array, you would set it to the next highest array index instead of 0.
Demo15.jpg



And that is all. The Backstab spell should now be complete.
Test it, and it should look like this:
Demo16.jpg


Now go out and fill the world with blood.

Changes:
Updated the demo map to AD System 1.10b GUI.
Updated tutorial slightly to match.
 

Attachments

  • Backstab.w3x
    73.7 KB · Views: 1,153
Reaction score
456
Why not to compare the units' facing in a easy way:

Code:
(Facing of <Unit A>) Less than or equal to ((Facing of <Unit B>) + 45.00)
(Facing of <Unit A>) Greater than or equal to ((Facing of <Unit B>) - 45.00)
Adds more freedom for the user, as those two values can be so easily modified.
 

gref

New Member
Reaction score
33
One reason: When a unit attacks and is not facing the unit it is attacking, it doesn't turn fully, and then attack.
Instead it attacks then turns. So that method is flawed unless the backstabber walks up to the target in a straight line, from behind it.

I already tried that when I made a backstab trigger ages ago. This allows that first attack each time.
 

gref

New Member
Reaction score
33
Um...Thats what the system does.

It just also does the hard work of adding every single potential target to the system, and then making sure the triggers created for those targets don't leak.

The difference being, that it changes the 3 triggers + conditions you would have to make, into one short trigger, and then also cleans up after itself.
 

Nathan0093

New Member
Reaction score
4
There is a problem with this system. If you order a unit to attack-ground then the game will crash. Please fix it :)
 

Nathan0093

New Member
Reaction score
4
I just found some more errors. This system also disables the "barrage" ability and makes all missile attacks automatically homed in to the target.
 

Romek

Super Moderator
Reaction score
963
There is a problem with this system. If you order a unit to attack-ground then the game will crash. Please fix it :)

o_O

I just found some more errors. This system also disables the "barrage" ability and makes all missile attacks automatically homed in to the target.

That happens if its enabled. It doesn't if its disabled. I don't think it's anything to do with the system/tutorial...

Not Bad.. Not Brilliant..
 

Nathan0093

New Member
Reaction score
4
^ I didnt mean to say that "barrage" made missile attacks homed. Other units who didnt have "Barrage" also had their missiles homed into their targets. I also made sure that the homing missile box is disabled for all of my units. When I turned off the system's functions everything went back to normal.
 

gref

New Member
Reaction score
33
You should able to change the missile homing the the Attack Detection orb.

Sorry for a late reply. This is the first time I've been on this forum in months.
Also, attack-move is in no way affected by this system... so that must be a bug with whatever map you used it in.
 

Nathan0093

New Member
Reaction score
4
^ Not attack-move. Its attack-ground order thats only available to artillery/siege attack type. I tried it in your tutorial map and it crashed showing the same error message. How does this system work? Is it like this: When a unit attacks you add the AD_Orb to it and identify it as the "attacker" while the attacked unit has the buff and is labeled "defender"? If so then can you possibly modify the trigger so that it does not give the AD_Orb to the artillery unit when they do an AoE attack on the ground aka Attack-ground?
 

monoVertex

I'm back!
Reaction score
460
Please take it out of spoiler. First, as a tutorial, there's no problem with the length, second, words within spoilers are not included in searches (I think, not sure) and are not "read" by search engines spiders.
 

NaPzt3R

You can change this now in User CP.
Reaction score
38
I don't see the point with the Attack Detection system. I made min like this:

Code:
Backstab
    Events
        Unit - A unit Is attacked
    Conditions
        (Level of Backstab  for (Attacking unit)) Greater than or equal to 0
    Actions
        Set BACKSTAB_target_view_angle = (Facing of (Attacked unit))
        Set BACKSTAB_attacker = (Attacking unit)
        Set BACKSTAB_target = (Attacked unit)
        Set BACKSTAB_random_dmg = (Real((Random integer number between 80 and 140)))
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            If - Conditions
                ((Abs(((Angle from (Position of BACKSTAB_target) to (Position of BACKSTAB_attacker)) mod 360.00))) - ((Facing of BACKSTAB_target) mod 360.00)) Greater than 120.00
                ((Abs(((Angle from (Position of BACKSTAB_target) to (Position of BACKSTAB_attacker)) mod 360.00))) - ((Facing of BACKSTAB_target) mod 360.00)) Less than 240.00
            Then - Actions
                Unit - Make BACKSTAB_attacker face BACKSTAB_target over 0.00 seconds
                Unit - Cause BACKSTAB_attacker to damage BACKSTAB_target, dealing BACKSTAB_random_dmg damage of attack type Hero and damage type Normal
                Special Effect - Create a special effect attached to the origin of BACKSTAB_target using Objects\Spawnmodels\Orc\OrcLargeDeathExplode\OrcLargeDeathExplode.mdl
                Special Effect - Destroy (Last created special effect)
                Special Effect - Create a special effect attached to the weapon of BACKSTAB_attacker using Abilities\Spells\Human\FlameStrike\FlameStrikeDamageTarget.mdl
                Special Effect - Destroy (Last created special effect)
                Animation - Play BACKSTAB_attacker's attack slam animation
                Floating Text - Create floating text that reads (String(BACKSTAB_random_dmg)) at (Position of BACKSTAB_target) with Z offset 0.00, using font size 11.00, color (0.00%, 100.00%, 0.00%), and 0.00% transparency
                Floating Text - Change (Last created floating text): Disable permanence
                Floating Text - Change the age of (Last created floating text) to 0.00 seconds
                Floating Text - Change the fading age of (Last created floating text) to 3.00 seconds
                Floating Text - Change the lifespan of (Last created floating text) to 4.00 seconds
            Else - Actions

Edit: Oh... Forgot to read some of the tutorial :p My bad.
 
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