• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[Trigger] Different dummies can't cast different spells at the same point!

Status
Not open for further replies.
Level 5
Joined
May 20, 2008
Messages
138
Hello!

I'm having a small annoying problem with a spell I'm triggering. The spell is called consecration and is an Instant (no target) spell that creates a burning field under the casting unit dealing damage over time to enemy units in it.

For this purpose I use a dummy casting Flame Strike for the damage over time and burning ground visual and another dummy casting a non-damaging Death and Decay using the same visual effect to get denser flames.

However the problem I am having is that there is some kind of bug that apparently prevents two different units being created and casting two different spells at the same point location at the same time.

Any help resolving this/explanations why it doesn't work would be much appreciated!

Here's my trigger:

  • Paladin Consecration
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to (Paladin) Consecration
    • Actions
      • Game - Display to (All players) the text: consecration
      • Set GEN_TEMP_POINT[1] = (Position of (Casting unit))
      • Set GEN_TEMP_POINT[2] = (Position of (Casting unit))
      • -------- Create Flame strike damage and effect --------
      • -------- Create Flame strike damage and effect --------
      • -------- Create Flame strike damage and effect --------
      • Unit - Create 1 Dummy Caster for (Owner of (Casting unit)) at GEN_TEMP_POINT[1] facing Default building facing degrees
      • Unit - Hide (Last created unit)
      • Unit - Add a 5.00 second Generic expiration timer to (Last created unit)
      • Unit - Add (Paladin) Consecration dummy to (Last created unit)
      • Unit - Order (Last created unit) to Human Blood Mage - Flame Strike GEN_TEMP_POINT[1] ---------////////////////////// When disabling this action the next dummy caster is created and successfully casts Death and decay. When this action is NOT disabled, the second dummy caster isn't created at all, however the first one successfully casts Flame Strike.
      • Custom script: call RemoveLocation(udg_GEN_TEMP_POINT[1])
      • -------- Create Death and Decay extra effect --------
      • -------- Create Death and Decay extra effect --------
      • -------- Create Death and Decay extra effect --------
      • Unit - Create 1 Dummy Caster for (Owner of (Casting unit)) at GEN_TEMP_POINT[2] facing Default building facing degrees
      • Unit - Hide (Last created unit) ---------/////////////////// I've disabled this when debugging so that I can see if the second dummy caster is created. Which it is, as long as the first dummy unit doesn't cast Flame Strike.
      • Unit - Add a 9.00 second Generic expiration timer to (Last created unit)
      • Unit - Add (Paladin) Consecration visual effect to (Last created unit)
      • Unit - Order (Last created unit) to Undead Lich - Death And Decay GEN_TEMP_POINT[2]
      • Custom script: call RemoveLocation(udg_GEN_TEMP_POINT[2])
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
1- Why are you using 2 GEN_TEMP_POINT with the same value? You can use 1 for both.
2- You don't need to hide the unit. Just remove the unit model (On Import Model type ".mdl"), and add Locust and Invulnerable to it.
3- Add the ability to the unit in the object editor and work with order strings. You can add 23980134 skills to the same Dummy, as long as the order string of the skills are different one from each other.
4- You could reduce the casting time of the spell, and also the expiration timer of the unit. I've even added 'Remove unit' right after the 'Order unit to cast', and it cast the spell anyway (if casting time is 0.00)
5- Be REALLY SURE that the 'Text Order String' of your Spell is the same than the skill order you're giving to the unit. (When you order a unit to cast a skill, that skill has a Text Order String ID, in this case it's "flamestrike". If you create a skill that is not part of the Skill List available in the Action setting, just change the Skill Text Order String ID in the Object Editor to the one the Skill Available in the Action Setting has).

6- Check if the Flamestrike casted by the first dummy isn't killing the second dummy.
7- Check the cast range and skill properties in the Object Editor of both skills... maybe 'Casting Range' or 'Mana Cost', or Tech Requirements, or Dependencies.

8- I don't think warcraft has a limit for things in points :) You can cast and do as many effects, units, actions using a point as you want.
 
Level 5
Joined
May 20, 2008
Messages
138
Thank you for such fast replies guys! :D

There's no need to use an array for the point, and no need to set it twice. use only one variable.

Try owner of triggering unit when you create the dummies.
1- Why are you using 2 GEN_TEMP_POINT with the same value? You can use 1 for both.
I tried creating two different points on the same spot for debugging reasons, since I had the same problem when I used a single point for creation of both the dummies and ordering both the casts. However, the problem persisted, which is why I posted here.

I'll try using "owner of triggering unit".

2- You don't need to hide the unit. Just remove the unit model (On Import Model type ".mdl"), and add Locust and Invulnerable to it.
Yep, it already has locust and invulnerable, and I will change the dummy to have no model when I've finished all my spells and everything is working. I need to see if the dummy even gets created when trying to figure out what's wrong (and that was helpful here, since I've been able to verify that the FIRST dummy gets created when the action to make it cast Flame Strike is ENABLED but the SECOND dummy doesn't, and that the SECOND dummy gets created and casts Death and Decay when the action to make the FIRST dummy cast Flame Strike is DISABLED).

3- Add the ability to the unit in the object editor and work with order strings. You can add 23980134 skills to the same Dummy, as long as the order string of the skills are different one from each other.
Yeah I could try that... but how do you think it will fix my problem? I currently have one universal dummy caster that handles a lot of different dummy spells, and I have a lot of dummy spells based on the same base-spell, for example Acid Bomb is used in many of the dummy missile effects I have.

4- You could reduce the casting time of the spell, and also the expiration timer of the unit. I've even added 'Remove unit' right after the 'Order unit to cast', and it cast the spell anyway (if casting time is 0.00)
The casting time of both the dummy Flame Strike and the dummy Death And Decay are 0 already, and so is the casting and backswing point of the dummy's animation as well. I could try adding a "Remove Unit" action after ordering the first dummy caster, but the second dummy caster needs his long expiration timer since Death and Decay is a channeled ability.

EDIT: I tried removing the unit right after casting the spell but for some reason it caused some bugs with some other triggers that increase damage dealt by the player and display the damage dealt as floating text, so it's not an option. Why does Warcraft do all these irrational, bugged things? :(

5- Be REALLY SURE that the 'Text Order String' of your Spell is the same than the skill order you're giving to the unit. (When you order a unit to cast a skill, that skill has a Text Order String ID, in this case it's "flamestrike". If you create a skill that is not part of the Skill List available in the Action setting, just change the Skill Text Order String ID in the Object Editor to the one the Skill Available in the Action Setting has).
I'll have to look into this!

6- Check if the Flamestrike casted by the first dummy isn't killing the second dummy.
It doesn't, the Flame Strike damages enemies only. The dummy also has 220 HP and the Flame Strike deals 25 initial damage and 25 damage per second. The second dummy caster doesn't even get created if the first one casts Flame Strike.

7- Check the cast range and skill properties in the Object Editor of both skills... maybe 'Casting Range' or 'Mana Cost', or Tech Requirements, or Dependencies.
Done it and there were no problems there! ;D Both skills work separately (cast by dummies), it's just when both are supposed to cast that this wierd stuff is happening.

Thanks again guys! I hope this strange mystery will unravel eventually...
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Well, it works creating one universal dummy and add the skill to that dummy every time it's created, but requires more work (from the system).

- Give dummys 9999 hp and mana :p won't hurt them ;)
- Declaring 'Owner of (Triggering Unit)' as TempPlayer would help efficiency.
- I just told you it worked for me... as an example, not suggestion :D

-----------------------------------------------------------------

- As a Major Suggestion. You could create another trigger that creates the 2nd dummy based on the cast of the first dummy, instead of creating both in the same trigger.

1) Hero cast Spell -> First dummy is Created
2) First Dummy Cast Spell -> 2nd dummy is created.

but how do you think it will fix my problem?

Casting a Spell is basically giving a unit the order of doing that. If you use 'attack' order string for a spell, your unit would cast the skill instead of attacking, or crash trying to do both. Instead of giving the unit a fixed order like 'Human - Flame Strike' you can

Unit - Give unit an order targeting a point
- Issued order is Equal to (Order(flamestrike))


That way you have a lot of control over what the dummy does, and it's basically the same for the system (as far as I know). You can have 10 Acid Bomb skills on the same dummy, and they all can be cast independently by changing the Text Order ID. (Though i'm not sure about the Spell Base ID that can be changed using Channel ability, those shouldn't be the same between skills either)

btw, I don' really know what's the text order string of the skill :p you can check that in the object editor.

Hope this is helpfull. In the worst case, post the map with the skill so we can give a look at it.
 
Level 5
Joined
May 20, 2008
Messages
138
Thank you for your reply! The order string thing seems very interesting I might start using it ;D

- As a Major Suggestion. You could create another trigger that creates the 2nd dummy based on the cast of the first dummy, instead of creating both in the same trigger.

I ended up doing something like this. I managed to work around the problem by creating two different triggers. I don't like having too many triggers but it seems like the best solution currently right? I'm still quite baffled why the initial trigger didn't work though :p

  • Paladin Consecration
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to (Paladin) Consecration
    • Actions
      • Set GEN_TEMP_POINT[1] = (Position of (Triggering unit))
      • -------- Create Flame strike damage and effect --------
      • Unit - Create 1 Dummy Caster for (Owner of (Triggering unit)) at GEN_TEMP_POINT[1] facing Default building facing degrees
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Add (Paladin) Consecration dummy to (Last created unit)
      • Unit - Order (Last created unit) to Human Blood Mage - Flame Strike GEN_TEMP_POINT[1]
      • Custom script: call RemoveLocation(udg_GEN_TEMP_POINT[1])
  • Paladin Consecration effect
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to (Paladin) Consecration
    • Actions
      • Set GEN_TEMP_POINT[1] = (Position of (Triggering unit))
      • -------- Create Death and Decay extra effect --------
      • Unit - Create 1 Dummy Caster for (Owner of (Triggering unit)) at GEN_TEMP_POINT[1] facing Default building facing degrees
      • Unit - Add a 9.00 second Generic expiration timer to (Last created unit)
      • Unit - Add (Paladin) Consecration visual effect to (Last created unit)
      • Unit - Order (Last created unit) to Undead Lich - Death And Decay GEN_TEMP_POINT[1]
      • Custom script: call RemoveLocation(udg_GEN_TEMP_POINT[1])
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Ok :D Whenever you use an ARRAY variable, the system disposes memory for the use of 8192 slots inside that variable (like having 8192 variables, but only using one) So. Use single Point variable instead of array :).

Don't mind about having several triggers. Maybe doing one hard trigger is heavier (for the system) than 2 simple triggers.

BUT...

Looking at your triggers, there's no use for the use of 2 points, and for the use of two triggers :p They both happen with the same event, and should work properly being merged into one trigger :p

BTW have you tried just creating the Special Effect instead of doing it with a dummy skill? :p
 
Level 5
Joined
May 20, 2008
Messages
138
Ok :D Whenever you use an ARRAY variable, the system disposes memory for the use of 8192 slots inside that variable (like having 8192 variables, but only using one) So. Use single Point variable instead of array :).
Wow I had no idea about that! Do you think I should switch to using a single GEN_TEMP_POINT for simple spells like this instead? (because I use GENT_TEMP_POINT[array] for charge spells and the like where I need to create and remove several points in the same trigger. I also use arrays sometimes to make spells MPI).

Don't mind about having several triggers. Maybe doing one hard trigger is heavier (for the system) than 2 simple triggers.

BUT...

Looking at your triggers, there's no use for the use of 2 points, and for the use of two triggers :p They both happen with the same event, and should work properly being merged into one trigger :p

Yes that was what I thought but that was when it bugged and I decided to post here! I experimented around quite a lot with my old trigger and it really was this single action that broke it:
  • Unit - Order (Last created unit) to Human Blood Mage - Flame Strike GEN_TEMP_POINT[1]
If it was enabled flame strike was cast but the second dummy wasn't even created, if it was disabled the second dummy got created and successfully cast.
BTW have you tried just creating the Special Effect instead of doing it with a dummy skill? :p

Do you think that would be more effective to trigger? It's this part of the flame strike visual that I'm using:
2zjcoxu.jpg

Combined with death and decay using the same visual to make it denser:
i3857s.jpg
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
You can do this:

Set TPoint = Center of Home
Unit - Order Unit to Move to TPoint
Call RemoveLocation(udg_TPoint)
Set TPoint = Center of Lake
Unit - Order Unit To Move to TPoint
Call RemoveLocation(udg_TPoint)

It will work, and will send each unit to the current TPoint configuration. The only reason to use Point Arrays is for Triggers that use several times a variable of the same type like:

Create Special Effect
Set FX[1] = Last Created Special Effect
Create Special Effect
Set FX[2] = Last Created Special Effect
Do a bunch of stuff
Destroy FX[1]
Create Another One
Set Last created Fx[1]
Do stuff
Wait 2 sec
Destroy FX[2]
Etc...

You could divide the damage dealt by 4, and create 4 units, send them all to cast at the same point (For each integer A from 1 to 4, do: Create Unit, Order Last Created Unit to Cast). It would cast 4 spells, and that would increase the density of the FX... i think...

I'd like to test it... xD Would you send me the map via PM or post it here to check it out? :p
 
Level 5
Joined
May 20, 2008
Messages
138
Thanks for your replies guys!

It will work, and will send each unit to the current TPoint configuration. The only reason to use Point Arrays is for Triggers that use several times a variable of the same type like:

Would it be more "effective" if you changed arrays such as "GEN_TEMP_POINT[1]" and "GEN_TEMP_POINT[2]" into two separate variables "TempPoint1" and "TempPoint2"?

Thank you guys for offering to look at my map but somehow the issue magically solved itself when I changed the trigger to this:

  • Paladin Consecration
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to (Paladin) Consecration
    • Actions
      • Game - Display to (All players) the text: consecration
      • Set GEN_TEMP_POINT_single = (Position of (Triggering unit))
      • -------- Create Flame strike damage and effect --------
      • -------- Create Flame strike damage and effect --------
      • -------- Create Flame strike damage and effect --------
      • Unit - Create 1 Dummy Caster for (Owner of (Triggering unit)) at GEN_TEMP_POINT_single facing Default building facing degrees
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Add (Paladin) Consecration dummy to (Last created unit)
      • Unit - Order (Last created unit) to Human Blood Mage - Flame Strike GEN_TEMP_POINT_single
      • -------- Create Death and Decay extra effect --------
      • -------- Create Death and Decay extra effect --------
      • -------- Create Death and Decay extra effect --------
      • Unit - Create 1 Dummy Caster for (Owner of (Triggering unit)) at GEN_TEMP_POINT_single facing Default building facing degrees
      • Unit - Add a 9.00 second Generic expiration timer to (Last created unit)
      • Unit - Add (Paladin) Consecration visual effect to (Last created unit)
      • Unit - Order (Last created unit) to Undead Lich - Death And Decay GEN_TEMP_POINT_single
      • Custom script: call RemoveLocation(udg_GEN_TEMP_POINT_single)

However, I am now creating another trigger that works in a similar manner and where it seems like I'm getting that annoying bug once again (or maybe I'm just stupid? :( )

  • Freezing Trap freeze
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Freezing Trap
    • Actions
      • Game - Display to (All players) the text: Debug: Mine exploded
      • -------- create the AoE effect and slow --------
      • Set GEN_TEMP_POINT[1] = (Position of (Triggering unit))
      • Unit - Create 1 Dummy Caster for (Owner of (Triggering unit)) at GEN_TEMP_POINT[1] facing Default building facing degrees
      • Unit - Add a 15.00 second Generic expiration timer to (Last created unit)
      • Unit - Add (Hunter) Freezing trap slow to (Last created unit)
      • Unit - Add (Hunter) Freezing trap visual effect to (Last created unit)
      • Unit - Order (Last created unit) to Undead Lich - Death And Decay GEN_TEMP_POINT[1]
      • -------- loop through all nearby units to find the closest one --------
      • Set GEN_TEMP_GROUP_single = (Units within 500.00 of GEN_TEMP_POINT[1] matching (((Matching unit) belongs to an enemy of (Owner of (Triggering unit))) Equal to True))
      • Set HHUNTER_Trap_distance = 500.00
      • Game - Display to (All players) the text: Debug: Does this pa...
      • Game - Display to (All players) the text: (String((Number of units in GEN_TEMP_GROUP_single)))
      • Game - Display to (All players) the text: (String(HHUNTER_Trap_distance))
      • Unit Group - Pick every unit in GEN_TEMP_GROUP_single and do (Actions)
        • Loop - Actions
          • Game - Display to (All players) the text: Debug: loop
          • Set GEN_TEMP_POINT[2] = (Position of (Picked unit))
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between GEN_TEMP_POINT[1] and GEN_TEMP_POINT[2]) Less than or equal to HHUNTER_Trap_distance
            • Then - Actions
              • Set HHUNTER_Trap_freezetarget = (Picked unit)
              • Set HHUNTER_Trap_distance = (Distance between GEN_TEMP_POINT[1] and GEN_TEMP_POINT[2])
            • Else - Actions
          • Custom script: call RemoveLocation(udg_GEN_TEMP_POINT[2])
      • -------- create another dummy to stun the closest target --------
      • Set GEN_TEMP_POINT_single = (Position of HHUNTER_Trap_freezetarget)
      • Unit - Create 1 Dummy Caster for (Owner of (Triggering unit)) at GEN_TEMP_POINT_single facing Default building facing degrees
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Add (Hunter) Freezing Trap stun to (Last created unit)
      • Unit - Order (Last created unit) to Human Mountain King - Storm Bolt HHUNTER_Trap_freezetarget
      • Game - Display to (All players) the text: Debug: Does this part of the trigger run?
      • Custom script: call DestroyGroup(udg_GEN_TEMP_GROUP_single)
      • Custom script: call RemoveLocation(udg_GEN_TEMP_POINT_single)
      • Custom script: call RemoveLocation(udg_GEN_TEMP_POINT[1])
Once again its a single spellcasting action that breaks the trigger.

  • Unit - Order (Last created unit) to Undead Lich - Death And Decay GEN_TEMP_POINT[1]
If this action is enabled, the game seems to forget about what GEN_TEMP_POINT[1] is and thus it doesn't put any units into GEN_TEMP_GROUP_single, and if I disable it, it creates the dummies, runs the loop and does the stun just fine. In other words, if the Death and Decay action is disabled everything else in the trigger runs perfectly, and if its enabled the game doesn't run the loop (nor create the second dummy caster, whose creation is dependant on the loop). Wtf?
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
Uh... but you are doing 5 stuff with the point:
1) The triggering unit is there
2) The Dummy 1 is created there
3) The dummy 1 is ordered to cast there
4) the Dummy 2 is created there
5) The dummy 2 is ordered to cast there...

Have you tried changing the order of the dummy creation/cast? First Death/Decay and then FireStrike?
 
Level 5
Joined
May 20, 2008
Messages
138
Oh, no, the Flame Strike/Death and Decay trigger is working fine since I changed it, even though I'm using the same point several times! The trigger I'm talking about now is a new one where I get a similar kind of bug (so I figured I'd post it in the same thread instead of taking space from other people in the thread list :p). It's the bottom "hidden" thing in my previous post (as you can see it's a completely different trigger).

Maybe there is some sort of known bug with ordering units to cast at a specific point via the trigger GUI?
 
Level 20
Joined
Jul 14, 2011
Messages
3,213
1) Whenever you use a Generic Unit Event you can change (Owner of (Triggering Unit)) for (Triggering Player)

2) Don't use Array Points. You can create Point1 and Point2 and work with these. It's 0.00001 faster xD. Also, I would suggest giving your variables more 'Generic' names.. P1 (Point 1), G1 (Group 1), TempPoint, TempGroup, GenGroup, GenPoint, Point_1, etc. There's a reason to call math variables 'X, Y, Z' :)

3) You are adding 2 skills to the first unit, and ordering to cast one of them. What's with the other one?

4) The 'Target' field of the ability allows casting on ground?

5) Is the Text-Order ID of the Ability the same than 'Lich - Death and Decay'?

6) Try using a Point with offset 1 and check if it works (Since that's a different point)

7) You could create the last dummy inside the loop and if/then/else, and not outside it =)

8) This isn't actually looping to find the nearest target... It's picking all the units within 500 range from the trap and freezing them all. You could pick a Random Unit from the group if you want to freeze one.

  • Freezing Trap freeze
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Freezing Trap
    • Actions
      • -------- create the AoE effect and slow --------
      • Set P1 = (Position of (Triggering unit))
      • Unit - Create 1 Dummy Caster for (Triggeriing Player) at P1 facing Default building facing degrees
      • Unit - Add a 15.00 second Generic expiration timer to (Last created unit)
      • Unit - Add (Hunter) Freezing trap slow to (Last created unit)
      • Unit - Add (Hunter) Freezing trap visual effect to (Last created unit)
      • Unit - Order (Last created unit) to Undead Lich - Death And Decay P1
      • -------- loop through all nearby units to find the closest one --------
      • Custom script: set bj_wantDestroyGroup = true
      • Unit Group - Pick every unit in (Units within 500.00 of P1 matching (((Matching unit) belongs to an enemy of (Triggering Player) Equal to True)) and do (Actions)
        • Loop - Actions
          • Set U1 = (Picked Unit)
          • Set P2 = (Position of U1)
          • -------- create another dummy to stun the closest target --------
          • Unit - Create 1 Dummy Caster for (Triggering Player) at P2 facing Default building facing degrees
          • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
          • Unit - Add (Hunter) Freezing Trap stun to (Last created unit)
          • Unit - Order (Last created unit) to Human Mountain King - Storm Bolt U1
          • Custom script: call RemoveLocation(udg_P2)
      • Custom script: call RemoveLocation(udg_P1)
Could be something like that. I know that you just wanted the Death and Decay thing... but I just wanted to check everything else xD
 
Level 22
Joined
Nov 14, 2008
Messages
3,256
Don't use Array Points. You can create Point1 and Point2 and work with these. It's 0.00001 faster xD.

False. It's not about speed in this case that you create a different amount of variables of a type instead of an array, it's based on how much space in a map they will take and I can assure you that it's definitely necessary as no user will use 2^13 array slots of a variable at the same time. The suggestion is true, statement about speed not.
 
Level 22
Joined
Nov 14, 2008
Messages
3,256
Globals are slow compared to locals (useless info but anyway), arrays slower than normal variables I guess as they'll need variable + index to retrieve the information. While non-array just need variable. Although compared to hashtables, faster for sure. That's why spells created with indexing are much faster than hashtables, and as JASS is such an awfully slow language you should keep it as fast as possible (from my point of view).
 
Status
Not open for further replies.
Top