• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Efficiency Question

Level 11
Joined
Aug 11, 2009
Messages
605
Just a quick question which setup of GUI triggers would be more efficient, or maybe it doesnt matter.

If I have, say 100 different Heroes and they each have spells that proc on normal attacks. Which of these two setups would be better to use?

First one would require one for each hero. Maybe this setup is best if the triggers are turned off if no one is playing the specific hero?
  • Passives 1
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (Unit-type of DamageEventSource) Equal to Aspirant (Tsunade)
      • IsDamageAttack Equal to True
    • Actions
Second, only needs one trigger to check, then one trigger for each hero that runs if you are playing that specific hero.
  • Passives 2
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (DamageEventSource is A Hero) Equal to True
      • IsDamageAttack Equal to True
    • Actions
      • For each (Integer A) from 1 to 100, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Unit-type of DamageEventSource) Equal to Hero_Type[(Integer A)]
            • Then - Actions
              • Trigger - Run (This trigger) (checking conditions)
              • Skip remaining actions
            • Else - Actions
And I know I shouldnt use Integer A, its only for showcase :D

Thanks in advance!
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
If you're concerned about performance then you would want to do something like #2 but remove the randomness.

You can use a Hashtable to save which triggers should run for each Hero-Type:
  • Events
    • Time - Elapsed game time is 0.01 seconds
  • Conditions
  • Actions
    • Set Variable Your_Hero_Type = Paladin
    • Set Variable Your_Trigger = Passive Smite Ability <gen>
    • Custom script: set udg_Hero_ID = udg_Your_Hero_Type
    • Set Variable Your_Trigger_Index = ((Load 0 of Hero_ID from Passive_Hashtable) + 1)
    • -------- --------
    • -------- Save this data into the hashtable --------
    • Hashtable - Save Your_Trigger as Your_Trigger_Index of Hero_ID in Passive_Hashtable
    • Hashtable - Save Your_Trigger_Index as 0 of Hero_ID in Passive_Hashtable
Then in your Passives trigger you can load this data and only run the triggers that have been previously saved (if any):
  • Hero Passives
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • IsDamageAttack Equal to True
    • Actions
      • Custom script: set udg_Hero_ID = GetUnitTypeId(udg_DamageEventSource)
      • Set Variable Your_Trigger_Index = (Load 0 of Hero_ID from Passive_Hashtable)
      • -------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Your_Trigger_Index Greater than 0
        • Then - Actions
          • For each (Passive_Index) from 1 to Your_Trigger_Index, do (Actions)
            • Loop - Actions
              • Trigger - Run (Load Passive_Index of Hero_ID from Passive_Hashtable) (checking conditions)
        • Else - Actions
Parent Key:
A hero's unit-type id (an Integer that's only accessible with custom script).

Child Keys:
0: How many triggers a hero-type has saved.
1+: The actual triggers that have been saved.

You could also change this to work for specific Units rather than a Unit-Type, just scrap the Hero_ID variable and use the Unit's handle as the Parent key. This would further optimize it if your map allows duplicates of the same hero. You'd likely want to save a trigger when your hero learns a new skill.
 
Last edited:
Level 11
Joined
Aug 11, 2009
Messages
605
I havnt tried hashtables before but this doesnt seem too bad to start and get to know it :D

For more information, its a Hero Collection RPG map where each player can only have 1 Hero active at a time. However, you can switch between Heroes that you have collected.

But I should just copy/paste the first trigger and change the values for each Hero type that can be played and it should work?

EDIT: This is how a trigger that handles the passives can look (wip)
  • Goku Passives
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • (Unit-type of DamageEventSource) Equal to Aspirant "A" (Goku)
      • IsDamageAttack Equal to True
    • Actions
      • Set VariableSet Goku_Player = (Owner of DamageEventSource)
      • Set VariableSet Goku_PlayerNumber = (Player number of Goku_Player)
      • Set VariableSet Hero_ManaGain = (Random real number between (Real(Hero_ManaPerHitMIN[Goku_PlayerNumber])) and 50.00)
      • Unit - Set mana of DamageEventSource to ((Mana of DamageEventSource) + Hero_ManaGain)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Mana of DamageEventSource) Equal to 1000.00
          • Hero_AutoUlt[Goku_PlayerNumber] Equal to True
        • Then - Actions
          • Unit - Order DamageEventSource to Orc Tauren Chieftain - Shockwave (Position of DamageEventTarget)
        • Else - Actions
      • Set VariableSet Hero_ProcCount[Goku_PlayerNumber] = (Hero_ProcCount[Goku_PlayerNumber] + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Hero_ProcCount[Goku_PlayerNumber] Equal to 5
          • UltraInstinct_Check[Goku_PlayerNumber] Equal to False
          • Hero_ProcViolet[Goku_PlayerNumber] Equal to True
          • Hero_ActiveHeroRank[Goku_PlayerNumber] Greater than or equal to 6
        • Then - Actions
          • Set VariableSet Hero_ProcCount[Goku_PlayerNumber] = 0
          • Set VariableSet Hero_ProcViolet[Goku_PlayerNumber] = False
          • Floating Text - Create floating text that reads |cffa335eeUltra Ins... above DamageEventSource with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
          • Set VariableSet FT_Ability = (Last created floating text)
          • Floating Text - Change FT_Ability: Disable permanence
          • Floating Text - Set the velocity of FT_Ability to 150.00 towards 90.00 degrees
          • Floating Text - Change the lifespan of FT_Ability to 1.50 seconds
          • Floating Text - Change the fading age of FT_Ability to 1.00 seconds
          • Set VariableSet UltraInstinct_Check[Goku_PlayerNumber] = True
          • Unit - Add |cffa335eeUltra Instinct Effect|r (Goku) to DamageEventSource
          • Set VariableSet UltraInstinct_Caster[Goku_PlayerNumber] = DamageEventSource
          • Player Group - Add Goku_Player to UltraInstinct_PlayerGroup
          • Set VariableSet UltraInstinct_Instances = (UltraInstinct_Instances + 1)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • UltraInstinct_Instances Equal to 1
            • Then - Actions
              • Trigger - Turn on Goku Ultra Instinct Loop <gen>
            • Else - Actions
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Hero_ProcCount[Goku_PlayerNumber] Equal to 5
              • Hero_ProcBlue[Goku_PlayerNumber] Equal to True
              • Hero_ActiveHeroRank[Goku_PlayerNumber] Greater than or equal to 4
            • Then - Actions
              • Set VariableSet Hero_ProcCount[Goku_PlayerNumber] = 0
              • Set VariableSet Hero_ProcBlue[Goku_PlayerNumber] = False
              • Floating Text - Create floating text that reads |cff0070ddSpirit Bo... above DamageEventSource with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
              • Set VariableSet FT_Ability = (Last created floating text)
              • Floating Text - Change FT_Ability: Disable permanence
              • Floating Text - Set the velocity of FT_Ability to 125.00 towards 45.00 degrees
              • Floating Text - Change the lifespan of FT_Ability to 1.50 seconds
              • Floating Text - Change the fading age of FT_Ability to 1.00 seconds
              • Set VariableSet Goku_Point = (Position of DamageEventTarget)
              • Set VariableSet SpiritBomb_Caster = DamageEventSource
              • Set VariableSet SpiritBomb_UnitGroup = (Units within 300.00 of Goku_Point matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of Goku_Player.) Equal to True)).)
              • Special Effect - Create a special effect at Goku_Point using war3mapImported\AZ_WSY_Misslie_blue.mdx
              • Special Effect - Set Scale of (Last created special effect) to 0.15
              • Special Effect - Destroy (Last created special effect)
              • Custom script: call RemoveLocation(udg_Goku_Point)
              • Set VariableSet SpiritBomb_Damage = (((Real((Agility of DamageEventSource (Include bonuses)))) x 4.00) + 0.00)
              • Unit Group - Pick every unit in SpiritBomb_UnitGroup and do (Actions)
                • Loop - Actions
                  • Trigger - Turn off Goku Passives <gen>
                  • Unit - Cause SpiritBomb_Caster to damage (Picked unit), dealing SpiritBomb_Damage damage of attack type Spells and damage type Normal
                  • Trigger - Turn on Goku Passives <gen>
              • Custom script: call DestroyGroup(udg_SpiritBomb_UnitGroup)
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Hero_ProcCount[Goku_PlayerNumber] Equal to 5
                  • Hero_ActiveHeroRank[Goku_PlayerNumber] Greater than or equal to 2
                • Then - Actions
                  • Set VariableSet Hero_ProcCount[Goku_PlayerNumber] = 0
                  • Floating Text - Create floating text that reads |cff00ff00Saiyan St... above DamageEventSource with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
                  • Set VariableSet FT_Ability = (Last created floating text)
                  • Floating Text - Change FT_Ability: Disable permanence
                  • Floating Text - Set the velocity of FT_Ability to 100.00 towards 135.00 degrees
                  • Floating Text - Change the lifespan of FT_Ability to 1.50 seconds
                  • Floating Text - Change the fading age of FT_Ability to 1.00 seconds
                  • Set VariableSet Goku_Point = (Position of DamageEventSource)
                  • Set VariableSet SaiyanStrike_Caster = DamageEventSource
                  • Set VariableSet SaiyanStrike_UnitGroup = (Units within 300.00 of Goku_Point matching ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of Goku_Player.) Equal to True)).)
                  • Special Effect - Create a special effect at Goku_Point using war3mapImported\animeslashfinal.mdl
                  • Special Effect - Set Color of (Last created special effect) to r: 125, g: 255, b: 255
                  • Special Effect - Set Position - Z of (Last created special effect) to 50.00
                  • Special Effect - Set Scale of (Last created special effect) to 2.00
                  • Special Effect - Destroy (Last created special effect)
                  • Custom script: call RemoveLocation(udg_Goku_Point)
                  • Set VariableSet SaiyanStrike_Damage = (((Real((Agility of DamageEventSource (Include bonuses)))) x 2.00) + 0.00)
                  • Unit Group - Pick every unit in SaiyanStrike_UnitGroup and do (Actions)
                    • Loop - Actions
                      • Set VariableSet SaiyanStrike_Target = (Picked unit)
                      • Special Effect - Create a special effect attached to the chest of SaiyanStrike_Target using Abilities\Weapons\DragonHawkMissile\DragonHawkMissile.mdl
                      • Special Effect - Destroy (Last created special effect)
                      • Trigger - Turn off Goku Passives <gen>
                      • Unit - Cause SaiyanStrike_Caster to damage SaiyanStrike_Target, dealing SaiyanStrike_Damage damage of attack type Spells and damage type Normal
                      • Trigger - Turn on Goku Passives <gen>
                  • Custom script: call DestroyGroup(udg_SaiyanStrike_UnitGroup)
                • Else - Actions

So I would remove the event+condition from this and each Hero type would have one of these triggers which would run on attack.
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
But I should just copy/paste the first trigger and change the values for each Hero type that can be played and it should work?
Yeah, that's the general idea.

But if you use one big trigger that handles all of a hero's Damage Events then you don't even really need a Hashtable. The idea was to register multiple triggers and only when they actually need to be registered, IE: Upon learning a passive skill for the first time.

With your "one big trigger" design, a Unit Indexer approach would simplify things:
  • Events
    • Unit - A unit Enters playable map area
  • Conditions
    • (Unit-type of (Triggering unit)) Equal to Goku
  • Actions
    • Set Variable Has_Passive_Trigger[(Custom value of (Triggering unit))] = True
    • Set Variable Passive_Trigger[(Custom value of (Triggering unit))] = Goku Passives <gen>
  • Hero Passives
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • IsDamageAttack Equal to True
      • Has_Passive_Trigger[(Custom value of (Triggering unit))] Equal to True
    • Actions
      • Trigger - Run Passive_Trigger[(Custom value of (Triggering unit)] (ignoring conditions)
This methods links the Trigger to the Unit directly by relying on it's custom value. The only downside here is it's limited to one trigger, but that seems to be what you want anyway.

Also, you can ignore/delete the initial Conditions in your Goku Passives trigger since we've confirmed that it's an Attack from Goku already in this Hero Passives trigger.
 
Top