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

Spell causing game crash - Please Test it yourself

Status
Not open for further replies.
Level 18
Joined
May 11, 2012
Messages
2,108
This spell sometimes crashes the game when there are lotsa enemies around you. I have no idea why it does so, but I suspect it could be lightning.



  • Death Hand
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Death Hand
    • Actions
      • -------- ------------------------------------------------------------------------------------- --------
      • Set DH_MaxIndex = (DH_MaxIndex + 1)
      • Set DH_TrigUnit[DH_MaxIndex] = (Triggering unit)
      • Set DH_TargetUnit[DH_MaxIndex] = (Target unit of ability being cast)
      • -------- ------------------------------------------------------------------------------------- --------
      • -------- ------------------------------------------------------------------------------------- --------
      • Set DH_Point = (Position of DH_TrigUnit[DH_MaxIndex])
      • Set DH_Point2 = (Position of DH_TargetUnit[DH_MaxIndex])
      • -------- ------------------------------------------------------------------------------------- --------
      • -------- ------------------------------------------------------------------------------------- --------
      • Unit - Turn collision for DH_TargetUnit[DH_MaxIndex] Off
      • Lightning - Create a Magic Leash lightning effect from source DH_Point to target DH_Point2
      • Lightning - Change color of DH_Lightning[DH_MaxIndex] to (67.00 12.00 49.00) with 1.00 alpha
      • Set DH_Lightning[DH_MaxIndex] = (Last created lightning effect)
      • -------- ------------------------------------------------------------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DH_MaxIndex Equal to 1
        • Then - Actions
          • Trigger - Turn on Death Hand Loop <gen>
        • Else - Actions
      • -------- ------------------------------------------------------------------------------------- --------
      • -------- ------------------------------------------------------------------------------------- --------
      • Custom script: call RemoveLocation(udg_DH_Point)
      • Custom script: call RemoveLocation(udg_DH_Point2)
      • Custom script: set udg_DH_Point = null
      • Custom script: set udg_DH_Point2 = null

  • Death Hand Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Custom script: local integer zOffset = 80
      • -------- ------------------------------------------------------------------------------------- --------
      • For each (Integer DH_Loop) from 1 to DH_MaxIndex, do (Actions)
        • Loop - Actions
          • -------- ------------------------------------------------------------------------------------- --------
          • Set DH_Point = (Position of DH_TrigUnit[DH_Loop])
          • Set DH_Point2 = (Position of DH_TargetUnit[DH_Loop])
          • Set DH_Angle = (Angle from DH_Point2 to DH_Point)
          • -------- ------------------------------------------------------------------------------------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • (Distance between DH_Point and DH_Point2) Less than or equal to 75.00
                  • (Life of DH_TargetUnit[DH_Loop]) Less than or equal to 0.41
            • Then - Actions
              • -------- ------------------------------------------------------------------------------------- --------
              • Lightning - Destroy DH_Lightning[DH_Loop]
              • -------- ------------------------------------------------------------------------------------- --------
              • Unit - Turn collision for DH_TargetUnit[DH_Loop] On
              • Unit - Create 1 Dummy Caster for (Owner of DH_TrigUnit[DH_Loop]) at DH_Point2 facing Default building facing degrees
              • Set TempDummyUnit = (Last created unit)
              • Unit - Add a 0.50 second Generic expiration timer to TempDummyUnit
              • Unit - Add Dummy Death Hand to TempDummyUnit
              • Unit - Set level of Dummy Death Hand for TempDummyUnit to (Level of Death Hand for DH_TrigUnit[DH_Loop])
              • Unit - Order TempDummyUnit to Orc Tauren Chieftain - War Stomp
              • Special Effect - Create a special effect at DH_Point2 using war3mapImported\DarkNova.mdx
              • Special Effect - Destroy (Last created special effect)
              • -------- ------------------------------------------------------------------------------------- --------
              • Set DH_TrigUnit[DH_Loop] = DH_TrigUnit[DH_MaxIndex]
              • Set DH_TrigUnit[DH_MaxIndex] = No unit
              • Set DH_TargetUnit[DH_Loop] = DH_TargetUnit[DH_MaxIndex]
              • Set DH_TargetUnit[DH_MaxIndex] = No unit
              • Set DH_Lightning[DH_Loop] = DH_Lightning[DH_MaxIndex]
              • Set DH_MaxIndex = (DH_MaxIndex - 1)
              • Set DH_Loop = (DH_Loop - 1)
            • Else - Actions
              • -------- ------------------------------------------------------------------------------------- --------
              • Set DH_Point3 = (DH_Point2 offset by 12.50 towards DH_Angle degrees)
              • Unit - Order DH_TargetUnit[DH_Loop] to Stop
              • Unit - Make DH_TargetUnit[DH_Loop] face DH_Point over 0.00 seconds
              • Custom script: call SetUnitX(udg_DH_TargetUnit[udg_DH_Loop], GetLocationX(udg_DH_Point3))
              • Custom script: call SetUnitY(udg_DH_TargetUnit[udg_DH_Loop], GetLocationY(udg_DH_Point3))
              • Custom script: call MoveLightningEx(udg_DH_Lightning[udg_DH_Loop], true, GetLocationX(udg_DH_Point), GetLocationY(udg_DH_Point), GetLocationZ(udg_DH_Point)+zOffset, GetLocationX(udg_DH_Point2), GetLocationY(udg_DH_Point2), GetLocationZ(udg_DH_Point2)+zOffset)
              • Custom script: call RemoveLocation(udg_DH_Point3)
              • -------- ------------------------------------------------------------------------------------- --------
          • -------- ------------------------------------------------------------------------------------- --------
          • Custom script: call RemoveLocation(udg_DH_Point)
          • Custom script: call RemoveLocation(udg_DH_Point2)
          • -------- ------------------------------------------------------------------------------------- --------
      • -------- ------------------------------------------------------------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • DH_MaxIndex Equal to 0
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
      • -------- ------------------------------------------------------------------------------------- --------
      • Custom script: set udg_DH_Point = null
      • Custom script: set udg_DH_Point2 = null
      • Custom script: set udg_DH_Point3 = null
 
Level 12
Joined
May 22, 2015
Messages
1,051
I tried reading through it. What exactly does the spell do?

From reading, this is what I think happens. Hopefully it's not embarrassing haha:
You target a unit with the spell and it drags them towards the caster and then stuns and damages enemies around the caster when that unit is in range or dead. A lightning effects shows the connection from the targeted unit and the caster.

If this is what happens, I am confused how more units being nearby would cause problems. The only things I can think of are if the dragged unit regaining collision with lots of nearby units can cause the game to crash.

If you think it's the lightning effect, try spawning tons of them and moving them around and see what happens.

Also maybe try to confirm that your array index is being reset correctly. I can't see a problem in the code, but if it's failing to be reset, then it could be going passed the array size.
 
Level 18
Joined
May 11, 2012
Messages
2,108
You guessed correctly.
I ask myself the same thing. I really don't know what the hell, I think I'm handling the lightning correctly and with caution.

I don't even...

When playing single player, this spell might even work through entire gameplay, but in multiplayer, the chances to ruin my game are so high.
 
Level 12
Joined
May 22, 2015
Messages
1,051
That sucks :/ I would definitely try outputting DH_MaxIndex to make sure it is decreasing properly and try spamming the lightning effects and moving them around super fast.

If neither of those work, you can try moving a unit the same way as with this trigger into a pile of other units and then give it collision back.

Is this spell cast a lot? Is it cast more with more players?
 
During your deindexing, add this line:
  • Set DH_TrigUnit[DH_Loop] = DH_TrigUnit[DH_MaxIndex]
  • Set DH_TrigUnit[DH_MaxIndex] = No unit
  • Set DH_TargetUnit[DH_Loop] = DH_TargetUnit[DH_MaxIndex]
  • Set DH_TargetUnit[DH_MaxIndex] = No unit
  • Set DH_Lightning[DH_Loop] = DH_Lightning[DH_MaxIndex]
  • Custom script: set udg_DH_Lightning[DH_MaxIndex] = null
Then when you move/destroy the lightning, add this script:
  • Custom script: if (udg_DH_Lightning[udg_DH_Loop] != null) then
  • Custom script: call MoveLightningEx(udg_DH_Lightning[udg_DH_Loop], true, GetLocationX(udg_DH_Point), GetLocationY(udg_DH_Point), GetLocationZ(udg_DH_Point)+zOffset, GetLocationX(udg_DH_Point2), GetLocationY(udg_DH_Point2), GetLocationZ(udg_DH_Point2)+zOffset)
  • Custom script: else
  • Custom script: call BJDebugMsg("Potential crash on moving lightning.")
  • Custom script: endif
  • Custom script: if (udg_DH_Lightning[udg_DH_Loop] != null) then
  • Lightning - Destroy DH_Lightning[DH_Loop]
  • Custom script: else
  • Custom script: call BJDebugMsg("Potential crash on destroy.")
  • Custom script: endif
I added a debug message that signifies when the trigger would have potentially crashed. Your goal is to reproduce the crash and see if you can get that message to display. If it you get the message, then you know it involves lightning and you should be able to debug more easily from there.

Otherwise it may be something else. In case you're curious, all I did was I nulled the pointer during the deindexing, and then I check if the pointer is null before performing actions on the lightning. If the lightning is the culprit, then technically this will prevent the crash, but it still means there is a problem with your code if it happens.
 
Okay, basicly, after reading this code, I found no obvious issues with it.

However, here's 3 possible issues you should rule out:

1) What happens if DH_Loop = DH_MaxIndex?
I'm not sure how "For each (Integer DH_Loop) from 1 to DH_MaxIndex, do (Actions)" converts into JASS, maybe the decrement of DH_MaxIndex inside the trigger screws things up here, causing an infinite loop.

2) A potential crash due to destroying a location that doesn't exist:
Set DH_Point = (Position of DH_TrigUnit[DH_Loop])
Set DH_Point2 = (Position of DH_TargetUnit[DH_Loop])
What if one of those units was removed from the game?
Again, I don't know how "Position of" converts into JASS, but it might be possible that it doesn't return a placeholder (0,0)-location if the unit is null and instead just returns null aswell.
In this case, you'd remove a null location, which will crash the thread.

3) You issue many orders throughout your spell. Make sure none of these orders fires any other potential trigger that you only want to fire on player-issued orders. This can create a trigger loop, especially if the trigger involving the player-issued order also fire another order.
 
Level 18
Joined
May 11, 2012
Messages
2,108
During your deindexing, add this line:
  • Set DH_TrigUnit[DH_Loop] = DH_TrigUnit[DH_MaxIndex]
  • Set DH_TrigUnit[DH_MaxIndex] = No unit
  • Set DH_TargetUnit[DH_Loop] = DH_TargetUnit[DH_MaxIndex]
  • Set DH_TargetUnit[DH_MaxIndex] = No unit
  • Set DH_Lightning[DH_Loop] = DH_Lightning[DH_MaxIndex]
  • Custom script: set udg_DH_Lightning[DH_MaxIndex] = null
Then when you move/destroy the lightning, add this script:
  • Custom script: if (udg_DH_Lightning[udg_DH_Loop] != null) then
  • Custom script: call MoveLightningEx(udg_DH_Lightning[udg_DH_Loop], true, GetLocationX(udg_DH_Point), GetLocationY(udg_DH_Point), GetLocationZ(udg_DH_Point)+zOffset, GetLocationX(udg_DH_Point2), GetLocationY(udg_DH_Point2), GetLocationZ(udg_DH_Point2)+zOffset)
  • Custom script: else
  • Custom script: call BJDebugMsg("Potential crash on moving lightning.")
  • Custom script: endif
  • Custom script: if (udg_DH_Lightning[udg_DH_Loop] != null) then
  • Lightning - Destroy DH_Lightning[DH_Loop]
  • Custom script: else
  • Custom script: call BJDebugMsg("Potential crash on destroy.")
  • Custom script: endif
I added a debug message that signifies when the trigger would have potentially crashed. Your goal is to reproduce the crash and see if you can get that message to display. If it you get the message, then you know it involves lightning and you should be able to debug more easily from there.

Otherwise it may be something else. In case you're curious, all I did was I nulled the pointer during the deindexing, and then I check if the pointer is null before performing actions on the lightning. If the lightning is the culprit, then technically this will prevent the crash, but it still means there is a problem with your code if it happens.

I have put these lines into my code. So far no Debug output and no crash.
Hopefully it'll stay like this. :)
 
Status
Not open for further replies.
Top