• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Spell: Psycho Hook Lag

Status
Not open for further replies.
Level 8
Joined
Feb 17, 2007
Messages
368
Can anyone tell me why this spell lags? The lag occurs after the spell is finished casting; ie. I think when all the hook dummys are destroyed.

  • Pein Psycho Hook
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Mass Psycho Hook
    • Actions
      • -------- Array slots are limited to 8192 --------
      • -------- We use a maximum of 100 dummys per cast --------
      • -------- So this spell shouldn't be casted more often then 80 times (lag would stop people from doing this anyway...) --------
      • For each (Integer i) from 1 to 6, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • PHMax Less than 80
            • Then - Actions
              • Set loc = (Position of (Triggering unit))
              • -------- Increases the total ammount of hooks by one --------
              • Set PHMax = (PHMax + 1)
              • -------- Sets the variables which are necessary --------
              • Set PHCaster[PHMax] = (Triggering unit)
              • -------- Shall the hook return yet? No --------
              • Set PHReturn[PHMax] = False
              • -------- How far did the hook travel yet? 0 --------
              • Set PHDistance[(PHMax x 2)] = 0.00
              • -------- How far shall it go? 1000 + 1000 per level --------
              • Set PHDistance[((PHMax x 2) + 1)] = (((Real((Level of Mass Psycho Hook for (Triggering unit)))) x 1000.00) + 1000.00)
              • -------- How fast will the hook travel forward? --------
              • Set PHSpeed[(PHMax x 2)] = 30.00
              • -------- And how fast back to the caster? --------
              • Set PHSpeed[((PHMax x 2) + 1)] = 15.00
              • -------- Straight or with an angle? --------
              • -------- Setting the angle to less then 0 will make the hook go straight like the normal dota hook --------
              • Set PHAngle[PHMax] = ((Real(i)) x 60.00)
              • -------- This is the head of the hook --------
              • Unit - Create 1 PsychoHookDummy for (Owner of (Triggering unit)) at loc facing (Facing of (Triggering unit)) degrees
              • -------- It shall look a little different --------
              • Animation - Change (Last created unit)'s size to (250.00%, 250.00%, 250.00%) of its original size
              • Set PHSegment[(PHMax x 100)] = (Last created unit)
              • -------- We created one segment already (the first one) --------
              • Set PHSegmentMax[PHMax] = 1
              • -------- Runs the main trigger to deal with the movement and so on --------
              • Trigger - Turn on PsychoHookLoop <gen>
              • -------- Removes leaks --------
              • Custom script: call RemoveLocation( udg_loc )
            • Else - Actions
  • PsychoHookLoop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • -------- Declaration of some local variables so there is no need to waste space for global ones --------
      • Custom script: local real a = 0
      • Custom script: local unit u = null
      • Custom script: local unit u2 = null
      • -------- This trigger will be turned of if there is nothing to do --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • PHMax Less than 1
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
          • For each (Integer i) from 1 to PHMax, do (Actions)
            • Loop - Actions
              • Custom script: set udg_PHDistance[udg_i*2] = udg_PHDistance[udg_i*2] + udg_PHSpeed[udg_i*2]
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • PHCaster[i] Not equal to No unit
                  • (PHCaster[i] is alive) Equal to True
                  • Or - Any (Conditions) are true
                    • Conditions
                      • PHDistance[(i x 2)] Less than PHDistance[((i x 2) + 1)]
                      • PHReturn[i] Equal to True
                  • ((Playable map area) contains PHSegment[(i x 100)]) Equal to True
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • PHReturn[i] Equal to False
                    • Then - Actions
                      • -------- Moves the first one --------
                      • Custom script: set u = udg_PHSegment[udg_i*100]
                      • -------- "a" is the direction the first hook will travel along --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • PHAngle[i] Greater than or equal to 0.00
                        • Then - Actions
                          • Custom script: set a = GetUnitFacing( udg_PHCaster[udg_i] ) + udg_PHAngle[udg_i]
                        • Else - Actions
                          • Custom script: set a = GetUnitFacing( udg_PHSegment[udg_i*100] )
                      • -------- This makes the first unit face where it's going --------
                      • Custom script: call SetUnitFacing( u, a )
                      • -------- This is called polar projection (it's the same as "point with polar offset" but with coordinates) --------
                      • -------- The position of the first unit will be set to its position + (Cos for x and Sin for y of its facing angle) * speed --------
                      • Custom script: call SetUnitX( u, GetUnitX( u ) + Cos( a * bj_DEGTORAD ) * udg_PHSpeed[udg_i*2] )
                      • Custom script: call SetUnitY( u, GetUnitY( u ) + Sin( a * bj_DEGTORAD ) * udg_PHSpeed[udg_i*2] )
                      • Set loc = (Position of PHSegment[(i x 100)])
                      • -------- Checks if a unit is within range --------
                      • -------- The unit has to be: --------
                      • -------- -non flying --------
                      • -------- -not be a target yet --------
                      • -------- -not be a target yet --------
                      • -------- -not to be a structure --------
                      • -------- -alive --------
                      • -------- -hostile --------
                      • Set TempArrayGroup[i] = (Units within 180.00 of loc matching ((((Matching unit) is A flying unit) Equal to False) and ((((((Matching unit) is in PHTargetGroup) Equal to False) and (((Matching unit) is A structure) Equal to False)) and (((Matching unit) is alive) Equal to True)) and
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (TempArrayGroup[i] is empty) Equal to False
                        • Then - Actions
                          • Set PHTarget[i] = (Random unit from TempArrayGroup[i])
                          • Unit Group - Add PHTarget[i] to PHTargetGroup
                          • Set PHDistance[((i x 2) + 1)] = 0.00
                          • Set PHReturn[i] = True
                          • -------- Set Damage here (Preset: 100 + 100 per level) --------
                          • Unit - Cause PHCaster[i] to damage PHTarget[i], dealing (((Real((Level of Mass Psycho Hook for PHCaster[i]))) x 1000.00) + 0.00) damage of attack type Spells and damage type Normal
                          • -------- Impact Effect --------
                          • Special Effect - Create a special effect attached to the chest of PHTarget[i] using Abilities\Spells\Undead\OrbOfDeath\OrbOfDeathMissile.mdl
                          • Special Effect - Destroy (Last created special effect)
                        • Else - Actions
                      • Custom script: call DestroyGroup( udg_TempArrayGroup[udg_i] )
                      • Custom script: call RemoveLocation( udg_loc )
                      • -------- Change distance between segments here (Preset: 75 ) --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • PHSegmentMax[i] Less than 101
                          • PHSegmentMax[i] Less than or equal to ((Integer(PHDistance[(i x 2)])) / 75)
                        • Then - Actions
                          • Set loc = (Position of PHCaster[i])
                          • Set loc2 = (Position of PHSegment[((i x 100) + (PHSegmentMax[i] - 1))])
                          • -------- Other hook dummys are created --------
                          • Unit - Create 1 PsychoHookDummy for (Owner of PHCaster[i]) at loc facing loc2
                          • Custom script: call RemoveLocation( udg_loc )
                          • Custom script: call RemoveLocation( udg_loc2 )
                          • Set PHSegment[((i x 100) + PHSegmentMax[i])] = (Last created unit)
                          • Set PHSegmentMax[i] = (PHSegmentMax[i] + 1)
                        • Else - Actions
                      • -------- Other hook dummys are moved --------
                      • Custom script: set u2 = udg_PHSegment[udg_i*100]
                      • For each (Integer i2) from 1 to PHSegmentMax[i], do (Actions)
                        • Loop - Actions
                          • Custom script: set u = udg_PHSegment[ udg_i * 100 + udg_i2 ]
                          • -------- This calculates the angle between a segment and the segment behind it --------
                          • Custom script: set a = Atan2( GetUnitY(u2) - GetUnitY(u), GetUnitX(u2) - GetUnitX(u) )
                          • Custom script: call SetUnitX( u, GetUnitX(u) + Cos(a) * udg_PHSpeed[udg_i*2] )
                          • Custom script: call SetUnitY( u, GetUnitY(u) + Sin(a) * udg_PHSpeed[udg_i*2] )
                          • -------- bj_RADTODEG is used to change radiants to degrees --------
                          • Custom script: call SetUnitFacing( u, a *bj_RADTODEG )
                          • Custom script: set u2 = u
                    • Else - Actions
                      • -------- Same the other way round --------
                      • Custom script: set u2 = udg_PHCaster[udg_i]
                      • Set loc = (Position of PHCaster[i])
                      • For each (Integer i2) from 1 to PHSegmentMax[i], do (Actions)
                        • Loop - Actions
                          • Custom script: set u = udg_PHSegment[ udg_i * 100 + ( udg_PHSegmentMax[udg_i] - udg_i2 ) ]
                          • Custom script: set a = Atan2( GetUnitY(u2) - GetUnitY(u), GetUnitX(u2) - GetUnitX(u) )
                          • Custom script: call SetUnitX( u, GetUnitX(u) + Cos(a) * udg_PHSpeed[udg_i*2+1] )
                          • Custom script: call SetUnitY( u, GetUnitY(u) + Sin(a) * udg_PHSpeed[udg_i*2+1] )
                          • Custom script: if udg_PHCaster[udg_i] != u2 then
                          • Custom script: call SetUnitFacing(u2, a*bj_RADTODEG+180)
                          • Custom script: endif
                          • Custom script: set u2 = u
                          • -------- Checks if the distance ^ 2 between the target and the caster is very small --------
                          • Custom script: if 25000>Pow(GetUnitX(u2)-GetUnitX(udg_PHCaster[udg_i]), 2)+Pow(GetUnitY(u2)-GetUnitY(udg_PHCaster[udg_i]), 2)then
                          • -------- Hides the segment --------
                          • Custom script: call ShowUnit(u2,false)
                          • Custom script: endif
                      • Custom script: call RemoveLocation( udg_loc )
                      • -------- Target is moved to the first/last hook (however you'd like to call it now) --------
                      • Custom script: set u = udg_PHTarget[udg_i]
                      • Custom script: set u2 = udg_PHSegment[udg_i*100]
                      • Custom script: call SetUnitX( u, GetUnitX( u2 ) )
                      • Custom script: call SetUnitY( u, GetUnitY( u2 ) )
                      • Set loc = (Position of PHTarget[i])
                      • -------- Stop if the target vanishes or reached the caster --------
                      • Set loc2 = (Position of PHCaster[i])
                      • -------- Delete the "IsAlive?-Thing" to make this skill pull dead units --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (PHTarget[i] is alive) Equal to True
                          • PHTarget[i] Not equal to No unit
                          • (Distance between loc and loc2) Greater than 64.00
                        • Then - Actions
                        • Else - Actions
                          • Set PHReturn[i] = False
                      • Custom script: call RemoveLocation( udg_loc )
                      • Custom script: call RemoveLocation( udg_loc2 )
                • Else - Actions
                  • -------- Clean up and sort array slots --------
                  • For each (Integer i2) from 0 to 99, do (Actions)
                    • Loop - Actions
                      • Unit - Unhide PHSegment[((i x 100) + i2)]
                      • Unit - Kill PHSegment[((i x 100) + i2)]
                      • Set PHSegment[((i x 100) + i2)] = PHSegment[((PHMax x 100) + i2)]
                      • -------- So it won't waste space until the slots are used again --------
                      • -------- Usually I don't do that but for such an ammount of units it seems appropriate --------
                      • Set PHSegment[((PHMax x 100) + i2)] = No unit
                  • Unit Group - Remove PHTarget[i] from PHTargetGroup
                  • Set PHCaster[i] = PHCaster[PHMax]
                  • Set PHTarget[i] = PHTarget[PHMax]
                  • Set PHDistance[(i x 2)] = PHDistance[(PHMax x 2)]
                  • Set PHDistance[((i x 2) + 1)] = PHDistance[((PHMax x 2) + 1)]
                  • Set PHSpeed[(i x 2)] = PHSpeed[(PHMax x 2)]
                  • Set PHSpeed[((i x 2) + 1)] = PHSpeed[((PHMax x 2) + 1)]
                  • Set PHAngle[i] = PHAngle[PHMax]
                  • Set PHReturn[i] = PHReturn[PHMax]
                  • Set PHSegmentMax[i] = PHSegmentMax[PHMax]
                  • Set PHMax = (PHMax - 1)
                  • Set i = (i - 1)
      • -------- Clean leaks --------
      • Custom script: set u = null
      • Custom script: set u2 = null
 
Level 13
Joined
Mar 24, 2010
Messages
950
well at time it looks like your running 100s of loops every .03 sec's which is alot.. also i didnt see but do you let the 100 dummy units die or are removed? Also 100 units to spawn and then die/remove is a shit ton.. just having that many units die at once on a semi old comp will make it lag spike a sec.
 
Level 19
Joined
Feb 4, 2009
Messages
1,313
just tried my spell on my laptop (which isn't the best one) and it did not lag at all
maybe you should get a new pc?
anyway I changed unhide&kill to remove for you so it will look worse but maybe be less performance-hungry
as a last resort you could change the effect/dummy model to something easier like the one used at dota(pudge wars
if that still won't work go play sc2 because it is just not possible to make this spell more efficient with the wc3 engine (I doubt that GUI or JASS would make a big difference in this case)
 

Attachments

  • PsychoHook v0.2.w3x
    58.9 KB · Views: 55
Level 8
Joined
Feb 17, 2007
Messages
368
No my pc is fine actually, lol. It's brand new. It doesn't lag in the test map that I dled for the spell, but in my map it does. So I'm thinking its somehow something with my map, but I don't know what... Or maybe my implementation of the spell? I dunno.. Let me test it with the remove trigger you added.
 
Status
Not open for further replies.
Top