[Spell] Custom Channel Teleport has a problem

Level 13
Joined
Sep 11, 2013
Messages
467
Greetings!:peasant-waving:

Today I started to test a Custom Channel Teleport spell that was created few months ago by the outstanding work of @Uncle and @Duckfarter in this <post> and I noticed a little problem and I wonder if someone can solve this problem because I don't know how to solve it by myself.. :peasant-confused:

As you can see in this video below, at 0:06 second, I double use very fast the same spell on the same position and the special effects remain forever stuck on me and on the target and I don't wish that..


  • Teleport Setup
    • Events
      • Time - Elapsed game time is 0.01 seconds
    • Conditions
    • Actions
      • -------- This unit is used to get us a pathable point near our teleport target while not interrupting the caster's orders! --------
      • Unit - Create 1 Teleport Dummy Wisp for Neutral Passive at (Center of (Playable map area)) facing Default building facing degrees
      • Set VariableSet TP_Pathing_Dummy = (Last created unit)
      • Unit - Make TP_Pathing_Dummy Invulnerable
      • Unit - Hide TP_Pathing_Dummy
      • Game - Display to (All players) the text: Create dummy?

  • Teleport Begin Casting
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • (Issued order) Equal to (Order(flare))
      • (Level of Teleport Instant (Ability) for (Triggering unit)) Greater than 0
    • Actions
      • Game - Display to (All players) the text: Issue teleport order
      • Set VariableSet TP_Caster = (Triggering unit)
      • Set VariableSet TP_Point[1] = (Target point of issued order)
      • -------- - --------
      • -------- This finds the closest eligible unit to the target point of ability being cast --------
      • Set VariableSet TP_Closest_Unit = No unit
      • Set VariableSet TP_Closest_Distance = 99999.00
      • Set VariableSet TP_Group = (Units in (Playable map area))
      • Unit Group - Remove TP_Caster from TP_Group.
      • -------- - --------
      • Unit Group - Pick every unit in TP_Group and do (Actions)
        • Loop - Actions
          • Set VariableSet TP_Target[0] = (Picked unit)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (TP_Target[0] is dead) Equal to False
              • (TP_Target[0] is hidden) Equal to False
              • (TP_Target[0] belongs to an ally of (Owner of TP_Caster).) Equal to True
              • (Owner of TP_Target[0]) Not equal to Neutral Passive
            • Then - Actions
              • Set VariableSet TP_Point[2] = (Position of TP_Target[0])
              • Set VariableSet TP_Current_Distance = (Distance between TP_Point[1] and TP_Point[2])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • TP_Current_Distance Less than TP_Closest_Distance
                • Then - Actions
                  • Set VariableSet TP_Closest_Distance = TP_Current_Distance
                  • Set VariableSet TP_Closest_Unit = TP_Target[0]
                • Else - Actions
              • Custom script: call RemoveLocation (udg_TP_Point[2])
            • Else - Actions
      • -------- - --------
      • -------- Remove leaks --------
      • Custom script: call RemoveLocation (udg_TP_Point[1])
      • Custom script: call DestroyGroup(udg_TP_Group)
      • -------- - --------
      • -------- Exit if no valid target was found --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TP_Closest_Unit Equal to No unit
        • Then - Actions
          • Game - Display to (All players) for 5.00 seconds the text: |cffff0000TELEPORT ...
          • -------- This will interrupt the Order and prevent the ability from ever being used: --------
          • Unit - Order TP_Caster to Stop.
          • Custom script: call BlzPauseUnitEx( udg_TP_Caster, true )
          • Custom script: call BlzPauseUnitEx( udg_TP_Caster, false )
          • Skip remaining actions
        • Else - Actions
      • -------- - --------
      • Unit Group - Add TP_Caster to TP_Caster_Group
      • Trigger - Turn on Teleport Target Dies <gen>
      • -------- - --------
      • -------- Track the staff target using Unit Indexing: --------
      • Set VariableSet UDex = (Custom value of TP_Caster)
      • Set VariableSet TP_Target[UDex] = TP_Closest_Unit
      • Set VariableSet TP_Number_Of_Teleports_On_Me[(Custom value of TP_Closest_Unit)] = (TP_Number_Of_Teleports_On_Me[(Custom value of TP_Closest_Unit)] + 1)
      • -------- - --------
      • -------- Special effects --------
      • Set VariableSet TP_Point[2] = (Position of TP_Caster)
      • Special Effect - Create a special effect at TP_Point[2] using Abilities\Spells\Human\MassTeleport\MassTeleportTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Special Effect - Create a special effect attached to the origin of TP_Caster using Abilities\Spells\Human\MassTeleport\MassTeleportTo.mdl
      • Set VariableSet TP_Effect_Caster[UDex] = (Last created special effect)
      • Special Effect - Create a special effect attached to the origin of TP_Target[UDex] using Abilities\Spells\Human\MassTeleport\MassTeleportTo.mdl
      • Set VariableSet TP_Effect_Target[UDex] = (Last created special effect)
      • Ubersplat - Create ubersplat at TP_Point[2] of type Human Mass Teleport with color (100.00%, 100.00%, 100.00%) and 0.00% transparency (Disable paused state, Disable skipping birth time)
      • Set VariableSet TP_Ubersplat[UDex] = (Last created ubersplat)
      • Ubersplat - Change TP_Ubersplat[UDex]: Enable render always state
      • Ubersplat - Show TP_Ubersplat[UDex]
      • -------- - --------
      • -------- Remove leaks --------
      • Custom script: call RemoveLocation (udg_TP_Point[2])

  • Teleport Finish Casting
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • (Ability being cast) Equal to Teleport Instant (Ability)
    • Actions
      • Game - Display to (All players) the text: Finishes casting
      • Set VariableSet TP_Caster = (Triggering unit)
      • Set VariableSet UDex = (Custom value of TP_Caster)
      • Set VariableSet TP_Point[1] = (Position of TP_Target[UDex])
      • -------- - --------
      • -------- Special effects --------
      • Special Effect - Create a special effect attached to the origin of TP_Target[UDex] using Abilities\Spells\Human\MassTeleport\MassTeleportTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Special Effect - Create a special effect attached to the origin of TP_Caster using Abilities\Spells\Human\MassTeleport\MassTeleportTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • -------- - --------
      • -------- Move caster --------
      • Unit - Unhide TP_Pathing_Dummy
      • Unit - Move TP_Pathing_Dummy instantly to TP_Point[1]
      • Unit - Hide TP_Pathing_Dummy
      • Custom script: call SetUnitX(udg_TP_Caster, GetUnitX(udg_TP_Pathing_Dummy))
      • Custom script: call SetUnitY(udg_TP_Caster, GetUnitY(udg_TP_Pathing_Dummy))
      • -------- - --------
      • -------- More special effects --------
      • Special Effect - Create a special effect attached to the origin of TP_Caster using Abilities\Spells\Human\MassTeleport\MassTeleportTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • -------- - --------
      • -------- Remove leaks --------
      • Custom script: call RemoveLocation (udg_TP_Point[1])

  • Teleport Stop Casting
    • Events
      • Unit - A unit Stops casting an ability
    • Conditions
      • (Ability being cast) Equal to Teleport Instant (Ability)
    • Actions
      • Game - Display to (All players) the text: Stops casting
      • Set VariableSet TP_Caster = (Triggering unit)
      • Set VariableSet UDex = (Custom value of TP_Caster)
      • -------- - --------
      • -------- Reset variables --------
      • Unit Group - Remove TP_Caster from TP_Caster_Group.
      • Set VariableSet TP_Number_Of_Teleports_On_Me[(Custom value of TP_Target[UDex])] = (TP_Number_Of_Teleports_On_Me[(Custom value of TP_Target[UDex])] - 1)
      • Set VariableSet TP_Target[UDex] = No unit
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Number of units in TP_Caster_Group) Equal to 0
        • Then - Actions
          • Trigger - Turn off Teleport Target Dies <gen>
        • Else - Actions
      • -------- - --------
      • -------- Remove effects --------
      • Ubersplat - Destroy TP_Ubersplat[UDex]
      • Special Effect - Destroy TP_Effect_Caster[UDex]
      • Special Effect - Destroy TP_Effect_Target[UDex]

  • Teleport Target Dies
    • Events
      • Unit - A unit Dies
    • Conditions
      • TP_Number_Of_Teleports_On_Me[(Custom value of (Triggering unit))] Greater than 0
    • Actions
      • -------- This trigger will only be ON while a unit is teleporting! --------
      • Unit Group - Pick every unit in TP_Caster_Group and do (Actions)
        • Loop - Actions
          • Set VariableSet TP_Caster = (Picked unit)
          • Set VariableSet UDex = (Custom value of TP_Caster)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Triggering unit) Equal to TP_Target[UDex]
            • Then - Actions
              • Unit - Order TP_Caster to Stop.
            • Else - Actions

I attached the map below.

The help will be appreciated!:peasant-bowing:
 

Attachments

  • Staff not Instant v.1.9 Bug.w3x
    31.2 KB · Views: 4

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
I think I fixed it. The issue was that you could queue additional Flare orders which would execute the moment you "Finished casting" Teleport. This was before "Stops casting" occurred and would break things since the clean-up step would be referencing the wrong variables at that point in time.

The fix: I added two Boolean variables which are used to ignore any queued "flare" Orders.
 

Attachments

  • Staff not Instant v.1.9 Fix 1.w3x
    33 KB · Views: 4
Last edited:
Level 13
Joined
Sep 11, 2013
Messages
467
I think I fixed it. The issue was that you could queue additional Flare orders which would execute the moment you "Finished casting" Teleport. This was before "Stops casting" occurred which would break everything since the clean-up step would be referencing the wrong variables by the time it ran.

The fix: I added two Boolean variables which are used to ignore any queued "flare" Orders.
Awesome! Work perfect! Thank you so much!

I wonder for example: If I want to make a second ability exactly like this one (channel), but with only 1 difference. The second spell(will be item) must be allowed only to cast on buildings (friends and allies)(and of course on ground to filter buildings(auto-select only buildings)). Should I duplicate all triggers and variables for the second spell?
 
Level 24
Joined
Feb 27, 2019
Messages
833
I think I fixed it. The issue was that you could queue additional Flare orders which would execute the moment you "Finished casting" Teleport. This was before "Stops casting" occurred and would break things since the clean-up step would be referencing the wrong variables at that point in time.

The fix: I added two Boolean variables which are used to ignore any queued "flare" Orders.
The queued TP order can be delayed for longer than a frame by queuing more orders (up to infinite) in-between causing the same problem. This is very strange. I cant quite wrap my head around it. I imagine it could have to do with the discrepancy of using orders to start the spell and spell events to end it or a unique behaviour for the specific spell data.

To get more accurate conditions, for unit abilities checking the cd and mana are at least two major parts of it but there could be many more parts that would have to be manually checked like if the unit is silenced. I dont know.
 
Level 13
Joined
Sep 11, 2013
Messages
467
No, you could adjust the Conditions to account for the two Ability types and have the Begins Casting trigger react differently based on which Order was issued.
Flare = Hero ability, Some other Point order = Item ability.
Well.. I've made a new channeling ability(for Item) with tornado order and i put this ability on an Item and I've changed the event, but, after that change the spell do not work at all with my new ability.. for some reason the trigger will not go to the Actions even if I let just the (Issued order) Equal to (Order(tornado)) in conditions..
  • Teleport Begin Casting
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • And - All (Conditions) are true
            • Conditions
              • (Issued order) Equal to (Order(tornado))
              • (Level of Teleport Instant ITEM for (Triggering unit)) Greater than 0
          • And - All (Conditions) are true
            • Conditions
              • (Issued order) Equal to (Order(flare))
              • (Level of Teleport Instant (Ability) for (Triggering unit)) Greater than 0
    • Actions
      • Game - Display to (All players) the text: test111
      • Set VariableSet TP_Caster = (Triggering unit)
      • Set VariableSet UDex = (Custom value of TP_Caster)
      • -------- - --------
      • -------- Prevent re-issued orders from running this trigger again: --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TP_Is_Preparing[UDex] Equal to True
        • Then - Actions
          • Skip remaining actions
        • Else - Actions
      • -------- - --------
      • Game - Display to (All players) the text: Issue teleport order
      • Set VariableSet TP_Point[1] = (Target point of issued order)
      • -------- - --------
      • -------- This finds the closest eligible unit to the target point of ability being cast --------
      • Set VariableSet TP_Closest_Unit = No unit
      • Set VariableSet TP_Closest_Distance = 99999.00
      • Set VariableSet TP_Group = (Units in (Playable map area))
      • Unit Group - Remove TP_Caster from TP_Group.
      • -------- - --------
      • Unit Group - Pick every unit in TP_Group and do (Actions)
        • Loop - Actions
          • Set VariableSet TP_Target[0] = (Picked unit)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (TP_Target[0] is dead) Equal to False
              • (TP_Target[0] is hidden) Equal to False
              • (TP_Target[0] belongs to an ally of (Owner of TP_Caster).) Equal to True
              • (Owner of TP_Target[0]) Not equal to Neutral Passive
            • Then - Actions
              • Set VariableSet TP_Point[2] = (Position of TP_Target[0])
              • Set VariableSet TP_Current_Distance = (Distance between TP_Point[1] and TP_Point[2])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • TP_Current_Distance Less than TP_Closest_Distance
                • Then - Actions
                  • Set VariableSet TP_Closest_Distance = TP_Current_Distance
                  • Set VariableSet TP_Closest_Unit = TP_Target[0]
                • Else - Actions
              • Custom script: call RemoveLocation (udg_TP_Point[2])
            • Else - Actions
      • -------- - --------
      • -------- Remove leaks --------
      • Custom script: call RemoveLocation (udg_TP_Point[1])
      • Custom script: call DestroyGroup(udg_TP_Group)
      • -------- - --------
      • -------- Exit if no valid target was found --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TP_Closest_Unit Equal to No unit
        • Then - Actions
          • Game - Display to (All players) for 5.00 seconds the text: |cffff0000TELEPORT ...
          • -------- This will interrupt the Order and prevent the ability from ever being used: --------
          • Unit - Order TP_Caster to Stop.
          • Custom script: call BlzPauseUnitEx( udg_TP_Caster, true )
          • Custom script: call BlzPauseUnitEx( udg_TP_Caster, false )
          • Skip remaining actions
        • Else - Actions
      • -------- - --------
      • -------- Prevent re-issued orders from running this trigger again: --------
      • Set VariableSet TP_Is_Preparing[UDex] = True
      • -------- - --------
      • Unit Group - Add TP_Caster to TP_Caster_Group
      • Trigger - Turn on Teleport Target Dies <gen>
      • -------- - --------
      • -------- Track the staff target using Unit Indexing: --------
      • Set VariableSet TP_Target[UDex] = TP_Closest_Unit
      • Set VariableSet TP_Number_Of_Teleports_On_Me[(Custom value of TP_Closest_Unit)] = (TP_Number_Of_Teleports_On_Me[(Custom value of TP_Closest_Unit)] + 1)
      • -------- - --------
      • -------- Special effects --------
      • Set VariableSet TP_Point[2] = (Position of TP_Caster)
      • Special Effect - Create a special effect at TP_Point[2] using Abilities\Spells\Human\MassTeleport\MassTeleportTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Special Effect - Create a special effect attached to the origin of TP_Caster using Abilities\Spells\Human\MassTeleport\MassTeleportTo.mdl
      • Set VariableSet TP_Effect_Caster[UDex] = (Last created special effect)
      • Special Effect - Create a special effect attached to the origin of TP_Target[UDex] using Abilities\Spells\Human\MassTeleport\MassTeleportTo.mdl
      • Set VariableSet TP_Effect_Target[UDex] = (Last created special effect)
      • Ubersplat - Create ubersplat at TP_Point[2] of type Human Mass Teleport with color (100.00%, 100.00%, 100.00%) and 0.00% transparency (Disable paused state, Disable skipping birth time)
      • Set VariableSet TP_Ubersplat[UDex] = (Last created ubersplat)
      • Ubersplat - Change TP_Ubersplat[UDex]: Enable render always state
      • Ubersplat - Show TP_Ubersplat[UDex]
      • -------- - --------
      • -------- Remove leaks --------
      • Custom script: call RemoveLocation (udg_TP_Point[2])

The queued TP order can be delayed for longer than a frame by queuing more orders (up to infinite) in-between causing the same problem. This is very strange. I cant quite wrap my head around it. I imagine it could have to do with the discrepancy of using orders to start the spell and spell events to end it or a unique behaviour for the specific spell data.

To get more accurate conditions, for unit abilities checking the cd and mana are at least two major parts of it but there could be many more parts that would have to be manually checked like if the unit is silenced. I dont know.
Wow.. yeah..I totally forgotten about interactions with other spells.. I tested the spell with a friend and I found just a bug for the moment.:peasant-sad:

Here is what tested.. 2 type of (Polymorph/Hex) - 1 Storm bolt - 1 silence aoe - 1 silence targeted unit.

As you(@Uncle, @Duckfarter) can see in the video below, the Polymorph/hex is the only one spell that I found that create this bug. Storm bolt, silence aoe and silence targeted unit will interrupt the spell without bugs from what i saw.

How can I solve this problem?:peasant-work-work:

Thank you!


Edit: I think I can fix polymorph bug with this trigger
  • Untitled Trigger 002
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Polymorph
    • Actions
      • Unit - Order (Target unit of ability being cast) to Stop.
Edit 2: The same problem(bug) as in the video appear with War stomp, Ensnare and Stasis Trap and I don't know how to fix that..

I can't use the same fix with Ensnare like i did with Polymorph because there is a projectile in the air and must stun the target only when it hits the target, not instantly like polymorph..
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Pretty strange. Warcraft is so damn broken, I'm pretty close to uninstalling this game for good. :peasant-thumbs-down-angry:

Anyway, I suppose a fix would be to use something like Dynamic Indexing instead of Unit Indexing and manually check the state of the caster rather than relying on Events like "Stops casting".

Edit: Try this version, I have a trigger that periodically checks the state of the casters and ends the spell if need be:
  • Teleport Caster State
    • Events
      • Time - Every 0.01 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in TP_Caster_Group and do (Actions)
        • Loop - Actions
          • Set VariableSet TP_Caster = (Picked unit)
          • Set VariableSet UDex = (Custom value of TP_Caster)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (TP_Target[UDex] is alive) Equal to False
                  • (TP_Caster is Stunned) Equal to True
                  • (TP_Caster is Snared) Equal to True
                  • (TP_Caster is Polymorphed) Equal to True
                  • (TP_Caster is Sleeping) Equal to True
            • Then - Actions
              • Trigger - Run Teleport Cleanup <gen> (checking conditions)
              • Unit - Order TP_Caster to Stop.
            • Else - Actions
I also tweaked the triggers to use the "Begins casting" Event, maybe that was the source of the problems.
 

Attachments

  • Staff not Instant v.1.9 Fix 3.w3x
    34.3 KB · Views: 3
Last edited:
Level 13
Joined
Sep 11, 2013
Messages
467
Warcraft is so damn broken, I'm pretty close to uninstalling this game for good.
It is broken, but you're not! :peasant-thumbs-up-cheers:You have solved over 99% of the problems even with this broken warcraft! Work-arounds are a way to make us think better and this broken warcraft force us to use a lot of work-arounds and this is interesting. Our brains evolve faster like this i think.

(I know I don't know what exactly is the real problem here.. but..)

I think I speak for everyone when I say we don't want you to leave this place. You're a gem, Uncle! You can do wonderful stuff here with this community, even with this broken game. :peasant-cheers-back:

Of course you're not trapped here, but at least keep this hobby alive from time to time because you did an outstanding job all those years and so many people love your work.:peasant-thumbs-up-cheers:

I wish that you'll start a new project maybe on youtube or maybe something else. I'm very curious about what you will create there:peasant-thinking:

That being said, I'm going back to my cave trying to find solutions to my problems. :peasant-work-work:

Edit: I just posted this massage and I noticed that you already sent me a map. I am going to test that map right now.:grin:
 
Level 13
Joined
Sep 11, 2013
Messages
467
Pretty strange. Warcraft is so damn broken, I'm pretty close to uninstalling this game for good. :peasant-thumbs-down-angry:

Anyway, I suppose a fix would be to use something like Dynamic Indexing instead of Unit Indexing and manually check the state of the caster rather than relying on Events like "Stops casting".

Edit: Try this version, I have a trigger that periodically checks the state of the casters and ends the spell if need be:
  • Teleport Caster State
    • Events
      • Time - Every 0.01 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in TP_Caster_Group and do (Actions)
        • Loop - Actions
          • Set VariableSet TP_Caster = (Picked unit)
          • Set VariableSet UDex = (Custom value of TP_Caster)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (TP_Target[UDex] is alive) Equal to False
                  • (TP_Caster is Stunned) Equal to True
                  • (TP_Caster is Snared) Equal to True
                  • (TP_Caster is Polymorphed) Equal to True
                  • (TP_Caster is Sleeping) Equal to True
            • Then - Actions
              • Trigger - Run Teleport Cleanup <gen> (checking conditions)
              • Unit - Order TP_Caster to Stop.
            • Else - Actions
I also tweaked the triggers to use the "Begins casting" Event, maybe that was the source of the problems.
Awesome solution as always! :peasant-thumbs-up-cheers:

I tested right now just what was bugged before (War stomp, Ensnare and Stasis Trap) and now, the channel teleport just stopped naturally and work perfect!

I'll test latter all abilities again like (Sleep/Cluster Rockets/Impale(custom)/Storm Bolt/2 type of (Polymorph/Hex)/1 silence aoe/1 silence targeted unit/ETC.) Right now I have to go outside a little bit.. Thank you so much once and once again!:peasant-cheers::peasant-victory:

Edit: I saw that you put this condition for the second Item ability. I'll try to understand how to create the second abilty teleport item that allow only teleport on buildings a little bit latter with that trigger.

  • Or - Any (Conditions) are true
    • Conditions
      • And - All (Conditions) are true
        • Conditions
          • (Issued order) Equal to (Order(tornado))
          • (Level of Teleport Instant (Ability) for (Triggering unit)) Greater than 0
 
Last edited:
Level 13
Joined
Sep 11, 2013
Messages
467
Edit: Try this version, I have a trigger that periodically checks the state of the casters and ends the spell if need be:
  • Teleport Caster State
    • Events
      • Time - Every 0.01 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in TP_Caster_Group and do (Actions)
        • Loop - Actions
          • Set VariableSet TP_Caster = (Picked unit)
          • Set VariableSet UDex = (Custom value of TP_Caster)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (TP_Target[UDex] is alive) Equal to False
                  • (TP_Caster is Stunned) Equal to True
                  • (TP_Caster is Snared) Equal to True
                  • (TP_Caster is Polymorphed) Equal to True
                  • (TP_Caster is Sleeping) Equal to True
            • Then - Actions
              • Trigger - Run Teleport Cleanup <gen> (checking conditions)
              • Unit - Order TP_Caster to Stop.
            • Else - Actions
I also tweaked the triggers to use the "Begins casting" Event, maybe that was the source of the problems.

Well, good news! I tested few abilities and all works great with your new solve!
  • Untitled Trigger 001
    • Events
      • Player - Player 1 (Red) types a chat message containing 1 as An exact match
    • Conditions
    • Actions
      • Unit - Order Tauren Chieftain 0026 <gen> to Orc Tauren Chieftain - War Stomp.
      • Unit - Order Witch Doctor 0028 <gen> to Orc Witch Doctor - Stasis Trap (Center of Region 000 <gen>)
      • Unit - Order Raider 0027 <gen> to Orc Raider - Ensnare Paladin 0025 <gen>
      • Unit - Order Dreadlord 0005 <gen> to Undead Dreadlord - Sleep Paladin 0025 <gen>
      • Unit - Order Crypt Lord 0011 <gen> to Undead Crypt Lord - Impale Paladin 0025 <gen>
      • Unit - Order Tinker 0012 <gen> to Neutral Tinker - Cluster Rockets (Center of Region 000 <gen>)
      • Unit - Order Mountain King 0032 <gen> to Human Mountain King - Storm Bolt Paladin 0025 <gen>
      • Unit - Order Shadow Hunter 0034 <gen> to Orc Shadow Hunter - Hex Paladin 0025 <gen>
      • Unit - Order Keeper of the Grove 0045 <gen> to Night Elf Keeper Of The Grove - Entangling Roots Paladin 0025 <gen>
      • Unit - Order Sorceress 0033 <gen> to Human Sorceress - Polymorph Paladin 0025 <gen>

I noticed that you already create a set up for the second teleport (Item) ability so I tried to follow the steps, but I didn't manage to solve the problem..

What I did..
1.I've made a new channeling ability(for Item) with tornado order and i put this ability on an Item(Scroll of Town Portal - Perishable) and I've changed the condition in (Teleport Issue Order) and in others triggers, but now, the trigger stuck the unit forever when I use it (Item or spell).. I don't know how to fix that..

These are the triggers I changed (Only the Condition before Actions)


  • Teleport Issue Order
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • And - All (Conditions) are true
            • Conditions
              • (Issued order) Equal to (Order(flare))
              • (Level of Teleport Instant (Ability) for (Triggering unit)) Greater than 0
      • Or - Any (Conditions) are true
        • Conditions
          • And - All (Conditions) are true
            • Conditions
              • (Issued order) Equal to (Order(tornado))
              • (Level of Teleport Instant ITEM for (Triggering unit)) Greater than 0
    • Actions
      • Game - Display to (All players) the text: Issues order
      • Set VariableSet TP_Caster = (Triggering unit)
      • Set VariableSet UDex = (Custom value of TP_Caster)
      • -------- - --------
      • Set VariableSet TP_Point[1] = (Target point of issued order)
      • -------- - --------
      • -------- This finds the closest eligible unit to the target point of ability being cast --------
      • Set VariableSet TP_Closest_Unit = No unit
      • Set VariableSet TP_Closest_Distance = 99999.00
      • Set VariableSet TP_Group = (Units in (Playable map area))
      • Unit Group - Remove TP_Caster from TP_Group.
      • -------- - --------
      • -------- ========================================================= --------
      • -------- Flare targeting: --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Issued order) Equal to (Order(flare))
        • Then - Actions
          • Unit Group - Pick every unit in TP_Group and do (Actions)
            • Loop - Actions
              • Set VariableSet TP_Target[0] = (Picked unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (TP_Target[0] belongs to an ally of (Owner of TP_Caster).) Equal to True
                  • (TP_Target[0] is dead) Equal to False
                  • (TP_Target[0] is hidden) Equal to False
                  • (Owner of TP_Target[0]) Not equal to Neutral Passive
                • Then - Actions
                  • Set VariableSet TP_Point[2] = (Position of TP_Target[0])
                  • Set VariableSet TP_Current_Distance = (Distance between TP_Point[1] and TP_Point[2])
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • TP_Current_Distance Less than TP_Closest_Distance
                    • Then - Actions
                      • Set VariableSet TP_Closest_Distance = TP_Current_Distance
                      • Set VariableSet TP_Closest_Unit = TP_Target[0]
                    • Else - Actions
                  • Custom script: call RemoveLocation (udg_TP_Point[2])
                • Else - Actions
        • Else - Actions
      • -------- - --------
      • -------- Tornado targeting: --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Issued order) Equal to (Order(tornado))
        • Then - Actions
          • Unit Group - Pick every unit in TP_Group and do (Actions)
            • Loop - Actions
              • Set VariableSet TP_Target[0] = (Picked unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (TP_Target[0] is A structure) Equal to True
                  • (TP_Target[0] belongs to an ally of (Owner of TP_Caster).) Equal to True
                • Then - Actions
                  • Set VariableSet TP_Point[2] = (Position of TP_Target[0])
                  • Set VariableSet TP_Current_Distance = (Distance between TP_Point[1] and TP_Point[2])
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • TP_Current_Distance Less than TP_Closest_Distance
                    • Then - Actions
                      • Set VariableSet TP_Closest_Distance = TP_Current_Distance
                      • Set VariableSet TP_Closest_Unit = TP_Target[0]
                    • Else - Actions
                  • Custom script: call RemoveLocation (udg_TP_Point[2])
                • Else - Actions
        • Else - Actions
      • -------- ========================================================= --------
      • -------- - --------
      • -------- Remove leaks --------
      • Custom script: call RemoveLocation (udg_TP_Point[1])
      • Custom script: call DestroyGroup(udg_TP_Group)
      • -------- - --------
      • -------- Exit if no valid target was found --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • TP_Closest_Unit Equal to No unit
        • Then - Actions
          • Game - Display to (All players) for 5.00 seconds the text: |cffff0000TELEPORT ...
          • -------- This will interrupt the Order and prevent the ability from ever being used: --------
          • Set VariableSet TP_Target[UDex] = No unit
          • Unit - Order TP_Caster to Stop.
          • Custom script: call BlzPauseUnitEx( udg_TP_Caster, true )
          • Custom script: call BlzPauseUnitEx( udg_TP_Caster, false )
          • Skip remaining actions
        • Else - Actions
      • -------- - --------
      • -------- Prevent re-issued orders from running this trigger again: --------
      • Set VariableSet TP_Target[UDex] = TP_Closest_Unit
  • Teleport Begin Casting
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to Teleport Instant (Ability)
          • (Ability being cast) Equal to Teleport Instant ITEM
    • Actions
      • Game - Display to (All players) the text: Begins casting
      • Set VariableSet TP_Caster = (Triggering unit)
      • Set VariableSet UDex = (Custom value of TP_Caster)
      • Set VariableSet TP_Closest_Unit = TP_Target[UDex]
      • -------- - --------
      • -------- Track the caster --------
      • Unit Group - Add TP_Caster to TP_Caster_Group
      • Trigger - Turn on Teleport Target Dies <gen>
      • Trigger - Turn on Teleport Caster State <gen>
      • -------- - --------
      • -------- Track the staff target using Unit Indexing: --------
      • Set VariableSet TP_Number_Of_Teleports_On_Me[(Custom value of TP_Closest_Unit)] = (TP_Number_Of_Teleports_On_Me[(Custom value of TP_Closest_Unit)] + 1)
      • -------- - --------
      • -------- Special effects --------
      • Set VariableSet TP_Point[2] = (Position of TP_Caster)
      • Special Effect - Create a special effect at TP_Point[2] using Abilities\Spells\Human\MassTeleport\MassTeleportTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • -------- - --------
      • Special Effect - Create a special effect attached to the origin of TP_Caster using Abilities\Spells\Human\MassTeleport\MassTeleportTo.mdl
      • Set VariableSet TP_Effect_Caster[UDex] = (Last created special effect)
      • -------- - --------
      • Special Effect - Create a special effect attached to the origin of TP_Target[UDex] using Abilities\Spells\Human\MassTeleport\MassTeleportTo.mdl
      • Set VariableSet TP_Effect_Target[UDex] = (Last created special effect)
      • -------- - --------
      • Ubersplat - Create ubersplat at TP_Point[2] of type Human Mass Teleport with color (100.00%, 100.00%, 100.00%) and 0.00% transparency (Disable paused state, Disable skipping birth time)
      • Set VariableSet TP_Ubersplat[UDex] = (Last created ubersplat)
      • Ubersplat - Change TP_Ubersplat[UDex]: Enable render always state
      • Ubersplat - Show TP_Ubersplat[UDex]
      • -------- - --------
      • -------- Remove leaks --------
      • Custom script: call RemoveLocation (udg_TP_Point[2])
  • Teleport Finish Casting
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to Teleport Instant (Ability)
          • (Ability being cast) Equal to Teleport Instant ITEM
    • Actions
      • Game - Display to (All players) the text: Finishes casting
      • Set VariableSet TP_Caster = (Triggering unit)
      • Set VariableSet UDex = (Custom value of TP_Caster)
      • Set VariableSet TP_Point[1] = (Position of TP_Target[UDex])
      • -------- - --------
      • -------- Special effects --------
      • Special Effect - Create a special effect attached to the origin of TP_Target[UDex] using Abilities\Spells\Human\MassTeleport\MassTeleportTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Special Effect - Create a special effect attached to the origin of TP_Caster using Abilities\Spells\Human\MassTeleport\MassTeleportTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • -------- - --------
      • -------- Move caster --------
      • Unit - Unhide TP_Pathing_Dummy
      • Unit - Move TP_Pathing_Dummy instantly to TP_Point[1]
      • Unit - Hide TP_Pathing_Dummy
      • Custom script: call SetUnitX(udg_TP_Caster, GetUnitX(udg_TP_Pathing_Dummy))
      • Custom script: call SetUnitY(udg_TP_Caster, GetUnitY(udg_TP_Pathing_Dummy))
      • -------- - --------
      • -------- More special effects --------
      • Special Effect - Create a special effect attached to the origin of TP_Caster using Abilities\Spells\Human\MassTeleport\MassTeleportTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • -------- - --------
      • -------- Remove leaks --------
      • Custom script: call RemoveLocation (udg_TP_Point[1])
  • Teleport Stop Casting
    • Events
      • Unit - A unit Stops casting an ability
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to Teleport Instant (Ability)
          • (Ability being cast) Equal to Teleport Instant ITEM
    • Actions
      • Game - Display to (All players) the text: Stops casting
      • Set VariableSet TP_Caster = (Triggering unit)
      • Set VariableSet UDex = (Custom value of TP_Caster)
      • Trigger - Run Teleport Cleanup <gen> (checking conditions)

I have attached the map I am working on now below.
What I did wrong?
 

Attachments

  • Staff not Instant v.1.9 Fix 3 and ITEM.w3x
    35.4 KB · Views: 2
Level 13
Joined
Sep 11, 2013
Messages
467
For the moment, I just want 1 Item (Scroll of Town Portal - Perishable/with 1 or 2 charges) that allow me to teleport only on buildings(friend and allies), but not on neutrals(passive). ideally, the item can be also casted on the ground just like the spell.

Bonus.. In the late future I think I wish to create another teleport item almost the same (Scroll of Town Portal, but permanent). I think we don't need extra triggers for that.

Sometimes, in my map, it is possible for a unit to have the spell and the item. I hope that will not create bugs.

Fun fact: This entire trigger that you created is very good for (divine shield) tricks.
With your trigger I can activate divine shield before or in the middle of teleport and the teleport and divine shield will not cancel and i love that.
In the normal default teleport, you can't do this trick.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Alright, since Items don't issue Orders I had to make an exception and have it find the closest target when you "Begin casting".

The only issue there is that I can't prevent the Item ability from being used when there's no valid targets. Instead, I have to refund the mana cost and cancel the cast with a Stop order. This seems fine and depending on how your map works it may never come up.

Also, this new String variable is used to define and distinguish between which ability is being used:
  • Set VariableSet TP_Base_Order_Id = flare
You'd either set it to "flare" or "tornado" depending on what was used.
 

Attachments

  • Staff not Instant v.1.9 Fix 4.w3x
    37.3 KB · Views: 3
Last edited:
Level 13
Joined
Sep 11, 2013
Messages
467
Alright, since Items don't issue Orders I had to make an exception and have it find the closest target when you "Begin casting".

The only issue there is that I can't prevent the Item ability from being used when there's no valid targets. Instead, I have to refund the mana cost and cancel the cast with a Stop order. This seems fine and depending on how your map works it may never come up.

Also, this new String variable is used to define and distinguish between which ability is being used:
  • Set VariableSet TP_Base_Order_Id = flare
You'd either set it to "flare" or "tornado" depending on what was used.
Excellent! Work very smooth! I think I managed to create the second item (Scroll of Town Portal, but permanent) with your help! :peasant-victory:

Here is what I did and seems to work.:peasant-smile:
  • Teleport Begin Casting
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to Teleport Instant (Ability)
          • (Ability being cast) Equal to Teleport Instant (Item)
          • (Ability being cast) Equal to Teleport Instant 2 (Item)
    • Actions
      • Game - Display to (All players) the text: Begins casting
      • Set VariableSet TP_Caster = (Triggering unit)
      • Set VariableSet UDex = (Custom value of TP_Caster)
      • -------- - --------
      • -------- Items don't issue orders so if that's the case then let's get the closest target here: --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Ability being cast) Equal to Teleport Instant (Item)
        • Then - Actions
          • Set VariableSet TP_Base_Order_Id = tornado
          • Set VariableSet TP_Point[1] = (Target point of ability being cast)
          • Trigger - Run Teleport Find Closest Target <gen> (ignoring conditions)
          • -------- - --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • TP_Closest_Unit Equal to No unit
            • Then - Actions
              • -------- More special exceptions for the item --------
              • Trigger - Turn off Teleport Stop Casting <gen>
              • Trigger - Run Teleport Refund Item Mana <gen> (ignoring conditions)
              • Unit - Order TP_Caster to Stop.
              • Trigger - Turn on Teleport Stop Casting <gen>
              • -------- - --------
              • Skip remaining actions
            • Else - Actions
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Ability being cast) Equal to Teleport Instant 2 (Item)
        • Then - Actions
          • Set VariableSet TP_Base_Order_Id = tornado
          • Set VariableSet TP_Point[1] = (Target point of ability being cast)
          • Trigger - Run Teleport Find Closest Target <gen> (ignoring conditions)
          • -------- - --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • TP_Closest_Unit Equal to No unit
            • Then - Actions
              • -------- More special exceptions for the item --------
              • Trigger - Turn off Teleport Stop Casting <gen>
              • Trigger - Run Teleport Refund Item Mana <gen> (ignoring conditions)
              • Unit - Order TP_Caster to Stop.
              • Trigger - Turn on Teleport Stop Casting <gen>
              • -------- - --------
              • Skip remaining actions
            • Else - Actions
        • Else - Actions
      • -------- - --------
      • Set VariableSet TP_Closest_Unit = TP_Target[UDex]
      • Game - Display to (All players) the text: (Name of TP_Closest_Unit)
      • -------- - --------
      • -------- Track the caster --------
      • Unit Group - Add TP_Caster to TP_Caster_Group
      • Trigger - Turn on Teleport Target Dies <gen>
      • Trigger - Turn on Teleport Caster State <gen>
      • -------- - --------
      • -------- Track the staff target using Unit Indexing: --------
      • Set VariableSet TP_Number_Of_Teleports_On_Me[(Custom value of TP_Closest_Unit)] = (TP_Number_Of_Teleports_On_Me[(Custom value of TP_Closest_Unit)] + 1)
      • -------- - --------
      • -------- Special effects --------
      • Set VariableSet TP_Point[2] = (Position of TP_Caster)
      • Special Effect - Create a special effect at TP_Point[2] using Abilities\Spells\Human\MassTeleport\MassTeleportTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • -------- - --------
      • Special Effect - Create a special effect attached to the origin of TP_Caster using Abilities\Spells\Human\MassTeleport\MassTeleportTo.mdl
      • Set VariableSet TP_Effect_Caster[UDex] = (Last created special effect)
      • -------- - --------
      • Special Effect - Create a special effect attached to the origin of TP_Target[UDex] using Abilities\Spells\Human\MassTeleport\MassTeleportTo.mdl
      • Set VariableSet TP_Effect_Target[UDex] = (Last created special effect)
      • -------- - --------
      • Ubersplat - Create ubersplat at TP_Point[2] of type Human Mass Teleport with color (100.00%, 100.00%, 100.00%) and 0.00% transparency (Disable paused state, Disable skipping birth time)
      • Set VariableSet TP_Ubersplat[UDex] = (Last created ubersplat)
      • Ubersplat - Change TP_Ubersplat[UDex]: Enable render always state
      • Ubersplat - Show TP_Ubersplat[UDex]
      • -------- - --------
      • -------- Remove leaks --------
      • Custom script: call RemoveLocation (udg_TP_Point[2])

  • Teleport Finish Casting
    • Events
      • Unit - A unit Finishes casting an ability
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to Teleport Instant (Ability)
          • (Ability being cast) Equal to Teleport Instant (Item)
          • (Ability being cast) Equal to Teleport Instant 2 (Item)
    • Actions
      • Game - Display to (All players) the text: Finishes casting
      • Set VariableSet TP_Caster = (Triggering unit)
      • Set VariableSet UDex = (Custom value of TP_Caster)
      • Set VariableSet TP_Point[1] = (Position of TP_Target[UDex])
      • -------- - --------
      • -------- Special effects --------
      • Special Effect - Create a special effect attached to the origin of TP_Target[UDex] using Abilities\Spells\Human\MassTeleport\MassTeleportTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • Special Effect - Create a special effect attached to the origin of TP_Caster using Abilities\Spells\Human\MassTeleport\MassTeleportTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • -------- - --------
      • -------- Move caster --------
      • Unit - Unhide TP_Pathing_Dummy
      • Unit - Move TP_Pathing_Dummy instantly to TP_Point[1]
      • Unit - Hide TP_Pathing_Dummy
      • Custom script: call SetUnitX(udg_TP_Caster, GetUnitX(udg_TP_Pathing_Dummy))
      • Custom script: call SetUnitY(udg_TP_Caster, GetUnitY(udg_TP_Pathing_Dummy))
      • -------- - --------
      • -------- More special effects --------
      • Special Effect - Create a special effect attached to the origin of TP_Caster using Abilities\Spells\Human\MassTeleport\MassTeleportTarget.mdl
      • Special Effect - Destroy (Last created special effect)
      • -------- - --------
      • -------- Remove leaks --------
      • Custom script: call RemoveLocation (udg_TP_Point[1])

  • Teleport Stop Casting
    • Events
      • Unit - A unit Stops casting an ability
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Ability being cast) Equal to Teleport Instant (Ability)
          • (Ability being cast) Equal to Teleport Instant (Item)
          • (Ability being cast) Equal to Teleport Instant 2 (Item)
    • Actions
      • Game - Display to (All players) the text: Stops casting
      • Set VariableSet TP_Caster = (Triggering unit)
      • Set VariableSet UDex = (Custom value of TP_Caster)
      • Trigger - Run Teleport Cleanup <gen> (checking conditions)

Also, this new String variable is used to define and distinguish between which ability is being used:
  • set.gif
    Set VariableSet TP_Base_Order_Id = flare
You'd either set it to "flare" or "tornado" depending on what was used.
So, I have to use flare if i'll create a new spell and tornado if i'll create a new item? I don't know if i understand correctly but seems to work like this.:peasant-thinking:


I don't have enough thanks for you, but thank you very much, Uncle!!!
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Flare is being used for the Non-Item ability. It has the special Order cancellation stuff. It can only target Allied units.

Tornado is being used for the Item ability and doesn't use the Order trigger. It can only target Allied buildings.

You can see that the Find Closest Target trigger references this String to determine the Targets Allowed. Just follow the pattern.
 
Level 13
Joined
Sep 11, 2013
Messages
467
Flare is being used for the Non-Item ability. It has the special Order cancellation stuff along with it's own targeting rules (any Allied unit).

Tornado is being used for the Item ability and doesn't use the Order trigger. It can only target Allied buildings.

For example, the Find Closest Target trigger references the new String to determine the targeting.
Right. Now I understand better:peasant-thumbs-up-cheers:
 
Top