• 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.

Chain Hook v1.1.1

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
=========================================
CHAIN HOOK v1.1.1
=========================================


At first, I was thinking to make something very original, something that really comes out from my own brain. I searching around the hive. And finally I got an idea. Yeah, the idea was about this ability, an ability that will grabs a unit for several seconds, but without using lightning effect. When I firstly tried to make this ability, I felt it's nearly impossible to make this work correctly. It's impossible for me to make it without the use of chain dummy group and use a normal indexing. This spell had been abandoned for several days until I got some ideas about ways to make it work. And yeah, it's working smoothly now, but not perfect because native looping integer gives the ability a bound. And you know what? I feel proud that I can finish this spell, I feel great, I feel smart, yeah, I just feel it.
I think this is the 2nd best of my resources after my iswp. I just feel a little disappointed that there is just some people come to say, "hey, nice spell there". yeah, because at first I think this is something brilliant.
Anyway, I have put so much effort on this spell. Check it out!! One of the most well-coded, efficient, very original, and super neat spell!!
in my resource list
Chain Hook
Launches a chain hook onto the targeted point. Grabs and deals damage once it hits a target. The target couldn't move further than specific range for several seconds.
Level 1 - 400 Max Range. 50 damage. 10 seconds.
Level 2 - 600 Max Range. 100 damage. 15 seconds.
Level 3 - 800 Max Range. 150 damage. 20 seconds.
Level 4 - 1000 Max Range. 200 damage. 25 seconds.

- This spell is highly configurable
- Do not grab a target at take back event
- This spell is a little fragile. Don't cast this too much/often/fast
- Cooldown, manacost, cast range, etc. haven't been set. You can set it as you like


  • Configuration
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- main ability that will run the trigger --------
      • Set CH_ConfMainAbility = Chain Hook
      • -------- unit model for the chain --------
      • Set CH_ConfChainModel = Chain
      • -------- unit model for the head of the chain hook --------
      • Set CH_ConfHeadModel = Head
      • -------- maximum casted chain hook for each unit. this is to avoid error --------
      • Set CH_ConfMaxCastPerUnit = 3
      • -------- true if you want the target to be taken with the chain head at the end of duration --------
      • Set CH_ConfTakeTarget = True
      • -------- Attack type. look at trigger comment above for the attack type list. Attack type affects the dealt damage amount --------
      • Set CH_ConfAttackType = 6
      • -------- distance per chain. set this to = 25 x chain model size at object editor --------
      • Set CH_ConfDistancePerChain = 50.00
      • -------- max distance for head chain to acquire a target --------
      • Set CH_ConfDetectRange = 100.00
      • -------- sfx when the head hits a target --------
      • Set CH_ConfOnHitSfx = Abilities\Weapons\HydraliskImpact\HydraliskImpact.mdl
      • -------- sfx when the target got dragged --------
      • Set CH_ConfDragSfx = Abilities\Weapons\AncientProtectorMissile\AncientProtectorMissile.mdl
      • -------- launch z of the chain hook --------
      • Set CH_ConfChainHeight = 60.00
      • -------- damage per level --------
      • Set CH_ConfDamage[1] = 50.00
      • Set CH_ConfDamage[2] = 100.00
      • Set CH_ConfDamage[3] = 150.00
      • Set CH_ConfDamage[4] = 200.00
      • -------- maximum range of the hook per level --------
      • Set CH_ConfMaxRange[1] = 400.00
      • Set CH_ConfMaxRange[2] = 600.00
      • Set CH_ConfMaxRange[3] = 800.00
      • Set CH_ConfMaxRange[4] = 1000.00
      • -------- duration of the hook after it locks a target --------
      • Set CH_ConfDuration[1] = 10.00
      • Set CH_ConfDuration[2] = 15.00
      • Set CH_ConfDuration[3] = 20.00
      • Set CH_ConfDuration[4] = 25.00
  • CH Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to CH_ConfMainAbility
    • Actions
      • Set CH_IndexMax = (CH_IndexMax + 1)
      • Set CH_Caster[CH_IndexMax] = (Triggering unit)
      • Set CH_CastIndex[CH_IndexMax] = 0
      • For each (Integer CH_Loop[1]) from 1 to CH_IndexMax, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • CH_Caster[CH_IndexMax] Equal to CH_Caster[CH_Loop[1]]
            • Then - Actions
              • Set CH_CastIndex[CH_IndexMax] = (CH_CastIndex[CH_IndexMax] + 1)
            • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • CH_CastIndex[CH_IndexMax] Greater than CH_ConfMaxCastPerUnit
        • Then - Actions
          • Unit - Order CH_Caster[CH_IndexMax] to Stop
          • Set CH_IndexMax = (CH_IndexMax - 1)
          • Skip remaining actions
        • Else - Actions
      • Set CH_Player = (Owner of CH_Caster[CH_IndexMax])
      • Set CH_Level = (Level of (Ability being cast) for CH_Caster[CH_IndexMax])
      • Set CH_Point[1] = (Position of CH_Caster[CH_IndexMax])
      • Set CH_Point[2] = (Target point of ability being cast)
      • Set CH_Angle[CH_IndexMax] = (Angle from CH_Point[1] to CH_Point[2])
      • Set CH_Boolean[CH_IndexMax] = False
      • Set CH_MaxRange[CH_IndexMax] = CH_ConfMaxRange[CH_Level]
      • Set CH_Damage[CH_IndexMax] = CH_ConfDamage[CH_Level]
      • Set CH_Integer[CH_IndexMax] = 0
      • Set CH_Integer2[CH_IndexMax] = 0
      • Set CH_DummyCount[CH_IndexMax] = (Integer((CH_MaxRange[CH_IndexMax] / CH_ConfDistancePerChain)))
      • Set CH_Target[CH_IndexMax] = No unit
      • Set CH_Duration[CH_IndexMax] = CH_ConfDuration[CH_Level]
      • For each (Integer CH_Loop[1]) from 1 to (CH_DummyCount[CH_IndexMax] - 1), do (Actions)
        • Loop - Actions
          • Set CH_IndexMax2 = (CH_IndexMax2 + 1)
          • Set CH_ChainsIndex[CH_IndexMax2] = CH_Loop[1]
          • Set CH_ChainsCastIndex[CH_IndexMax2] = CH_CastIndex[CH_IndexMax]
          • Set CH_ChainsOwner[CH_IndexMax2] = CH_Caster[CH_IndexMax]
          • Set CH_Point[3] = (CH_Point[1] offset by (CH_ConfDistancePerChain x (Real(CH_Loop[1]))) towards CH_Angle[CH_IndexMax] degrees)
          • Unit - Create 1 CH_ConfChainModel for CH_Player at CH_Point[3] facing CH_Angle[CH_IndexMax] degrees
          • Set CH_Chains[CH_IndexMax2] = (Last created unit)
          • Animation - Change CH_Chains[CH_IndexMax2]'s vertex coloring to (100.00%, 100.00%, 100.00%) with 100.00% transparency
          • Unit - Add Crow Form to CH_Chains[CH_IndexMax2]
          • Unit - Remove Crow Form from CH_Chains[CH_IndexMax2]
          • Animation - Change CH_Chains[CH_IndexMax2] flying height to CH_ConfChainHeight at 0.00
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • CH_Loop[1] Equal to 1
            • Then - Actions
              • Unit - Create 1 CH_ConfHeadModel for CH_Player at CH_Point[3] facing CH_Angle[CH_IndexMax] degrees
              • Set CH_Head[CH_IndexMax] = (Last created unit)
              • Unit - Add Crow Form to CH_Head[CH_IndexMax]
              • Unit - Remove Crow Form from CH_Head[CH_IndexMax]
              • Animation - Change CH_Head[CH_IndexMax] flying height to CH_ConfChainHeight at 0.00
            • Else - Actions
          • Custom script: call RemoveLocation(udg_CH_Point[3])
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • CH_IndexMax Equal to 1
        • Then - Actions
          • Trigger - Turn on CH Loop <gen>
        • Else - Actions
      • Custom script: call RemoveLocation(udg_CH_Point[1])
      • Custom script: call RemoveLocation(udg_CH_Point[2])
  • CH Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • For each (Integer CH_Loop[2]) from 1 to CH_IndexMax, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • CH_Integer[CH_Loop[2]] Less than CH_DummyCount[CH_Loop[2]]
            • Then - Actions
              • Set CH_Integer[CH_Loop[2]] = (CH_Integer[CH_Loop[2]] + 1)
              • For each (Integer CH_Loop[3]) from 1 to CH_IndexMax2, do (Actions)
                • Loop - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • CH_ChainsOwner[CH_Loop[3]] Equal to CH_Caster[CH_Loop[2]]
                    • Then - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • CH_ChainsCastIndex[CH_Loop[3]] Equal to CH_CastIndex[CH_Loop[2]]
                        • Then - Actions
                          • Custom script: call SetUnitX(udg_CH_Chains[udg_CH_Loop[3]], GetUnitX(udg_CH_Caster[udg_CH_Loop[2]]) + ( I2R (udg_CH_ChainsIndex[udg_CH_Loop[3]]) * udg_CH_ConfDistancePerChain) * Cos(udg_CH_Angle[udg_CH_Loop[2]] * bj_DEGTORAD))
                          • Custom script: call SetUnitY(udg_CH_Chains[udg_CH_Loop[3]], GetUnitY(udg_CH_Caster[udg_CH_Loop[2]]) + ( I2R (udg_CH_ChainsIndex[udg_CH_Loop[3]]) * udg_CH_ConfDistancePerChain) * Sin(udg_CH_Angle[udg_CH_Loop[2]] * bj_DEGTORAD))
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • CH_ChainsIndex[CH_Loop[3]] Equal to (CH_Integer[CH_Loop[2]] - 1)
                            • Then - Actions
                              • Animation - Change CH_Chains[CH_Loop[3]]'s vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
                            • Else - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • CH_ChainsIndex[CH_Loop[3]] Equal to CH_Integer[CH_Loop[2]]
                            • Then - Actions
                              • Custom script: call SetUnitX(udg_CH_Head[udg_CH_Loop[2]], GetUnitX(udg_CH_Chains[udg_CH_Loop[3]]))
                              • Custom script: call SetUnitY(udg_CH_Head[udg_CH_Loop[2]], GetUnitY(udg_CH_Chains[udg_CH_Loop[3]]))
                              • Custom script: set udg_CH_Point[4] = Location(GetUnitX(udg_CH_Head[udg_CH_Loop[2]]), GetUnitY(udg_CH_Head[udg_CH_Loop[2]]))
                              • Set CH_Group = (Units within CH_ConfDetectRange of CH_Point[4] matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of CH_Caster[CH_Loop[2]])) Equal to True) and ((((
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • (Number of units in CH_Group) Greater than 0
                                • Then - Actions
                                  • Set CH_Integer[CH_Loop[2]] = (CH_DummyCount[CH_Loop[2]] + 1)
                                  • Set CH_Target[CH_Loop[2]] = (Random unit from CH_Group)
                                  • Custom script: call UnitDamageTargetBJ( udg_CH_Caster[udg_CH_Loop[2]], udg_CH_Target[udg_CH_Loop[2]], udg_CH_Damage[udg_CH_Loop[2]], ConvertAttackType(udg_CH_ConfAttackType), DAMAGE_TYPE_NORMAL )
                                  • Unit Group - Add CH_Target[CH_Loop[2]] to CH_ChainedGroup
                                  • Special Effect - Create a special effect attached to the chest of CH_Target[CH_Loop[2]] using CH_ConfOnHitSfx
                                  • Special Effect - Destroy (Last created special effect)
                                • Else - Actions
                              • Custom script: call RemoveLocation(udg_CH_Point[4])
                              • Custom script: call DestroyGroup(udg_CH_Group)
                            • Else - Actions
                        • Else - Actions
                    • Else - Actions
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • CH_Target[CH_Loop[2]] Not equal to No unit
                • Then - Actions
                  • Set CH_Point[4] = (Position of CH_Caster[CH_Loop[2]])
                  • Set CH_Point[5] = (Position of CH_Target[CH_Loop[2]])
                  • Set CH_Range[CH_Loop[2]] = (Distance between CH_Point[4] and CH_Point[5])
                  • Custom script: set udg_CH_Angle[udg_CH_Loop[2]] = AngleBetweenPoints(udg_CH_Point[4], udg_CH_Point[5])
                  • Custom script: call SetUnitX(udg_CH_Head[udg_CH_Loop[2]], GetLocationX(udg_CH_Point[5]))
                  • Custom script: call SetUnitY(udg_CH_Head[udg_CH_Loop[2]], GetLocationY(udg_CH_Point[5]))
                  • Custom script: call SetUnitFacing(udg_CH_Head[udg_CH_Loop[2]], udg_CH_Angle[udg_CH_Loop[2]])
                  • For each (Integer CH_Loop[3]) from 1 to CH_IndexMax2, do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • CH_ChainsOwner[CH_Loop[3]] Equal to CH_Caster[CH_Loop[2]]
                        • Then - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • CH_ChainsCastIndex[CH_Loop[3]] Equal to CH_CastIndex[CH_Loop[2]]
                            • Then - Actions
                              • Animation - Change CH_Chains[CH_Loop[3]]'s vertex coloring to (100.00%, 100.00%, 100.00%) with 100.00% transparency
                              • Custom script: call SetUnitX(udg_CH_Chains[udg_CH_Loop[3]], GetUnitX(udg_CH_Caster[udg_CH_Loop[2]]) + ( I2R (udg_CH_ChainsIndex[udg_CH_Loop[3]]) * udg_CH_ConfDistancePerChain) * Cos(udg_CH_Angle[udg_CH_Loop[2]] * bj_DEGTORAD))
                              • Custom script: call SetUnitY(udg_CH_Chains[udg_CH_Loop[3]], GetUnitY(udg_CH_Caster[udg_CH_Loop[2]]) + ( I2R (udg_CH_ChainsIndex[udg_CH_Loop[3]]) * udg_CH_ConfDistancePerChain) * Sin(udg_CH_Angle[udg_CH_Loop[2]] *bj_DEGTORAD))
                              • Custom script: call SetUnitFacing(udg_CH_Chains[udg_CH_Loop[3]], udg_CH_Angle[udg_CH_Loop[2]])
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • CH_ChainsIndex[CH_Loop[3]] Less than or equal to (Integer((CH_Range[CH_Loop[2]] / CH_ConfDistancePerChain)))
                                • Then - Actions
                                  • Animation - Change CH_Chains[CH_Loop[3]]'s vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
                                • Else - Actions
                            • Else - Actions
                        • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • CH_Range[CH_Loop[2]] Greater than CH_MaxRange[CH_Loop[2]]
                    • Then - Actions
                      • Custom script: call SetUnitX(udg_CH_Target[udg_CH_Loop[2]], GetUnitX(udg_CH_Caster[udg_CH_Loop[2]]) + udg_CH_MaxRange[udg_CH_Loop[2]] * Cos(udg_CH_Angle[udg_CH_Loop[2]] * bj_DEGTORAD) )
                      • Custom script: call SetUnitY(udg_CH_Target[udg_CH_Loop[2]], GetUnitY(udg_CH_Caster[udg_CH_Loop[2]]) + udg_CH_MaxRange[udg_CH_Loop[2]] * Sin(udg_CH_Angle[udg_CH_Loop[2]] * bj_DEGTORAD) )
                      • Set CH_Point[6] = (Position of CH_Target[CH_Loop[2]])
                      • Special Effect - Create a special effect at CH_Point[6] using CH_ConfDragSfx
                      • Special Effect - Destroy (Last created special effect)
                      • Custom script: call RemoveLocation(udg_CH_Point[6])
                    • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • CH_Duration[CH_Loop[2]] Greater than 0.00
                    • Then - Actions
                      • Set CH_Duration[CH_Loop[2]] = (CH_Duration[CH_Loop[2]] - 0.03)
                    • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • Or - Any (Conditions) are true
                        • Conditions
                          • CH_Duration[CH_Loop[2]] Less than or equal to 0.00
                          • (CH_Target[CH_Loop[2]] is alive) Equal to False
                          • (CH_Caster[CH_Loop[2]] is alive) Equal to False
                    • Then - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • CH_Boolean[CH_Loop[2]] Equal to False
                        • Then - Actions
                          • For each (Integer CH_Loop[3]) from 1 to CH_IndexMax2, do (Actions)
                            • Loop - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • CH_ChainsOwner[CH_Loop[3]] Equal to CH_Caster[CH_Loop[2]]
                                • Then - Actions
                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    • If - Conditions
                                      • CH_ChainsCastIndex[CH_Loop[3]] Equal to CH_CastIndex[CH_Loop[2]]
                                    • Then - Actions
                                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                        • If - Conditions
                                          • CH_ChainsIndex[CH_Loop[3]] Less than or equal to ((Integer(CH_Range[CH_Loop[2]])) / (Integer(CH_ConfDistancePerChain)))
                                        • Then - Actions
                                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                            • If - Conditions
                                              • (CH_DummyCount[CH_Loop[2]] - CH_ChainsIndex[CH_Loop[3]]) Less than CH_Integer2[CH_Loop[2]]
                                            • Then - Actions
                                              • Set CH_Integer2[CH_Loop[2]] = ((CH_DummyCount[CH_Loop[2]] - CH_ChainsIndex[CH_Loop[3]]) - 1)
                                            • Else - Actions
                                        • Else - Actions
                                          • Unit - Remove CH_Chains[CH_Loop[3]] from the game
                                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                            • If - Conditions
                                              • CH_Loop[3] Not equal to CH_IndexMax2
                                            • Then - Actions
                                              • Set CH_Chains[CH_Loop[3]] = CH_Chains[CH_IndexMax2]
                                              • Set CH_ChainsCastIndex[CH_Loop[3]] = CH_ChainsCastIndex[CH_IndexMax2]
                                              • Set CH_ChainsIndex[CH_Loop[3]] = CH_ChainsIndex[CH_IndexMax2]
                                              • Set CH_ChainsOwner[CH_Loop[3]] = CH_ChainsOwner[CH_IndexMax2]
                                            • Else - Actions
                                          • Set CH_IndexMax2 = (CH_IndexMax2 - 1)
                                          • Set CH_Loop[3] = (CH_Loop[3] - 1)
                                    • Else - Actions
                                • Else - Actions
                          • Set CH_Boolean[CH_Loop[2]] = True
                        • Else - Actions
                      • Set CH_Integer2[CH_Loop[2]] = (CH_Integer2[CH_Loop[2]] + 1)
                      • For each (Integer CH_Loop[3]) from 1 to CH_IndexMax2, do (Actions)
                        • Loop - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • CH_ChainsOwner[CH_Loop[3]] Equal to CH_Caster[CH_Loop[2]]
                            • Then - Actions
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • CH_ChainsCastIndex[CH_Loop[3]] Equal to CH_CastIndex[CH_Loop[2]]
                                • Then - Actions
                                  • Custom script: call SetUnitX(udg_CH_Chains[udg_CH_Loop[3]], GetUnitX(udg_CH_Caster[udg_CH_Loop[2]]) + ( I2R (udg_CH_ChainsIndex[udg_CH_Loop[3]]) * udg_CH_ConfDistancePerChain) * Cos(udg_CH_Angle[udg_CH_Loop[2]] * bj_DEGTORAD))
                                  • Custom script: call SetUnitY(udg_CH_Chains[udg_CH_Loop[3]], GetUnitY(udg_CH_Caster[udg_CH_Loop[2]]) + ( I2R (udg_CH_ChainsIndex[udg_CH_Loop[3]]) * udg_CH_ConfDistancePerChain) * Sin(udg_CH_Angle[udg_CH_Loop[2]] * bj_DEGTORAD))
                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    • If - Conditions
                                      • CH_ChainsIndex[CH_Loop[3]] Equal to (CH_DummyCount[CH_Loop[2]] - CH_Integer2[CH_Loop[2]])
                                    • Then - Actions
                                      • Custom script: call SetUnitX(udg_CH_Head[udg_CH_Loop[2]], GetUnitX(udg_CH_Chains[udg_CH_Loop[3]]))
                                      • Custom script: call SetUnitY(udg_CH_Head[udg_CH_Loop[2]], GetUnitY(udg_CH_Chains[udg_CH_Loop[3]]))
                                      • Unit - Remove CH_Chains[CH_Loop[3]] from the game
                                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                        • If - Conditions
                                          • CH_ConfTakeTarget Equal to True
                                          • (CH_Caster[CH_Loop[2]] is alive) Equal to True
                                          • (CH_Target[CH_Loop[2]] is alive) Equal to True
                                        • Then - Actions
                                          • Custom script: call SetUnitX(udg_CH_Target[udg_CH_Loop[2]], GetUnitX(udg_CH_Head[udg_CH_Loop[2]]))
                                          • Custom script: call SetUnitY(udg_CH_Target[udg_CH_Loop[2]], GetUnitY(udg_CH_Head[udg_CH_Loop[2]]))
                                          • Set CH_Point[6] = (Position of CH_Target[CH_Loop[2]])
                                          • Special Effect - Create a special effect at CH_Point[6] using CH_ConfDragSfx
                                          • Special Effect - Destroy (Last created special effect)
                                          • Custom script: call RemoveLocation(udg_CH_Point[6])
                                        • Else - Actions
                                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                        • If - Conditions
                                          • CH_Loop[3] Not equal to CH_IndexMax2
                                        • Then - Actions
                                          • Set CH_Chains[CH_Loop[3]] = CH_Chains[CH_IndexMax2]
                                          • Set CH_ChainsCastIndex[CH_Loop[3]] = CH_ChainsCastIndex[CH_IndexMax2]
                                          • Set CH_ChainsIndex[CH_Loop[3]] = CH_ChainsIndex[CH_IndexMax2]
                                          • Set CH_ChainsOwner[CH_Loop[3]] = CH_ChainsOwner[CH_IndexMax2]
                                        • Else - Actions
                                      • Set CH_IndexMax2 = (CH_IndexMax2 - 1)
                                      • Set CH_Loop[3] = (CH_Loop[3] - 1)
                                    • Else - Actions
                                • Else - Actions
                            • Else - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • CH_Integer2[CH_Loop[2]] Equal to CH_DummyCount[CH_Loop[2]]
                        • Then - Actions
                          • Unit Group - Remove CH_Target[CH_Loop[2]] from CH_ChainedGroup
                          • Unit - Remove CH_Head[CH_Loop[2]] from the game
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • CH_Loop[2] Not equal to CH_IndexMax
                            • Then - Actions
                              • Set CH_Caster[CH_Loop[2]] = CH_Caster[CH_IndexMax]
                              • Set CH_Angle[CH_Loop[2]] = CH_Angle[CH_IndexMax]
                              • Set CH_Boolean[CH_Loop[2]] = CH_Boolean[CH_IndexMax]
                              • Set CH_CastIndex[CH_Loop[2]] = CH_CastIndex[CH_IndexMax]
                              • Set CH_Damage[CH_Loop[2]] = CH_Damage[CH_IndexMax]
                              • Set CH_DummyCount[CH_Loop[2]] = CH_DummyCount[CH_IndexMax]
                              • Set CH_Duration[CH_Loop[2]] = CH_Duration[CH_IndexMax]
                              • Set CH_Head[CH_Loop[2]] = CH_Head[CH_IndexMax]
                              • Set CH_Integer[CH_Loop[2]] = CH_Integer[CH_IndexMax]
                              • Set CH_Integer2[CH_Loop[2]] = CH_Integer2[CH_IndexMax]
                              • Set CH_MaxRange[CH_Loop[2]] = CH_MaxRange[CH_IndexMax]
                              • Set CH_Range[CH_Loop[2]] = CH_Range[CH_IndexMax]
                              • Set CH_Target[CH_Loop[2]] = CH_Target[CH_IndexMax]
                            • Else - Actions
                          • Set CH_IndexMax = (CH_IndexMax - 1)
                          • Set CH_Loop[2] = (CH_Loop[2] - 1)
                        • Else - Actions
                    • Else - Actions
                  • Custom script: call RemoveLocation(udg_CH_Point[4])
                  • Custom script: call RemoveLocation(udg_CH_Point[5])
                • Else - Actions
                  • Set CH_Integer2[CH_Loop[2]] = (CH_Integer2[CH_Loop[2]] + 1)
                  • For each (Integer CH_Loop[3]) from 1 to CH_IndexMax2, do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • CH_ChainsOwner[CH_Loop[3]] Equal to CH_Caster[CH_Loop[2]]
                        • Then - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • CH_ChainsCastIndex[CH_Loop[3]] Equal to CH_CastIndex[CH_Loop[2]]
                            • Then - Actions
                              • Custom script: call SetUnitX(udg_CH_Chains[udg_CH_Loop[3]], GetUnitX(udg_CH_Caster[udg_CH_Loop[2]]) + ( I2R (udg_CH_ChainsIndex[udg_CH_Loop[3]]) * udg_CH_ConfDistancePerChain) * Cos(udg_CH_Angle[udg_CH_Loop[2]] * bj_DEGTORAD))
                              • Custom script: call SetUnitY(udg_CH_Chains[udg_CH_Loop[3]], GetUnitY(udg_CH_Caster[udg_CH_Loop[2]]) + ( I2R (udg_CH_ChainsIndex[udg_CH_Loop[3]]) * udg_CH_ConfDistancePerChain) * Sin(udg_CH_Angle[udg_CH_Loop[2]] * bj_DEGTORAD))
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • CH_ChainsIndex[CH_Loop[3]] Equal to (CH_DummyCount[CH_Loop[2]] - CH_Integer2[CH_Loop[2]])
                                • Then - Actions
                                  • Custom script: call SetUnitX(udg_CH_Head[udg_CH_Loop[2]], GetUnitX(udg_CH_Chains[udg_CH_Loop[3]]))
                                  • Custom script: call SetUnitY(udg_CH_Head[udg_CH_Loop[2]], GetUnitY(udg_CH_Chains[udg_CH_Loop[3]]))
                                  • Unit - Remove CH_Chains[CH_Loop[3]] from the game
                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    • If - Conditions
                                      • CH_Loop[3] Not equal to CH_IndexMax2
                                    • Then - Actions
                                      • Set CH_Chains[CH_Loop[3]] = CH_Chains[CH_IndexMax2]
                                      • Set CH_ChainsCastIndex[CH_Loop[3]] = CH_ChainsCastIndex[CH_IndexMax2]
                                      • Set CH_ChainsIndex[CH_Loop[3]] = CH_ChainsIndex[CH_IndexMax2]
                                      • Set CH_ChainsOwner[CH_Loop[3]] = CH_ChainsOwner[CH_IndexMax2]
                                    • Else - Actions
                                  • Set CH_IndexMax2 = (CH_IndexMax2 - 1)
                                  • Set CH_Loop[3] = (CH_Loop[3] - 1)
                                • Else - Actions
                            • Else - Actions
                        • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • CH_Integer2[CH_Loop[2]] Equal to CH_DummyCount[CH_Loop[2]]
                    • Then - Actions
                      • Unit - Remove CH_Head[CH_Loop[2]] from the game
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • CH_Loop[2] Not equal to CH_IndexMax
                        • Then - Actions
                          • Set CH_Caster[CH_Loop[2]] = CH_Caster[CH_IndexMax]
                          • Set CH_Angle[CH_Loop[2]] = CH_Angle[CH_IndexMax]
                          • Set CH_Boolean[CH_Loop[2]] = CH_Boolean[CH_IndexMax]
                          • Set CH_CastIndex[CH_Loop[2]] = CH_CastIndex[CH_IndexMax]
                          • Set CH_Damage[CH_Loop[2]] = CH_Damage[CH_IndexMax]
                          • Set CH_DummyCount[CH_Loop[2]] = CH_DummyCount[CH_IndexMax]
                          • Set CH_Duration[CH_Loop[2]] = CH_Duration[CH_IndexMax]
                          • Set CH_Head[CH_Loop[2]] = CH_Head[CH_IndexMax]
                          • Set CH_Integer[CH_Loop[2]] = CH_Integer[CH_IndexMax]
                          • Set CH_Integer2[CH_Loop[2]] = CH_Integer2[CH_IndexMax]
                          • Set CH_MaxRange[CH_Loop[2]] = CH_MaxRange[CH_IndexMax]
                          • Set CH_Range[CH_Loop[2]] = CH_Range[CH_IndexMax]
                          • Set CH_Target[CH_Loop[2]] = CH_Target[CH_IndexMax]
                        • Else - Actions
                      • Set CH_IndexMax = (CH_IndexMax - 1)
                      • Set CH_Loop[2] = (CH_Loop[2] - 1)
                    • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • CH_IndexMax Equal to 0
          • CH_IndexMax2 Equal to 0
        • Then - Actions
          • Trigger - Turn off CH Loop <gen>
        • Else - Actions

v1.1.1 - Tooltips improved
- Indexing fixed
- Main ability stored in a variable

v1.1.0- Index recycling improved
- Added sfx on drag
- Added instant pull

v1.0.9- fixed bug in take back animation where some chain skipped
- some improvements

v1.0.8- Bug in take back event fixed
- some improvements

v1.0.7- Now with take back animation
- Index recycler is now merged with loop trigger
- Many improvemets

v1.0.6- Attack type is now configurable
- Debuff removed
- Maximum cast per unit is now configurable to avoid error
- Cast trigger optimized

v1.0.5- Fixed mistake in loop
- The chain is now using a proper scaling

v1.0.4- removed a useless variable
- an unrecycled variable added

v1.0.3- Fixed repeated function call at loop trigger
- Added debuff
- Still can't find the leaked point.

v1.0.2- Optimized cast event trigger
- Fixed mistake in Index Handler
- Removed group leaks in loop

v1.0.1- removed duration bug
- better launch
- loop trigger (use of points) optimized
- leaks in loop trigger removed
- many other minor changes

v1.0.0 - Uploaded

1. Copy chain hook ability, chain and head unit at object editor into your map
2. Open import manager, export all files there into your map
3. Copy Chain Hook folder at trigger editor and paste it on you map
4. Open configuration trigger, edit them as you like. follow the instructions to help you understand what each variable means
5. Done

Callahanfor the Behemot Rider model
Infrisiosfor the precious chain models

Post here if you find anything's wrong with triggers or another objects. Don't need to give me credits. Edit it as you like. Please, give the system ratings instead of giving me rep+ (see my rep+ is disabled). End of all, enjoy :)
[TD] I. Greetings and opening words [/TD]
[TD] II. Description [/TD]

[TD] III. Characteristic [/TD]

[TD] IV. Triggers [/TD] [TD] V. Updates [/TD]
[TD] VI. How to import [/TD]

[TD] VII. Credits [/TD]
[TD] VIII. Closing words [/TD]

[TD] IX. My Resources [/TD]

Keywords:
chain, hook
Contents

Chain Hook (Map)

Reviews
19:01, 5th Jan 2014 BPower: review: http://www.hiveworkshop.com/forums/spells-569/chain-hook-v1-1-1-a-244237/index2.html#post2452466 To get your spell approved it has to run bug free on multiple casts. I'll set it to "Need Fix" until further...
Status
Not open for further replies.

Moderator

M

Moderator

19:01, 5th Jan 2014
BPower: review: http://www.hiveworkshop.com/forums/spells-569/chain-hook-v1-1-1-a-244237/index2.html#post2452466

To get your spell approved it has to run bug free on multiple casts.
I'll set it to "Need Fix" until further update.

If you have any questions feel free to send me a PM.
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
UPDATED!!!
- removed duration bug
- better launch
- loop trigger (use of points) optimized
- leaks in loop trigger removed
- many other minor changes

UPDATED !!!
- Optimized cast event trigger
- Fixed mistake in Index Handler
- Removed group leaks in loop

Leaks checker by nhocklanhox6 keeps telling me that there is 1 location is leaked on each cast. But I think it just tells me bullshit (I'm just kidding :p). Anyway, please, help me to find that leak.

UPDATED!!!
- Fixed repeated function call at loop trigger
- Added debuff
- Still can't find the leaked point.
 
Last edited by a moderator:
Level 15
Joined
Jul 6, 2009
Messages
889
GUI D:

Just two questions:

1. If you have some long range Blink, what happens? Will that unit be dragged with you?

2. If the caster dies, does the chain collapse?

Anyway:

1. The hook looks nice. It's not overkill but not too bland. I think it's just right.

2. Update the submission image to be of an in-game screenshot.

3. It's a nice spell. The concept is nice.
 

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
two answer:
1. yeah, I think that unit still will be dragged with the caster. But blink is not a fitting ability for strength hero like that..
2. yes,the chain collapsed. Actually I have just added this condition in v1.0.7. The chain will be taken back to the caster without dragging the target with...

anyway:
2. is that really important? I like that just use simple picture like that for the main screenshoot...

But, in this version, the "take back" event is still bugged. You will find the bug when caster stay close to the target at the end of duration

Updated to v1.0.8
- Bug in take back event fixed
- some improvements

This spell become trouble some with take back animation :( but I can't delete it. It makes the spell looks more lovely. Current advice is, dont cast this spell too fast and too much. I will try to find the problem ASAP
 
Last edited by a moderator:

Kazeon

Hosted Project: EC
Level 34
Joined
Oct 12, 2011
Messages
3,449
the prblem because we use a large number of chain unit. where double loop integer (i mean loop inside a loop) can not work with a large number. So then only advice is dont cast this too much..

actually the unit is still chained. it's just the chains that are not shown..

I have found a way how to fix the problem, but it will be something like remake of loop trigger. I'm just wondering what will I get by doing that hard update..
 
Last edited by a moderator:
Level 3
Joined
Sep 1, 2009
Messages
37
Wow thats a really cool spell. Was expecting a pudge hook copy but Im quite surprised. One thing that you could maybe implement (not sure if possible) would be to have the backswing animation of the hook - when you miss - grab onto targets in its path, if there happen to be any. You get what I mean?
 
Level 3
Joined
Sep 1, 2009
Messages
37
thnks :)
no, I don't get what you mean :p

you shoot out the chain - if it doesn't hit any unit it immediately flies back to you(that's how it works right now) . if it collides with any unit along its path - while returning to the casters position, it could connect the chain to the unit. That's my idea. If you still don't understand maybe I can make a picture once I'm on pc. ;)
 
Level 3
Joined
Sep 1, 2009
Messages
37
what I get is: so it will be like a pudges meat hook?

Nono I will explain on the picture example:

BFgMUnK.jpg


Caster shoots the hook targetting the black circle right. It will travel to the black circle but since there is no one to get hooked, the chain will return back to the caster.

Here is my idea: If any unit stands in the chains trajectory while its RETURNING, the chain would grab onto it just like it would if it hit a target in the first place.

So if the unit in the red circle was to move to where the arrow points while the chain is travelling back (from the black circle to the caster) it would get grabbed by the chain, and you could use the "Pull Targets" spell just as you would normally to pull the unit back to you.
 
Level 3
Joined
Sep 1, 2009
Messages
37
it can be but it seems not logical :p
I use an example here as question. How can you slice a coconut using backside of the knife? it's the same, how can the head grab a unit using its dull backside? :p

Yeah I thought about that too. It makes sense, but it would be a neat mechanic IF the head of the chain had a hook model :).

On a side note, Im pretty sure you could slice a coconut with the backside of a knife if you pressed hard enough :D.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
The spell produces errors very easily:
Units don't get detached properly, aswell as the hook is not always shown.
In the picture the unit within the circle is hooked, but no chain dummy units are displayed.

Concept and effects:
  • The spell is interesting and some people could find it useful
  • The time the hook lasts is ridiculously long, I would recommend something between 3 -7 seconds
Code and in-game behaviour:
  • The spell doesn't display correct in many cases (attached file)
  • Pulling units back per ability is too much delayed. (my personal opinion)
  • Hooking outside map boundaries will crash the game. (WorldBounds, BoundSentinel)
    For spells with high missle range, you should always check wether the unit is still inside the map or not.
  • I would recommend to use either coordinates or locations only.
    • Set CH_Angle[CH_Loop[2]] = (Angle from CH_Point[4] to CH_Point[5])
    ==
    • Custom script: set udg_CH_Angle[udg_CH_Loop[2]] = AngleBetweenPoints(udg_CH_Point[4], udg_CH_Point[5])
    You don't have to use custom script, when the GUI generated code does exactly the same.
Get rid of the bugs and we can discuss how you can optimize your code. For a huge amount of coded lines, it is always useful to add comments in between.
This will help you to erase unnecessary code and bugs.
 

Attachments

  • test.jpg
    test.jpg
    1 MB · Views: 146
Last edited:
Status
Not open for further replies.
Top