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

Help! Chain Lightning Trigger Doesn't Work!

Status
Not open for further replies.
Level 6
Joined
Aug 31, 2018
Messages
157
Sometimes when "Chain Lightning" is used it does not hit the other two or one target(s) near the main target.

And when there are only two targets, it hits the main target, and not the second target.

So it works maybe 50% of the time.


So.. How to fix it so that it hits the required targets all the time?
 

Attachments

  • Lightning 1.png
    Lightning 1.png
    315.7 KB · Views: 23
  • Lightning 2.png
    Lightning 2.png
    302 KB · Views: 24
Level 24
Joined
Feb 9, 2009
Messages
1,787
Even with zoom I can't read it, try posting it in [] code tags, check this:
 
Level 2
Joined
Jun 8, 2020
Messages
11
Holy, Sorry man, I tried already)

1626084831102.png
1626084845674.png


Even with zoom I can't read it, try posting it in [] code tags, check this:
I attached new scrns
 
Last edited:
Level 25
Joined
Sep 26, 2009
Messages
2,378
You should just copy and paste the trigger like @Devalut showed, since some longer conditions (i.e. your unit group creation) is cut off.
From what I see, you have a few issues
  • the spell is not MUI, so multiple casts at the same time will break the spell
  • waits are inaccurate and even worse if your map is supposed to be multiplayer map
  • the way you pick target units is faulty as well - you can end up picking nearby dead units, but also the original target multiple times (I assumed that based on your posts, since ultimately the text is cut off there). You should just create one unit group which consists of allies of the target unit, but not the target unit itself, and pick two random units from it.
  • there are some memory leaks - mainly when you call "Position of (unit)" you create a location that needs to be destroyed later.
I think the main issue may be with the faulty way you pick units and then the conditions you use to determine if you should create a dummy unit or not.
 
Level 2
Joined
Jun 11, 2011
Messages
8
Thank you for your assistance ahead of time, and for your patience with this. @Nichilus
  • It won't be utilizing mui that's just how it is set up; For there to be two different triggers with different arrays.
  • Elaborate the wait time issue.
  • The further you dig into the unit groups the full check is for the following: Units within 550 of position of AT_CL[1] matching - Belongs to an ally of Owner of trigger unit "false", Not equal to AT_CL[1], mechanical equal to "false", is alive "true", buff stealth "false".
  • The problem with the "You should just create one unit group which consists of allies of the target unit, but not the target unit itself, and pick two random units from it." is that when done in that way the chain lightning tends to hit the same target twice every once in a while. (Not something it should be allowed to do)

What conditions would you suggest be used?


  • Chain Lightning Alliance
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chain Lightning Elemental Shaman
      • ((Triggering unit) belongs to an ally of Player 1 (Red).) Equal to True
    • Actions
      • Set VariableSet AvengerTargets_ChainLightning[1] = (Target unit of ability being cast)
      • Set VariableSet UnitGroup = (Units within 550.00 of (Position of AvengerTargets_ChainLightning[1]) matching (((((Matching unit) belongs to an ally of (Owner of (Triggering unit)).) Equal to False) and ((Matching unit) Not equal to AvengerTargets_ChainLightning[1])) and (((Matching unit)
      • Set VariableSet AvengerTargets_ChainLightning[2] = (Random unit from UnitGroup)
      • Custom script: call DestroyGroup (udg_UnitGroup)
      • Set VariableSet UnitGroup = (Units within 550.00 of (Position of AvengerTargets_ChainLightning[2]) matching (((((Matching unit) belongs to an ally of (Owner of (Triggering unit)).) Equal to False) and ((Matching unit) Not equal to AvengerTargets_ChainLightning[1])) and ((((Matching unit
      • Set VariableSet AvengerTargets_ChainLightning[3] = (Random unit from UnitGroup)
      • Custom script: call DestroyGroup (udg_UnitGroup)
      • Game - Display to (All players) the text: |cffb4ff00 1|r
      • Game - Display to (All players) the text: (Name of AvengerTargets_ChainLightning[1])
      • Wait 0.44 seconds
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (AvengerTargets_ChainLightning[2] Not equal to No unit) and ((AvengerTargets_ChainLightning[2] Not equal to AvengerTargets_ChainLightning[1]) and (AvengerTargets_ChainLightning[2] Not equal to AvengerTargets_ChainLightning[3]))
        • Then - Actions
          • Unit - Create 1 Dummy Basic No Ability for (Owner of (Triggering unit)) at (Position of AvengerTargets_ChainLightning[1]) facing Default building facing degrees
          • Unit - Add Chain Lightning Dummy Elemental Shaman to (Last created unit)
          • Unit - Set level of Chain Lightning Dummy Elemental Shaman for (Last created unit) to (Level of Chain Lightning Elemental Shaman for (Triggering unit))
          • Unit - Add a 3.00 second Generic expiration timer to (Last created unit)
          • Unit - Order (Last created unit) to Orc Far Seer - Chain Lightning AvengerTargets_ChainLightning[2]
          • Game - Display to (All players) the text: |cffffc800 2|r
          • Wait 0.22 seconds
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (AvengerTargets_ChainLightning[3] Not equal to No unit) and ((AvengerTargets_ChainLightning[3] Not equal to AvengerTargets_ChainLightning[1]) and (AvengerTargets_ChainLightning[3] Not equal to AvengerTargets_ChainLightning[2]))
            • Then - Actions
              • Unit - Create 1 Dummy Basic No Ability for (Owner of (Triggering unit)) at (Position of AvengerTargets_ChainLightning[2]) facing Default building facing degrees
              • Unit - Add Chain Lightning Dummy Elemental Shaman to (Last created unit)
              • Unit - Set level of Chain Lightning Dummy Elemental Shaman for (Last created unit) to (Level of Chain Lightning Elemental Shaman for (Triggering unit))
              • Unit - Add a 3.00 second Generic expiration timer to (Last created unit)
              • Unit - Order (Last created unit) to Orc Far Seer - Chain Lightning AvengerTargets_ChainLightning[3]
              • Game - Display to (All players) the text: |cffb4ffff 3|r
            • Else - Actions
              • Game - Display to (All players) the text: |cffff0000 3 [NO T...
              • Set VariableSet AvengerTargets_ChainLightning[1] = No unit
              • Game - Display to (All players) the text: |cff00ff00 [1 RES...
              • Set VariableSet AvengerTargets_ChainLightning[2] = No unit
              • Game - Display to (All players) the text: |cffffff00 [2 RES...
              • Set VariableSet AvengerTargets_ChainLightning[3] = No unit
              • Game - Display to (All players) the text: |cff00ffff [3 RESET...
              • Game - Display to (All players) the text: |cff00ff00 [Good to...
        • Else - Actions
          • Game - Display to (All players) the text: |cffff0000 2 [NO T...
          • Set VariableSet AvengerTargets_ChainLightning[1] = No unit
          • Game - Display to (All players) the text: |cff00ff00 [1 RES...
          • Set VariableSet AvengerTargets_ChainLightning[2] = No unit
          • Game - Display to (All players) the text: |cffffff00 [2 RES...
          • Set VariableSet AvengerTargets_ChainLightning[3] = No unit
          • Game - Display to (All players) the text: |cff00ffff [3 RESET...
          • Game - Display to (All players) the text: |cff00ff00 [Good to...
      • Wait 1.00 seconds
      • Game - Display to (All players) the text: |cffff0000 [HARD...
      • Set VariableSet AvengerTargets_ChainLightning[1] = No unit
      • Game - Display to (All players) the text: |cff00ff00 [1 RES...
      • Set VariableSet AvengerTargets_ChainLightning[2] = No unit
      • Game - Display to (All players) the text: |cffffff00 [2 RES...
      • Set VariableSet AvengerTargets_ChainLightning[3] = No unit
      • Game - Display to (All players) the text: |cff00ffff [3 RESET...
      • Game - Display to (All players) the text: |cff00ff00 [Good to...
 
Last edited:
Level 25
Joined
Sep 26, 2009
Messages
2,378
It won't be utilizing mui that's just how it is set up; For there to be two different triggers with different arrays.
Well, MUI makes it easier, as you will have only one code, instead of duplicates with different variables. And if you already have some MUI spells in your map, it's better to be consistent with your approach. Of course, how you deal with it in the end is up to you.

Elaborate the wait time issue.
Even when you set wait time to 0.22 seconds, the actual wait time is each time different - i.e. 0.28 the first time, 0.33 the second time, 0.30 the third time, etc.
This wait time is further off in multiplayer as there is an added latency due to synchronization of all players.
Last but not least, after Wait you may lose reference to some unit functions - i.e. "Target unit of ability being cast" may no longer point to target in your trigger. Only (Triggering unit) is immune to this, as far as I know.
So if you want to have accurate delays, you should use timers.
Also, I found some ancient post with statistics of wait delay, check the tables for single player and multiplayer: Wait Command, Good or Bad?


The further you dig into the unit groups the full check is for the following: Units within 550 of position of AT_CL[1] matching - Belongs to an ally of Owner of trigger unit "false", Not equal to AT_CL[1], mechanical equal to "false", is alive "true", buff stealth "false".
Ok, for some reason the trigger is still cut off (not sure if this is WE issue or issue on this site). Based on what you wrote, the trigger may pick a same unit for AT_CL[2] and AT_CL[3]. Of course, later in the trigger, you check if AT_CL[2] != AT_CL[3]. But the issue is that from a pool of, let's say, 3 possible targets, you have a 33% chance of picking the same unit for AT_CL[2] and AT_CL[3]. So your spell is supposed to chain 2 times, you have 3 possible chain targets, yet there is a 33% chance that the spell will chain only once.

The problem with the "You should just create one unit group which consists of allies of the target unit, but not the target unit itself, and pick two random units from it." is that when done in that way the chain lightning tends to hit the same target twice every once in a while. (Not something it should be allowed to do)
That depends on how complex the spell's behavior should be.
If you want to just hit N targets without any wait, you can do this:
  • Actions
    • Set VariableSet ChainSource = (Target unit of ability being cast)
    • Set VariableSet UnitGroup = <create unit group the same way like you do right now>
    • Custom script: set bj_wantDestroyGroup = true
    • Unit Group - Pick every unit in (Random 2 units from UnitGroup) and do (Actions)
      • Loop - Actions
        • Set VariableSet ChainTarget = (Picked unit)
        • -------- create dummy at ChainSource, order to cast spell on ChainTarget --------
        • Set VariableSet ChainSource = ChainTarget
If you want the delays between each lightning, that gets things complicated, as Waits should not be used in loop actions. Picking two random units could be done outside a loop like this:
  • Actions
    • -------- picks first chain target: --------
    • Set VariableSet ChainTarget = (Random unit from UnitGroup)
    • Unit Group - Remove ChainTarget from UnitGroup.
    • -------- do stuff for first chain target --------
    • -------- ----------------------------------------- --------
    • -------- picks second chain target: --------
    • Set VariableSet ChainTarget = (Random unit from UnitGroup)
    • Unit Group - Remove ChainTarget from UnitGroup.
    • -------- do stuff for second chain target --------
 
Level 2
Joined
Jun 11, 2011
Messages
8
Well, MUI makes it easier, as you will have only one code, instead of duplicates with different variables. And if you already have some MUI spells in your map, it's better to be consistent with your approach. Of course, how you deal with it in the end is up to you.


Even when you set wait time to 0.22 seconds, the actual wait time is each time different - i.e. 0.28 the first time, 0.33 the second time, 0.30 the third time, etc.
This wait time is further off in multiplayer as there is an added latency due to synchronization of all players.
Last but not least, after Wait you may lose reference to some unit functions - i.e. "Target unit of ability being cast" may no longer point to target in your trigger. Only (Triggering unit) is immune to this, as far as I know.
So if you want to have accurate delays, you should use timers.
Also, I found some ancient post with statistics of wait delay, check the tables for single player and multiplayer: Wait Command, Good or Bad?



Ok, for some reason the trigger is still cut off (not sure if this is WE issue or issue on this site). Based on what you wrote, the trigger may pick a same unit for AT_CL[2] and AT_CL[3]. Of course, later in the trigger, you check if AT_CL[2] != AT_CL[3]. But the issue is that from a pool of, let's say, 3 possible targets, you have a 33% chance of picking the same unit for AT_CL[2] and AT_CL[3]. So your spell is supposed to chain 2 times, you have 3 possible chain targets, yet there is a 33% chance that the spell will chain only once.


That depends on how complex the spell's behavior should be.
If you want to just hit N targets without any wait, you can do this:
  • Actions
    • Set VariableSet ChainSource = (Target unit of ability being cast)
    • Set VariableSet UnitGroup = <create unit group the same way like you do right now>
    • Custom script: set bj_wantDestroyGroup = true
    • Unit Group - Pick every unit in (Random 2 units from UnitGroup) and do (Actions)
      • Loop - Actions
        • Set VariableSet ChainTarget = (Picked unit)
        • -------- create dummy at ChainSource, order to cast spell on ChainTarget --------
        • Set VariableSet ChainSource = ChainTarget
If you want the delays between each lightning, that gets things complicated, as Waits should not be used in loop actions. Picking two random units could be done outside a loop like this:
  • Actions
    • -------- picks first chain target: --------
    • Set VariableSet ChainTarget = (Random unit from UnitGroup)
    • Unit Group - Remove ChainTarget from UnitGroup.
    • -------- do stuff for first chain target --------
    • -------- ----------------------------------------- --------
    • -------- picks second chain target: --------
    • Set VariableSet ChainTarget = (Random unit from UnitGroup)
    • Unit Group - Remove ChainTarget from UnitGroup.
    • -------- do stuff for second chain target --------
Okay, @Nichilus that makes sense, thank you for taking the time to explain this. I had been wondering about the wait times for a while. I've heard things but never been shown any comprehensive evidence. As for the rest, I figured out what you spoke about in reference to the location leak so I made it as it's own variable and plugged it into the group and is now being removed on the hard reset at the end of the trigger so thanks, I guess I accidentally flaked on that. As well as the fact that in the second unitgroup I had a redundancy and once I fixed it the trigger now works as intended 100% of the time on all number of targets (1-3) consistently. Again thank you for all the help and I apologize, I should've scoured my data a couple more times, since it was such a trivial overlooked issue that was definitely my fault.
 
Status
Not open for further replies.
Top