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

Taunt System

Taunt System - Solu9

Table of content
  • What does the Taunt System do?
  • How to implement
  • Requirements
  • How to get the original owner of a currently taunted unit

What does the Taunt System do?

This system will let units with the Taunt ability force targeted units to only auto attack them for a set duration.
For the duration of the Taunt, the owner of the taunted unit will be unable to control it.


Fairly standard procedure. Copy the three triggers; "Taunt Setup", "Taunt Start", and "Taunt Duration" and paste them into your map (remember to enable "Automatically create unknown variables while pasting trigger data" under File -> Preferences -> General).
Next, copy and paste the following from the test map to your map (TauntBuffer + TauntBuff + Taunt + Taunted + TauntReq):


ZBwlH9C.jpg
1B61j9z.jpg
wyQdEdI.jpg
NBv8UM0.jpg


Give the TauntBuffer unit the TauntBuff ability which must have its Buff value set to the Taunted buff.
Give the ability Taunt to the units you want to be able to use Taunt.
That should be it for implementing the system. However there a a few requirements you must fulfill for the system to work.

There are two main requirements you must be able to fulfill if you want to use this system.

Firstly you need to disable usage for the swapper ally players of any ability that is not allowed to be used by a unit that is taunted (More on swapper ally players further down).
So you have two options to do so.

OPTION 1:
You can go the upgrade route.
Here you need to use the TauntReq upgrade you imported earlier. ANY ability that is not allowed to be used while taunted must have the Techtree - Requirement of the TauntReq upgrade, as shown below.


hslP9Mr.jpg


Your TauntSetup trigger should look like this for Option 1:

IGs06J5.jpg


OPTION 2:
You can also go the disable-ability route.
Here you disable ability use for the swapper ally players, in the map initialization. Each and every ability that is not allowed to be used by a unit that is taunted, must be set in this trigger.
Your TauntSetup trigger should look like this for Option 2:


HZmGX1J.jpg


Cons:
No matter what option you choose you have to copy and paste quite a lot.
Option 1 on paper looks like the best but comes with one drawback. The TauntReq upgrade, will show up on unlearned abilities.


QdEE4mX.jpg

This is ONLY cosmetic though, and won't have any effect while the game is running.

Option 2 has no cosmetic flaws, but depending on how many abilities you have in your map, the loading time may take a hit.
Ultimately it's up to you to decide which option fits you the best.
Please note that the test map provided here uses Option 1 by default.


Secondly. You must set up your teams (or forces) so each team has a swapper ally player that is computer controlled.


M38ORFk.jpg
EmLdWFn.jpg


This is the setup from the test map.
A swapper ally player is a computer controlled player which a taunted unit changes owner to while the Taunt lasts. Therefore each team in your map must have such a swapper ally.
Using Option 1 all swapper allies DO NOT have the upgrade TauntReq researched for them in the map initialization and will thus not be able to use any abilities. When the Taunt fades from a unit, the unit will swap back to its original owner, and regain the TauntReq upgrade to again be able to use abilities.
Same thing happens with Option 2, just without the TauntReq upgrade needed.

The current Taunt Setup trigger takes into account how many teams there are in the map (no matter if you choose Option 1 or 2), so I would highly advice that for swapper ally players, you use the last player (player 24) and go downwards accordingly to how many teams you have. Two teams = player 24 +23, three teams = player 24 + 23 + 22, etc.
As is, the system is set up for two teams. If you require more teams you have to add more conditions to this part of the Taunt Start trigger:


eVou90T.jpg

If you need to know, or use, the real owner of a unit that is currently taunted you can do it like so:

  • Test Map Specifics 1
    • Events
    • Conditions
      • ((Triggering unit) has buff Taunted ) Equal to True
    • Actions
      • Set VariableSet TempPlayer = (Load (Key Player.) of (Key (Triggering unit).) in TauntedHash.)

Where Triggering Unit is the unit you want to know the owner of. Play around with it and see how you need to go about it in your map.

I think that is all.
I hope you can find a use for this system in your map, and feel free to ask if you have any question.


  • Taunt Setup
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set VariableSet TauntDuration = 5.00
      • -------- --------------------------- --------
      • -------- Choose how you want to restrict taunted units in using abilities. --------
      • -------- --------------------------- --------
      • -------- 1. Upgrade restriction --------
      • For each (Integer Taunted_int) from 1 to (24 - (Number of teams)), do (Actions)
        • Loop - Actions
          • Player - Set the current research level of TauntReq to 1 for (Player(Taunted_int))
      • -------- --------------------------- --------
      • -------- 2. Ability restriction --------
      • For each (Integer Taunted_int) from (24 - (Number of players)) to 24, do (Actions)
        • Loop - Actions
          • Player - Disable Animate Dead for (Player(Taunted_int))
          • Player - Disable Avatar for (Player(Taunted_int))
          • -------- Do this for every ability in your map that you don't want to be able to be used while a unit is taunted --------
      • -------- --------------------------- --------
      • Hashtable - Create a hashtable
      • Set VariableSet TauntedHash = (Last created hashtable)
  • Taunt Start
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Taunt
    • Actions
      • Set VariableSet TauntedPlayer = (Owner of (Target unit of ability being cast))
      • Set VariableSet TauntedUnit = (Target unit of ability being cast)
      • -------- ------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Load (Key Timer.) of (Key (Target unit of ability being cast).) from TauntedHash.) Greater than 0.00
        • Then - Actions
        • Else - Actions
          • Hashtable - Save Handle OfTauntedPlayer as (Key Player.) of (Key (Target unit of ability being cast).) in TauntedHash.
      • -------- ------------------------------- --------
      • Hashtable - Save Handle OfTauntedUnit as (Key Unit.) of (Key (Target unit of ability being cast).) in TauntedHash.
      • Hashtable - Save Handle Of(Triggering unit) as (Key Target.) of (Key (Target unit of ability being cast).) in TauntedHash.
      • Hashtable - Save TauntDuration as (Key Timer.) of (Key (Target unit of ability being cast).) in TauntedHash.
      • Unit Group - Add TauntedUnit to TauntedGroup
      • -------- ------------------------------- --------
      • Set VariableSet TauntPoint = (Position of (Triggering unit))
      • Unit - Create 1 TauntBuffer for (Owner of (Triggering unit)) at TauntPoint facing Default building facing degrees
      • Set VariableSet TauntBufferUnit = (Last created unit)
      • Unit - Order TauntBufferUnit to Human Sorceress - Slow TauntedUnit
      • Unit - Add a 1.00 second Generic expiration timer to TauntBufferUnit
      • Custom script: call RemoveLocation(udg_TauntPoint)
      • -------- ------------------------------- --------
      • -------- Decide your forces. If you have more than two force, then add more conditions --------
      • -------- ------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (TauntedPlayer is in (All allies of Player 1 (Red).).) Equal to True
        • Then - Actions
          • Unit - Change ownership of TauntedUnit to Player 24 (Peanut) and Change color
        • Else - Actions
          • Unit - Change ownership of TauntedUnit to Player 23 (Emerald) and Change color
      • -------- ------------------------------- --------
      • Unit - Order TauntedUnit to Attack (Triggering unit)
      • Trigger - Turn on Taunt Duration <gen>
  • Taunt Duration
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in TauntedGroup and do (Actions)
        • Loop - Actions
          • Set VariableSet TauntTimer = (Load (Key Timer.) of (Key (Picked unit).) from TauntedHash.)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • TauntTimer Less than or equal to 0.00
            • Then - Actions
              • Unit - Change ownership of (Picked unit) to (Load (Key Player.) of (Key (Picked unit).) in TauntedHash.) and Change color
              • Hashtable - Clear all child hashtables of child (Key (Picked unit).) in TauntedHash.
              • Unit Group - Remove (Picked unit) from TauntedGroup.
            • Else - Actions
              • Hashtable - Save (TauntTimer - 0.03) as (Key Timer.) of (Key (Picked unit).) in TauntedHash.
              • Unit - Order (Picked unit) to Attack (Load (Key Target.) of (Key (Picked unit).) in TauntedHash.)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in TauntedGroup) Equal to 0
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
Contents

Taunt System 1.1 - Solu9 (Map)

Reviews
Wrda
There are parts of actions which still use (Target unit of ability being cast) instead of the variable that refers to it. Death Type on dummy should be can't raise, doesn't decay. You only need one dummy unit for instant casts, no need to recreate it...
Thanks for the reply.
I was not aware of this function. Will it be able to know what specific abilities are on a given unit?
No, but it can disable a single ability on a unit without affecting other units owned by the same player. Also hides the UI button as well.
Disabling & hiding UI button with this function have a counter, which means for each true/false call there must be exactly one false/true call to revert a disabled/hidden flag to its default state.
 
No, but it can disable a single ability on a unit without affecting other units owned by the same player. Also hides the UI button as well.
Disabling & hiding UI button with this function have a counter, which means for each true/false call there must be exactly one false/true call to revert a disabled/hidden flag to its default state.
Then I don't understand why that would be a better solution. The system would then need to know what specific abilities the taunted unit has, which would require a tremendous amount of setup triggers. Unless I'm missing the point.
In the system as is, there is no need to hide UI elements, since the unit is swapped to an computer controlled ally of the player getting taunted. Which is the whole point. The owner of the taunted unit looses complete control over the unit, but the unit is still allied to the taunted player's allies.
The only function of that computer swapper ally is to act as a taunt buffer player, and is not supposed to be an actual played player in the map.
 
If you want to make the owner lose complete control over the unit, why not force deselect the taunted unit (Remove unit from selection for player) inside the periodic trigger for the user? You wouldn't have to involve an external player.
if you spam select the unit you will still be able to control it, albeit not without difficulty.
Swapping controller gets rid of freak scenarios. The owner of the taunted unit simply can't control the unit, even if able to select it. Which, well in my book, is the definition of a true taunt.
I believe there have been plenty of different solutions to taunt abilities. But non without some form of drawback. That is what I have tried to achieve here.
 

Wrda

Spell Reviewer
Level 25
Joined
Nov 18, 2012
Messages
1,864
There are parts of actions which still use (Target unit of ability being cast) instead of the variable that refers to it.
Death Type on dummy should be can't raise, doesn't decay.
You only need one dummy unit for instant casts, no need to recreate it.
If you're using 1.33 or 1.32 (I think?), you can use BlzGroupGetSize to get the size of group to turn the periodic trigger off instead of relying on ones that have to loop through the whole group:
  • Custom script: if BlzGroupGetSize(udg_TauntedGroup) == 0 then
  • Trigger - Turn off (This trigger)
  • Custom script: endif
This still has another limitation not mentioned, if the mapmaker uses "Fixed Player Settings", then when hovering the unit that swapped the owner to swapper player will mention the latter's name instead of the actual owner.

Yet, this is an alternative to the taunt ability from mountain giants which works and is more forceful and not "cancelable easily".

Approved
 
Top