• 🏆 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!

Knock-Back 3D - MMS 3D V. 3.2.1

Knock-Back 3D
Multi-Movement System


System Description:
This, Incredible, System makes you able to move units, bounce them, make them fly, damage them with whatsoever technique you can think of, add effects on stages, and OUTRAGEOUS number of other features all smoothly joined together in one system

System Usage:
The MMS system itself has 60+ features, giving it outrageous possible usages, of which:
  1. Jump
  2. Line Damage
  3. AoE Damage
  4. Loop Damage
  5. Unit DPS
  6. Destructable Destroyer (intelligent)
  7. Bouncing Ball
  8. Missile
  9. Attack Missile
  10. Cyclone Movement
  11. Black Hole Simulation
  12. Homing Movement
  13. Acceleration to a Unit
  14. Realistic Missile
  15. And more depending on your imagination

System Features: (60+)
  • KB3D Features GUI
    • Events
    • Conditions
    • Actions
      • -------- Those Values are Required for the KB --------
      • -------- ------------------------------------------------ --------
      • -------- ------------------------ --------
      • -------- Knock-Backed Unit, the Knock-Backed Unit who all actions orbit around --------
      • Set KB3D_Unit = No unit
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Max Range, Maximum Range possible of the Knock-Back --------
      • Set KB3D_Range = 0.00
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Base KB Speed, Base Speed when starting the Knock-Back --------
      • Set KB3D_Speed = 0.00
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Angle, The KB's line angle, this will be useless if KB3D_Targeted_Unit is not null --------
      • Set KB3D_Angle = 0.00
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- ------------------------------------------------ --------
      • -------- Those Values are Optional for the KB --------
      • -------- NOTE: some values may depend on other to function, like LineDamage that needs "Damager, AttackType, DamageType, AoE" to function --------
      • -------- ------------------------------------------------ --------
      • -------- ------------------------ --------
      • -------- Targets Allowed --------
      • -------- ------------------------ --------
      • -------- Filter Damages and AoEKB with those values, if true, each one will allow filtering of Structures, Mechanicals, Magic Imminues, Allies --------
      • -------- ------------------------ --------
      • Set KB3D_D_MAGIC_IMMINUE = False
      • Set KB3D_D_ALLY = False
      • Set KB3D_D_MECHANICAL = False
      • Set KB3D_D_STRUCTURE = False
      • Set KB3D_D_ENEMY = True
      • Set KB3D_D_FLYING = False
      • Set KB3D_D_RESISTANT = False
      • -------- Requires: AoEKB, or, Damagers, or, BounceTarget --------
      • -------- ------------------------ --------
      • -------- Speed Changer, makes the unit move forward with a bonus speed equal to the KB speed, negative speed also works --------
      • Set KB3D_Speed_Changer = False
      • -------- Requires: NONE, Disables Angle --------
      • -------- ------------------------ --------
      • -------- Homing Missile, automatically sets needed features of KB3D for a homing missile --------
      • Set KB3D_HomingMissile = True
      • -------- Requires: NONE, Disables Angle --------
      • -------- ------------------------ --------
      • -------- Bounce Unit, Makes the KBed unit bounce on unpathable areas and units --------
      • Set KB3D_Bounce_Unit = False
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Bounce Targets, Bounces units that encounter the KBed unit --------
      • Set KB3D_Bounce_Target = False
      • -------- Requires: AoE --------
      • -------- ------------------------ --------
      • -------- End on Target Bounce, when hits a unit, ends the KB --------
      • Set KB3D_EndOnTargetBounce = False
      • -------- Requires: Bounce_Target --------
      • -------- ------------------------ --------
      • -------- Bounce Power, intensity of the Bounce --------
      • Set KB3D_Bounce_Power = 1.00
      • -------- Requires: Bounce --------
      • -------- ------------------------ --------
      • -------- Bounce Effect, Effect created on units that get Bounced --------
      • Set KB3D_Bounce_Fx = <Empty String>
      • -------- Requires: Bounce --------
      • -------- ------------------------ --------
      • -------- Destroy Destructibles, Destroys any destructibles on the path of the KB, does not destroy platforms, bridges, elevators --------
      • Set KB3D_DestroyDestructables = False
      • -------- Requires: Line Damage --------
      • -------- ------------------------ --------
      • -------- Line Effect, Effect created on units damaged by Line Damage --------
      • Set KB3D_Line_Fx = <Empty String>
      • -------- Requires: Line Damage --------
      • -------- ------------------------ --------
      • -------- End Trigger, This trigger will be excecuted at the end of the KB, you can use KB3D_Unit and KB3D_Targeted_Unit variables in the trigger --------
      • Set KB3D_EndTrigger = KB3D_EndTrigger
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- End on Obstacle, Immediatly Ends the KB if the KBed unit encounters an unpathable area --------
      • Set KB3D_EndOnObstacle = False
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Arc, Arc of the Angle of the KB, does not work with homing KB --------
      • Set KB3D_Arc = 0.00
      • -------- Requires: Angle --------
      • -------- ------------------------ --------
      • -------- Ending Effect, an Effect created at the End of the KB on the KBed Unit --------
      • Set KB3D_EndFx = <Empty String>
      • -------- Requires: AoE --------
      • -------- ------------------------ --------
      • -------- AoE End Damage, Damage dealt to enemy units in the AoE at the End of the KB --------
      • Set KB3D_AoEEndDamage = 0.00
      • -------- Requires: AoE, Damager, AType, DType --------
      • -------- ------------------------ --------
      • -------- AoE KB, if true, KBs Enemy units within the AoE, Range, Speed, Angle, are automatic --------
      • Set KB3D_AoEKB = False
      • -------- Requires: AoE --------
      • -------- ------------------------ --------
      • -------- AoE KB Power, The Power of the AoE KB, default value is 1.00 (normal), Min value: 0.01, Max value: 3.00 --------
      • Set KB3D_AoEKB_Power = 0.00
      • -------- Requires: AoEKB --------
      • -------- ------------------------ --------
      • -------- End when Dead, if true, the KB will end if the KBed unit is dead, TRUE by default --------
      • Set KB3D_EndwhenDead = True
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Ground Damage, Damages the Unit When it hits the Ground, Damage dealt is KB3D_ImpactDamage --------
      • Set KB3D_GroundDamage = False
      • -------- Requires: Damager, ImpactDamage, AType, DType --------
      • -------- ------------------------ --------
      • -------- KB the Target, When the Targeted Unit is hit, it will be KBed depending on the speed of the original KB --------
      • Set KB3D_KBTarget = False
      • -------- Requires: Targeted_Unit --------
      • -------- ------------------------ --------
      • -------- Stop Time, Maximum Time the KB will last, Note that if the KBed unit is flying at this time, it will be stuck --------
      • Set KB3D_StopTime = 0.00
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Kill at End, Kills the KBed Unit at the End of the KB --------
      • Set KB3D_KillatEnd = False
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Kill at Time, When this time is reached, the KBed unit will be killed, if this number is higher than KB3D_StopTime, EndWhenDead will be automatically turned on no matter what --------
      • Set KB3D_KillatTime = 0.00
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Acceleration, Speed Added/s to the KB speed --------
      • Set KB3D_Accel = 0.00
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Allow going outside playable bounds, Allows the KBed unit to go out of the Playable Bounds, SAFETY notice: this will not crash the game --------
      • Set KB3D_AllowOutSiding = False
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Area of Effect, Range where the Line Damage is applied to units --------
      • Set KB3D_AoE = 0.00
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Area of Effect Damage, Makes the KB3D_Damager, damage enemy units within KB3D_AoE by this value as a DPS --------
      • Set KB3D_AoEDamage = 0.00
      • -------- Requires: AoE, Damager, DType, AType --------
      • -------- ------------------------ --------
      • -------- Attack Type, Attack type of ALL damagings in the Instance --------
      • Set KB3D_AttackType = Normal
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Damage Type, Damage type of ALL damagings in the Instance --------
      • Set KB3D_DamageType = Magic
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Damager, Source of ALL damagings in the Instance --------
      • Set KB3D_Damager = No unit
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Destroy Trees?, Destroy Trees around the KBed unit while he is KBed? --------
      • Set KB3D_DestroyTree = True
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Disable Unit?, Disable the KBed Unit's Movement and Turning? --------
      • Set KB3D_DisableUnit = False
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- End When Hit?, Ends the KB if the KBed Unit hits the Targeted Unit --------
      • Set KB3D_EndWhenHit = False
      • -------- Requires: Targeted_Unit --------
      • -------- ------------------------ --------
      • -------- Face KB Anlge, makes the KBed Unit Face the Anlge of the KB during the KB --------
      • Set KB3D_FaceAngle = False
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Effect, Effect created on the Unit's Location if he is not flying, and applied on the Unit if he is flying on the Attach Point --------
      • Set KB3D_Fx = <Empty String>
      • -------- Requires: Attach --------
      • -------- ------------------------ --------
      • -------- Attachment Point, location on the KBed unit where Effects are attached --------
      • Set KB3D_Attach = <Empty String>
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- AoE End Effect, Effect Created on target units in the AoE at the End of the KB --------
      • Set KB3D_AoEEndFx = <Empty String>
      • -------- Requires: AoE, Attach --------
      • -------- ------------------------ --------
      • -------- Impact Damage, Damaged dealt to the KBed Unit if he hits an obstacle --------
      • Set KB3D_ImpactDamage = 0.00
      • -------- Requires: Damager --------
      • -------- ------------------------ --------
      • -------- intelligent KB, Enables the intelligent features of KB3D, see Main Code Comments for more info --------
      • Set KB3D_iKB = True
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Kill When Hit?, Kills the KBed Unit if he hits the Targeted Unit, Automatically set EndWhenHit to true --------
      • Set KB3D_KillWhenHit = False
      • -------- Requires: Targeted_Unit --------
      • -------- ------------------------ --------
      • -------- Kill if Out of Playable Bounds, Kills the KBed Unit if he gets out of Playable Bounds, this automatically sets KB3D_AllowOutSiding to TRUE --------
      • Set KB3D_KillifOutSider = False
      • -------- Requires: AllowOutSiding --------
      • -------- ------------------------ --------
      • -------- Line Damage, Damage dealt to enemy units in the AoE around the KBed Unit --------
      • Set KB3D_LineDamage = 0.00
      • -------- Requires: Damager, AoE --------
      • -------- ------------------------ --------
      • -------- Loop Damage, DPS dealt to the KBed Unit --------
      • Set KB3D_LoopDamage = 0.00
      • -------- Requires: Damager, AoE --------
      • -------- ------------------------ --------
      • -------- Jump over Cliff, Allows the KBed unit to go over cliffs if he has more than 150 fly height and IF there is a possible location where he can land in a pathable point, not recommended with >0 Acceleration --------
      • Set KB3D_JumpOverCliff = False
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Target Damage, Damage dealt to the Targeted Unit when both KBed Unit and Targeted Unit hit each other, only happens once --------
      • Set KB3D_TargetDamage = 0.00
      • -------- Requires: Targeted_Unit, Damager --------
      • -------- ------------------------ --------
      • -------- Targeted Unit, if not null, makes the KBed Unit act like a homing missile targeting this unit, it also used for other functions --------
      • Set KB3D_Targeted_Unit = No unit
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Trail Effect, Effect Attached on the KBed Unit all along the Knock-Back and Destroyed at the end of the KB --------
      • Set KB3D_TrailFx = <Empty String>
      • -------- Requires: Attach --------
      • -------- ------------------------ --------
      • -------- Stop at Unpathable, Makes it impossible for the KBed Unit to path throught Unpathable Terrain --------
      • Set KB3D_UnpathableStop = True
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- Z Offset, Max Flying Height reached while Knockbacking --------
      • Set KB3D_Zoffset = 0.00
      • -------- Requires: NONE --------
      • -------- ------------------------ --------
      • -------- ------------------------------------------------ --------
      • -------- Registed All of the Settings --------
      • Custom script: call ExecuteFunc( "KB3D_Registration" )
      • -------- You can use the following to know how much the knock-back will last -- this can vary if the KB is homed on a moving unit --------
      • Set KB3D_Time = KB3D_Time
JASS:
    // Those Values are Required for the KB
    // ------------------------------------------------
    // ------------------------
    // Knock-Backed Unit, the Knock-Backed Unit who all actions orbit around
    set udg_KB3D_Unit = null
    // Requires: NONE
    // ------------------------
    // Max Range, Maximum Range possible of the Knock-Back
    set udg_KB3D_Range = 0.00
    // Requires: NONE
    // ------------------------
    // Base KB Speed, Base Speed when starting the Knock-Back
    set udg_KB3D_Speed = 0.00
    // Requires: NONE
    // ------------------------
    // Angle, The KB's line angle, this will be useless if KB3D_Targeted_Unit is not null
    set udg_KB3D_Angle = 0.00
    // Requires: NONE
    // ------------------------
    // ------------------------------------------------
    // Those Values are Optional for the KB
    // NOTE: some values may depend on other to function, like LineDamage that needs "Damager, AttackType, DamageType, AoE" to function
    // ------------------------------------------------
    // ------------------------
    // Targets Allowed
    // ------------------------
    // Filter Damages and AoEKB with those values, if true, each one will allow filtering of Structures, Mechanicals, Magic Imminues, Allies
    // ------------------------
    set udg_KB3D_D_MAGIC_IMMINUE = false
    set udg_KB3D_D_ALLY = false
    set udg_KB3D_D_MECHANICAL = false
    set udg_KB3D_D_STRUCTURE = false
    set udg_KB3D_D_ENEMY = true
    set udg_KB3D_D_FLYING = false
    set udg_KB3D_D_RESISTANT = false
    // Requires: AoEKB, or, Damagers, or, BounceTarget
    // ------------------------
    // Speed Changer, makes the unit move forward with a bonus speed equal to the KB speed, negative speed also works
    set udg_KB3D_Speed_Changer = false
    // Requires: NONE, Disables Angle
    // ------------------------
    // Homing Missile, automatically sets needed features of KB3D for a homing missile
    set udg_KB3D_HomingMissile = true
    // Requires: NONE, Disables Angle
    // ------------------------
    // Bounce Unit, Makes the KBed unit bounce on unpathable areas and units
    set udg_KB3D_Bounce_Unit = false
    // Requires: NONE
    // ------------------------
    // Bounce Targets, Bounces units that encounter the KBed unit
    set udg_KB3D_Bounce_Target = false
    // Requires: AoE
    // ------------------------
    // End on Target Bounce, when hits a unit, ends the KB
    set udg_KB3D_EndOnTargetBounce = false
    // Requires: Bounce_Target
    // ------------------------
    // Bounce Power, intensity of the Bounce
    set udg_KB3D_Bounce_Power = 1.00
    // Requires: Bounce
    // ------------------------
    // Bounce Effect, Effect created on units that get Bounced
    set udg_KB3D_Bounce_Fx = ""
    // Requires: Bounce
    // ------------------------
    // Destroy Destructibles, Destroys any destructibles on the path of the KB, does not destroy platforms, bridges, elevators
    set udg_KB3D_DestroyDestructables = false
    // Requires: Line Damage
    // ------------------------
    // Line Effect, Effect created on units damaged by Line Damage
    set udg_KB3D_Line_Fx = ""
    // Requires: Line Damage
    // ------------------------
    // End Trigger, This trigger will be excecuted at the end of the KB, you can use KB3D_Unit and KB3D_Targeted_Unit variables in the trigger
    set udg_KB3D_EndTrigger = udg_KB3D_EndTrigger
    // Requires: NONE
    // ------------------------
    // End on Obstacle, Immediatly Ends the KB if the KBed unit encounters an unpathable area
    set udg_KB3D_EndOnObstacle = false
    // Requires: NONE
    // ------------------------
    // Arc, Arc of the Angle of the KB, does not work with homing KB
    set udg_KB3D_Arc = 0.00
    // Requires: Angle
    // ------------------------
    // Ending Effect, an Effect created at the End of the KB  on the KBed Unit
    set udg_KB3D_EndFx = ""
    // Requires: AoE
    // ------------------------
    // AoE End Damage, Damage dealt to enemy units in the AoE at the End of the KB
    set udg_KB3D_AoEEndDamage = 0.00
    // Requires: AoE, Damager, AType, DType
    // ------------------------
    // AoE KB, if true, KBs Enemy units within the AoE, Range, Speed, Angle, are automatic
    set udg_KB3D_AoEKB = false
    // Requires: AoE
    // ------------------------
    // AoE KB Power, The Power of the AoE KB, default value is 1.00 (normal), Min value: 0.01, Max value: 3.00
    set udg_KB3D_AoEKB_Power = 0.00
    // Requires: AoEKB
    // ------------------------
    // End when Dead, if true, the KB will end if the KBed unit is dead, TRUE by default
    set udg_KB3D_EndwhenDead = true
    // Requires: NONE
    // ------------------------
    // Ground Damage, Damages the Unit When it hits the Ground, Damage dealt is KB3D_ImpactDamage
    set udg_KB3D_GroundDamage = false
    // Requires: Damager, ImpactDamage, AType, DType
    // ------------------------
    // KB the Target, When the Targeted Unit is hit, it will be KBed depending on the speed of the original KB
    set udg_KB3D_KBTarget = false
    // Requires: Targeted_Unit
    // ------------------------
    // Stop Time, Maximum Time the KB will last, Note that if the KBed unit is flying at this time, it will be stuck
    set udg_KB3D_StopTime = 0.00
    // Requires: NONE
    // ------------------------
    // Kill at End, Kills the KBed Unit at the End of the KB
    set udg_KB3D_KillatEnd = false
    // Requires: NONE
    // ------------------------
    // Kill at Time, When this time is reached, the KBed unit will be killed, if this number is higher than KB3D_StopTime, EndWhenDead will be automatically turned on no matter what
    set udg_KB3D_KillatTime = 0.00
    // Requires: NONE
    // ------------------------
    // Acceleration, Speed Added/s to the KB speed
    set udg_KB3D_Accel = 0.00
    // Requires: NONE
    // ------------------------
    // Allow going outside playable bounds, Allows the KBed unit to go out of the Playable Bounds, SAFETY notice: this will not crash the game
    set udg_KB3D_AllowOutSiding = false
    // Requires: NONE
    // ------------------------
    // Area of Effect, Range where the Line Damage is applied to units
    set udg_KB3D_AoE = 0.00
    // Requires: NONE
    // ------------------------
    // Area of Effect Damage, Makes the KB3D_Damager, damage enemy units within KB3D_AoE by this value as a DPS
    set udg_KB3D_AoEDamage = 0.00
    // Requires: AoE, Damager, DType, AType
    // ------------------------
    // Attack Type, Attack type of ALL damagings in the Instance
    set udg_KB3D_AttackType = ATTACK_TYPE_MELEE
    // Requires: NONE
    // ------------------------
    // Damage Type, Damage type of ALL damagings in the Instance
    set udg_KB3D_DamageType = DAMAGE_TYPE_MAGIC
    // Requires: NONE
    // ------------------------
    // Damager, Source of ALL damagings in the Instance
    set udg_KB3D_Damager = null
    // Requires: NONE
    // ------------------------
    // Destroy Trees?, Destroy Trees around the KBed unit while he is KBed?
    set udg_KB3D_DestroyTree = true
    // Requires: NONE
    // ------------------------
    // Disable Unit?, Disable the KBed Unit's Movement and Turning?
    set udg_KB3D_DisableUnit = false
    // Requires: NONE
    // ------------------------
    // End When Hit?, Ends the KB if the KBed Unit hits the Targeted Unit
    set udg_KB3D_EndWhenHit = false
    // Requires: Targeted_Unit
    // ------------------------
    // Face KB Anlge, makes the KBed Unit Face the Anlge of the KB during the KB
    set udg_KB3D_FaceAngle = false
    // Requires: NONE
    // ------------------------
    // Effect, Effect created on the Unit's Location if he is not flying, and applied on the Unit if he is flying on the Attach Point
    set udg_KB3D_Fx = ""
    // Requires: Attach
    // ------------------------
    // Attachment Point, location on the KBed unit where Effects are attached
    set udg_KB3D_Attach = ""
    // Requires: NONE
    // ------------------------
    // AoE End Effect, Effect Created on target units in the AoE at the End of the KB
    set udg_KB3D_AoEEndFx = ""
    // Requires: AoE, Attach
    // ------------------------
    // Impact Damage, Damaged dealt to the KBed Unit if he hits an obstacle
    set udg_KB3D_ImpactDamage = 0.00
    // Requires: Damager
    // ------------------------
    // intelligent KB, Enables the intelligent features of KB3D, see Main Code Comments for more info
    set udg_KB3D_iKB = true
    // Requires: NONE
    // ------------------------
    // Kill When Hit?, Kills the KBed Unit if he hits the Targeted Unit, Automatically set EndWhenHit to true
    set udg_KB3D_KillWhenHit = false
    // Requires: Targeted_Unit
    // ------------------------
    // Kill if Out of Playable Bounds, Kills the KBed Unit if he gets out of Playable Bounds, this automatically sets KB3D_AllowOutSiding to TRUE
    set udg_KB3D_KillifOutSider = false
    // Requires: AllowOutSiding
    // ------------------------
    // Line Damage, Damage dealt to enemy units in the AoE around the KBed Unit
    set udg_KB3D_LineDamage = 0.00
    // Requires: Damager, AoE
    // ------------------------
    // Loop Damage, DPS dealt to the KBed Unit
    set udg_KB3D_LoopDamage = 0.00
    // Requires: Damager, AoE
    // ------------------------
    // Jump over Cliff, Allows the KBed unit to go over cliffs if he has more than 150 fly height and IF there is a possible location where he can land in a pathable point, not recommended with >0 Acceleration
    set udg_KB3D_JumpOverCliff = false
    // Requires: NONE
    // ------------------------
    // Target Damage, Damage dealt to the Targeted Unit when both KBed Unit and Targeted Unit hit each other, only happens once
    set udg_KB3D_TargetDamage = 0.00
    // Requires: Targeted_Unit, Damager
    // ------------------------
    // Targeted Unit, if not null, makes the KBed Unit act like a homing missile targeting this unit, it also used for other functions
    set udg_KB3D_Targeted_Unit = null
    // Requires: NONE
    // ------------------------
    // Trail Effect, Effect Attached on the KBed Unit all along the Knock-Back and Destroyed at the end of the KB
    set udg_KB3D_TrailFx = ""
    // Requires: Attach
    // ------------------------
    // Stop at Unpathable, Makes it impossible for the KBed Unit to path throught Unpathable Terrain
    set udg_KB3D_UnpathableStop = true
    // Requires: NONE
    // ------------------------
    // Z Offset, Max Flying Height reached while Knockbacking
    set udg_KB3D_Zoffset = 0.00
    // Requires: NONE
    // ------------------------
    // ------------------------------------------------
    // Registed All of the Settings
    call ExecuteFunc( "KB3D_Registration" )
    // You can use the following to know how much the knock-back will last -- this can vary if the KB is homed on a moving unit
    set udg_KB3D_Time = udg_KB3D_Time

System CODE:
JASS:
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           Knock-Back 3D               [JASS - GUI]     V. 3.2.1         //
//     Multi-Movement System 3D                                            //
//                                            by Jad aka DotCa and T.D.W.  //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           System's Hidden Features:                                     //
//                                                                         //
//     1. To know if a unit is being KBed by the System, Use:              //
//        - LoadBoolean(udg_KB3D_HA, GetHandleId(Unit), GetHandleId(Unit)) //
//        True means that the unit is being KBed, also works in GUI        //
//     2. Use udg_KB3D_Time variable after registring the KB to actually   //
//        know how much the KB will last, NOTE that this the time may      //
//        varry if you have a Homing KB (using KB3D_Targeted_Unit)         //
//     3. Some Variables in the System has default values, but useful;     //
//        in Example, "udg_KB3D_Attach" is "origin" even without setting   //
//        it, so you won't need to change it before Registering a KB       //
//     4. You can get the ID of a Knockback after registrating it by       //
//        using the value of KB3D_Counter                                  //
//     5. You can remove any KB on a specific unit by setting KB3D_Remove  //
//        KB3D_RemoveUnit to this Unit, and then calling the function:     //
//        "KB3D_RemoveUnit()                                               //
//     6. You can know what caused the end of a KB in the EndTrigger by    //
//        checking those variables: KB3D_EndisUnit / KB3D_EndisUnpathable  //
//        KB3D_EndisNormal                                                 //
//     7. You can use the following Pause/Resume functions on a specific   //
//        KB instance or on all the system                                 //
//           - KB3D_Pause( ID )          Applies on a single KB            //
//           - KB3D_Resume( ID )         Applies on a single KB            //
//           - KB3D_PauseAll()           Applies on a All KB Instances     //
//           - KB3D_ResumeAll()          Applies on a All KB Instances     //
//           - KB3D_PauseRegistration()  Applies on a All KB Instances     //
//           - KB3D_ResumeRegistration() Applies on a All KB Instances     //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           System Informations:                                          //
//                                                                         //
//  The System is a well performing, ultra-purpose knockback (see uses     //
//  below ) Coded in JASS making it possible for all users to take         //
//  advantage of it, and GUI friendly to use, see Examples in the triggers //
//  above                                                                  //
//            Configurations that have default values:                     //
//                                                                         //
//     - KB3D_EndWhenDead        ==> TRUE                 by default       //
//     - KB3D_UnpathableStop     ==> TRUE                 by default       //
//     - KB3D_iKB                ==> TRUE                 by default       //
//     - KB3D_D_ENEMY            ==> TRUE                 by default       //
//     - KB3D_DestroyTree        ==> TRUE                 by default       //
//     - KB3D_AttackType         ==> ATTACK_TYPE_NORMAL   by default       //
//     - KB3D_DamageType         ==> DAMAGE_TYPE_MAGIC    by default       //
//     - KB3D_AoEKB_Power        ==> 1.00                 by default       //
//     - KB3D_Attach             ==> "origin"             by default       //
//     - Other Booleans          ==> FALSE                by default       //
//                                                                         //
//  The System also uses Always positive values for some configurations    //
//  to not make the knockback go wrong, those configurations are:          //
//                                                                         //
//      "KB3D_Range" - "KB3D_Speed" - "KB3D_ZOffset" - "KB3D_AoE"          //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//            HomingMissile, Accessibility feature                         //
//                                                                         //
//    When true, there will be no need to set the range and some other     //
//    features, since they will be automatically set to fit a homing       //
//    missile:                                                             //
//     - KB3D_Zoffset - KB3D_Range - KB3D_KillatEnd - KB3D_EndWhenHit -    //
//     - KB3D_FaceAngle - KB3D_UnpathableStop - KB3D_KillWhenHit -         //
//                                                                         //
//    This feature allows to skip the configurations of some features      //
//    needed for a homing missile, Note that Targeted_Unit needs to be set //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//            iKB, intelligent KB informations:                            //
//                                                                         //
//     iKB, makes some features in KB3D act intelligently, those features: //
//                                                                         //
//       -Range: usually always positive, it will be available in negative //
//               values, it will, if negative, flip the Angle (+180 d)     //
//       -Speed: usually always positive, it will be available in negative //
//               values, it will act normally, just the KBed unit will     //
//               move backward if the current speed is negative            //
//       -Height: usually always positive, it will be available in negative//
//               values, it will, if negative, make the unit go down       //
//               instead of up                                             //
//       -Damages:                                                         //
//       AoEEndDamage, AoEDamage, LineDamage, ImpactDamage, TargetDamage   //
//                                                                         //
//             All those values ^ will turn intelligent, by this, it means //
//             that if the Target of the Damage is not in approximated     //
//             height (Z) of the KBed Unit, the damage won't occur         //
//       -AoEKB, usually KBs all units in the AoE, it will choose only     //
//        Units that are close to it by the height, Z offset               //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           System Requirements:   Basic WE - (NONE)                      //
//                                                                         //
//  The System uses implemented CheckWalkability System by PurgeandFire    //
//  You "can" remove the initialization trigger of PnF's System since      //
//  it is directly implemented in the System, all will work fine with or   //
//  without removing your Initializer trigger                              //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           Credits:                                                      //
//                                                                         //
//    *WEHZ & TS Helpers Group for helping in Script Fixes                 //
//    *Barry the Moose for helping in main codes and fixes                 //
//    *PurgeandFire for his CheckWalkability System                        //
//    *Vexorian / Nestharus for the GetCollision function                  //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           How to Import?                                                //
//                                                                         //
//  1. Check that Create Unknown Variables is ticked in your WE Settings   //
//  2. Copy the Paste the Knock-Back 3D Folder                             //
//  3. Delete the Variable Creator Trigger and learn how to use the System //
//     by reading the documentation in the 2 Features Triggers (GUI - JASS)//
//     Congratulations, the System is now implemented in your map          //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           How to Use?                                                   //
//                                                                         //
//  1. There are many Examples of use in the KB3D Example Folder           //
//  2. Documentations are there in the Features Triggers to help you       //
//  3. The KB3D System is an Ultra-Purpose System where you can use it for://
//     -Projectiles, the system supports homing so a projectile is easy    //
//     -Jump, the System's smoothness in the fly is useful for a jump spell//
//     -And of course, a 2D Knock-Back                                     //
//     -And More depending on your imagination                             //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           Bug Reports - Feedbacks                                       //
//                                                                         //
//  * We count on you to report bugs in the system, also telling the source//
//  * Feedbacks about the system are much appreciated                      //
//  * We mostly hope suggestions about enhancements for the System         //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

function KB3D_AlwaysNeg takes real R returns real
    if R > 0 then
        return -R
    endif
    return R
endfunction

function KB3D_InBetween takes real Min, real R, real Max returns real
    return RMaxBJ(RMinBJ(R, Max), Min)
endfunction

function KB3D_IsInBetween takes real Min, real R, real Max returns boolean
    return R > Min and R < Max
endfunction

function KB3D_CW_Loop takes nothing returns nothing
    if IsItemVisible(GetEnumItem()) then
        set udg_CP_HiddenItems[udg_CP_HiddenItemsIndex] = GetEnumItem()
        call SetItemVisible(udg_CP_HiddenItems[udg_CP_HiddenItemsIndex], false)
        set udg_CP_HiddenItemsIndex = ( udg_CP_HiddenItemsIndex + 1 )
    endif
endfunction

function KB3D_CW takes real x, real y returns boolean
    local real x2 = 0
    local real y2 = 0
    //---------------------------
    call MoveRectTo(udg_CP_Rect, x, y)
    call EnumItemsInRect(udg_CP_Rect, null, function KB3D_CW_Loop )
    call SetItemPosition(udg_CP_Item, x, y)
    set x2 = GetItemX(udg_CP_Item)
    set y2 = GetItemY(udg_CP_Item)
    call SetItemVisible(udg_CP_Item, false)
    //---------------------------
    loop
        exitwhen udg_CP_HiddenItemsIndex == 0
        set udg_CP_HiddenItemsIndex = udg_CP_HiddenItemsIndex - 1
        call SetItemVisible(udg_CP_HiddenItems[udg_CP_HiddenItemsIndex], true)
        set udg_CP_HiddenItems[udg_CP_HiddenItemsIndex] = null
    endloop
    //---------------------------
    return (((x2-x)*(x2-x) + (y2-y)*(y2-y) <= 75) and (not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY)))
endfunction

function KB3D_GetCoordinatesZ takes real x, real y returns real
    local location L = Location(x,y)
    local real r = 0
    local integer I = 0
    local integer t = 12
    local boolean B = true
    loop
    exitwhen I == 12
        if GetPlayerSlotState(Player(I)) != ConvertPlayerSlotState(1) then
            set t = t - 1
        else
            if IsLocationFoggedToPlayer( L , Player(I)) then
                set B = false
                set t = t - 1
            endif
        endif
        set I = I + 1
    endloop
    if B or t == 0 then
        set r = GetLocationZ(L)
    endif
    call RemoveLocation(L)
    set L = null
    return r
endfunction

function KB3D_Approx takes unit U, unit U2, integer Loop returns boolean
    local real r = KB3D_InBetween(50, LoadReal(udg_KB3D_HA, 29, Loop) / 2, 1000)
    local real r1 = GetUnitFlyHeight(U2)
    //---------------------------
    return KB3D_IsInBetween(r1-r, GetUnitFlyHeight(U), r1+r)
endfunction

function KB3D_Filter takes unit U, unit U1, integer Loop returns boolean
    if not IsUnitType(U, UNIT_TYPE_DEAD) then
    //---------------------------
        if not(LoadBoolean(udg_KB3D_HA, 48, Loop)) and ( IsUnitType(U, UNIT_TYPE_STRUCTURE)) then
            return false
        elseif not((LoadBoolean(udg_KB3D_HA, 48, Loop)) and ( IsUnitType(U, UNIT_TYPE_STRUCTURE))) then
            if not(LoadBoolean(udg_KB3D_HA, 49, Loop)) and ( IsUnitType(U, UNIT_TYPE_MECHANICAL)) then
                return false
            endif
        endif
    //---------------------------
        if not(LoadBoolean(udg_KB3D_HA, 50, Loop)) and ( IsUnitType(U, UNIT_TYPE_MAGIC_IMMUNE)) then
            return false
        endif
    //---------------------------
        if not(LoadBoolean(udg_KB3D_HA, 51, Loop)) and ( IsUnitAlly(U, GetOwningPlayer(U1))) then
            return false
        endif
    //---------------------------
        if not(LoadBoolean(udg_KB3D_HA, 63, Loop)) and ( IsUnitEnemy(U, GetOwningPlayer(U1))) then
            return false
        endif
    //---------------------------
        if not(LoadBoolean(udg_KB3D_HA, 64, Loop)) and ( IsUnitType(U, UNIT_TYPE_RESISTANT)) then
            return false
        endif
    //---------------------------
        if not(LoadBoolean(udg_KB3D_HA, 65, Loop)) and ( IsUnitType(U, UNIT_TYPE_FLYING)) then
            return false
        endif
    //---------------------------
        return true
    endif
    //---------------------------
    return false
endfunction

function KB3D_RegisterUnitCollision takes unit u, real x, real y, integer i returns real
    local real l = 0
    local real h = 300
    local real m = 150
    local real nm
    //---------------------------
    loop
        if (IsUnitInRangeXY(u, x+m, y, 0)) then
            set l = m
        else
            set h = m
        endif
        set nm = (l+h)/2
        exitwhen nm+.001 >  m and nm-.001 < m
        set m = nm
    endloop
    //---------------------------
    set m = R2I(m*10)/10.
    call SaveReal( udg_KB3D_HA, 16, GetUnitTypeId(u), m )
    //---------------------------
    return m
endfunction

function KB3D_GetUnitCollision takes unit u returns real
    local integer i = GetUnitTypeId(u)
    //---------------------------
    if HaveSavedReal( udg_KB3D_HA, 16, i) then
        return LoadReal(udg_KB3D_HA, 16, i)
    endif
    //---------------------------
    return KB3D_RegisterUnitCollision(u, GetUnitX(u), GetUnitY(u), i)
endfunction

function KB3D_Tree_Check takes destructable D returns boolean
    return IssueTargetOrderById( udg_KB3D_Harvester, 852018, D ) and IssueImmediateOrderById(udg_KB3D_Harvester, 851972)
endfunction

function KB3D_KillEnumDest takes nothing returns nothing
    local destructable D = GetEnumDestructable()
    //---------------------------
    if GetDestructableLife(D)>0 and ( KB3D_Tree_Check(D) ) and (GetUnitFlyHeight(LoadUnitHandle(udg_KB3D_HA, 0, R2I(udg_KB3D_Reals[0]))) < GetDestructableOccluderHeight(D)) and LoadBoolean(udg_KB3D_HA, 8, R2I(udg_KB3D_Reals[0])) then
        call KillDestructable(D)
    elseif /*not(KB3D_CW(GetDestructableX(D),GetDestructableY(D))) and*/ GetDestructableLife(D)>0 and not(KB3D_Tree_Check(D)) and LoadBoolean(udg_KB3D_HA, 56, R2I(udg_KB3D_Reals[0])) then
        call KillDestructable(D)
    endif
    set D = null
endfunction

function KB3D_CircleTreeKill takes real radius, real x, real y returns nothing
    local rect r = Rect(x-radius, y-radius, x+radius, y+radius)
    //---------------------------
    call EnumDestructablesInRect(r, null, function KB3D_KillEnumDest)
    //---------------------------
    call RemoveRect(r)
    set r = null
endfunction

function KB3D_BounceOnUnit takes unit u, unit U, integer Loop returns nothing
    set udg_KB3D_Angle = (Atan2(GetUnitY(u) - GetUnitY(U), GetUnitX(u) - GetUnitX(U)) *57.29578) + GetRandomReal(-15,15)
    set udg_KB3D_Speed = LoadReal(udg_KB3D_HA, 2, Loop) / .03125 * .25 * LoadReal(udg_KB3D_HA, 59, Loop)
    set udg_KB3D_DestroyTree = LoadBoolean(udg_KB3D_HA, 8, Loop)
    set udg_KB3D_Fx = LoadStr(udg_KB3D_HA, 9, Loop)
    set udg_KB3D_Attach = LoadStr(udg_KB3D_HA, 10, Loop)
    set udg_KB3D_Range = 1.5*udg_KB3D_Speed*udg_KB3D_Bounce_Power
    set udg_KB3D_Unit = u
    set udg_KB3D_Bounce_Fx = LoadStr(udg_KB3D_HA, 62, Loop)
    set udg_KB3D_Accel = -udg_KB3D_Speed*.6
    set udg_KB3D_Bounce_Unit = true
    call TriggerEvaluate(udg_KB3D_Registration)
    call SaveEffectHandle(udg_KB3D_HA, 14, udg_KB3D_Counter, LoadEffectHandle(udg_KB3D_HA, 14, Loop))
endfunction

function KB3D_Bounce_Filter takes nothing returns boolean
    local boolean b = not(IsUnitInGroup(GetFilterUnit(), LoadGroupHandle(udg_KB3D_HA, 68, R2I(udg_KB3D_Reals[0])))) or KB3D_Filter(LoadUnitHandle(udg_KB3D_HA, 0, R2I(udg_KB3D_Reals[0])),LoadUnitHandle(udg_KB3D_HA, 0, R2I(udg_KB3D_Reals[0])),R2I(udg_KB3D_Reals[0]))
    if b then
        call GroupAddUnit(LoadGroupHandle(udg_KB3D_HA, 68, R2I(udg_KB3D_Reals[0])), GetFilterUnit())
    endif
    return b
endfunction

function KB3D_FilterGrp takes nothing returns boolean
    return KB3D_Filter(GetFilterUnit(), LoadUnitHandle(udg_KB3D_HA, 0, R2I(udg_KB3D_Reals[0])),R2I(udg_KB3D_Reals[0]))
endfunction

function KB3D_ClearInstance takes integer i returns nothing
    local integer x = 0
    //---------------------------
    call DestroyGroup(LoadGroupHandle(udg_KB3D_HA, 27, i))
    call DestroyGroup(LoadGroupHandle(udg_KB3D_HA, 67, i))
    //---------------------------
    loop
        exitwhen x > 100
        call RemoveSavedHandle(udg_KB3D_HA, x, i)
        call SaveReal(udg_KB3D_HA, x, i, 0)
        set x = x +1
    endloop
endfunction

function KB3D_isPossiblePathability takes real x, real y, real RADangle, real MaxDist returns boolean
    local real X = x
    local real Y = y
    local real max = RAbsBJ(MaxDist)
    local real dist = max
    //---------------------------
    loop
        exitwhen (dist <= 0)
        set dist = dist - max/300
        set X = x + ( dist * Cos(RADangle) )
        set Y = y + ( dist * Sin(RADangle) )
        if KB3D_CW(X,Y) then
            return true
        endif
    endloop
    //---------------------------
    return false
endfunction

function MoveUnit_3D takes unit U, real x, real y, real z, real MaxZ, boolean P, boolean OS, boolean KiOS, real Angle, real S, real time, integer Loop returns boolean
    local boolean B = false
    local boolean b = true
    local real tz
    // CREEPY FUNCTION ALERT
    if LoadBoolean(udg_KB3D_HA, 57, Loop) then
        if LoadBoolean(udg_KB3D_HA, 44, Loop) then
            set tz = KB3D_GetCoordinatesZ(x,y) - LoadReal(udg_KB3D_HA, 68, Loop)
            set z = z - tz
            call SaveReal(udg_KB3D_HA, 68, Loop, KB3D_GetCoordinatesZ(x,y))
            if LoadReal(udg_KB3D_HA, 3, Loop)<0 and GetUnitDefaultFlyHeight(U)<z then
                call SetUnitFlyHeight(U, KB3D_InBetween(-999,z,GetUnitDefaultFlyHeight(U)), 0)
            else
                call SetUnitFlyHeight(U, z, 0)
            endif
        else
            call SetUnitFlyHeight(U, KB3D_InBetween(GetUnitDefaultFlyHeight(U), z, 9999), 0)
        endif
    endif
    //---------------------------
    if ( not(P) or ( KB3D_CW(x, y) ) ) then
        set B = true
        if (OS) then
            call SetUnitX(U, KB3D_InBetween(udg_KB3D_Reals[6], x, udg_KB3D_Reals[5]))
            call SetUnitY(U, KB3D_InBetween(udg_KB3D_Reals[8], y, udg_KB3D_Reals[7]))
            set b = false
            if (KiOS) and (not(KB3D_IsInBetween(udg_KB3D_Reals[2], x, udg_KB3D_Reals[1])) or not(KB3D_IsInBetween(udg_KB3D_Reals[4], x, udg_KB3D_Reals[3]))) then
                call KillUnit(U)
            endif
        else
            call SetUnitX(U, KB3D_InBetween(udg_KB3D_Reals[2], x, udg_KB3D_Reals[1]))
            call SetUnitY(U, KB3D_InBetween(udg_KB3D_Reals[4], y, udg_KB3D_Reals[3]))
            set b = false
        endif
    elseif LoadBoolean(udg_KB3D_HA, 52, Loop) and P and not(KB3D_CW(x, y)) then
        if GetUnitFlyHeight(U) != 0 then
            if KB3D_isPossiblePathability(GetUnitX(U),GetUnitY(U), Angle, S*time/0.03125) and LoadBoolean(udg_KB3D_HA, 44, Loop) then
                set B = true
                //call SaveBoolean(udg_KB3D_HA, 53, Loop, true)
                if (OS) then
                    call SetUnitX(U, KB3D_InBetween(udg_KB3D_Reals[6], x, udg_KB3D_Reals[5]))
                    call SetUnitY(U, KB3D_InBetween(udg_KB3D_Reals[8], y, udg_KB3D_Reals[7]))
                    set b = false
                    if (KiOS) and (not(KB3D_IsInBetween(udg_KB3D_Reals[2], x, udg_KB3D_Reals[1])) or not(KB3D_IsInBetween(udg_KB3D_Reals[4], x, udg_KB3D_Reals[3]))) then
                        call KillUnit(U)
                    endif
                else
                    call SetUnitX(U, KB3D_InBetween(udg_KB3D_Reals[2], x, udg_KB3D_Reals[1]))
                    call SetUnitY(U, KB3D_InBetween(udg_KB3D_Reals[4], y, udg_KB3D_Reals[3]))
                    set b = false
                endif
            else
                call SaveBoolean(udg_KB3D_HA, 52, Loop, false)
            endif
        else
        endif
    endif
    if b then
        set udg_KB3D_B = true
        if LoadBoolean(udg_KB3D_HA, 66, Loop) then
            set udg_KB3D_EndisUnpathable = true
            set udg_KB3D_EndisNormal = false
            return true
        endif
    endif
    return false
endfunction

function KB3D_LineDamageLoop takes unit U, group g returns nothing
    local integer Loop = R2I(udg_KB3D_Reals[0])
    local unit Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
    local attacktype AType = ConvertAttackType(LoadInteger(udg_KB3D_HA, 20, Loop))
    local damagetype DType = ConvertDamageType(LoadInteger(udg_KB3D_HA, 21, Loop))
    local real LineD = LoadReal(udg_KB3D_HA, 28, Loop)
    local unit U1 = LoadUnitHandle(udg_KB3D_HA, 0, Loop)
    local group G = LoadGroupHandle(udg_KB3D_HA, 27, Loop)
    //---------------------------
    if KB3D_Filter(U, U1, Loop) and not ( IsUnitInGroup(U, G) ) then
        call GroupAddUnit(G, U)
        if not(LoadBoolean(udg_KB3D_HA, 44, Loop)) then
            call UnitDamageTarget(Damager, U, LineD, true, false, AType, DType, null)
            call DestroyEffect(AddSpecialEffectTarget(LoadStr(udg_KB3D_HA, 58, Loop), U, LoadStr(udg_KB3D_HA, 10, Loop)))
        elseif KB3D_Approx(U, U1, Loop) then
            call UnitDamageTarget(Damager, U, LineD, true, false, AType, DType, null)
            call DestroyEffect(AddSpecialEffectTarget(LoadStr(udg_KB3D_HA, 58, Loop), U, LoadStr(udg_KB3D_HA, 10, Loop)))
        endif
    endif
    //---------------------------
    set G = null
    set U1 = null
    set Damager = null
    set AType = null
    set DType = null
endfunction

function KB3D_AoEDamageLoop takes unit U, group g returns nothing
    local integer Loop = R2I(udg_KB3D_Reals[0])
    local unit Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
    local attacktype AType = ConvertAttackType(LoadInteger(udg_KB3D_HA, 20, Loop))
    local damagetype DType = ConvertDamageType(LoadInteger(udg_KB3D_HA, 21, Loop))
    local real AoED = LoadReal(udg_KB3D_HA, 32, Loop)
    local unit U1 = LoadUnitHandle(udg_KB3D_HA, 0, Loop)
    //---------------------------
    if KB3D_Filter(U, U1, Loop) then
        if not(LoadBoolean(udg_KB3D_HA, 44, Loop)) then
            call UnitDamageTarget(Damager, U, AoED * 0.031250000, true, false, AType, DType, null)
        elseif KB3D_Approx(U, U1, Loop) then
            call UnitDamageTarget(Damager, U, AoED * 0.031250000, true, false, AType, DType, null)
        endif
    endif
    //---------------------------
    set U1 = null
    set Damager = null
    set AType = null
    set DType = null
endfunction

function KB3D_AoEEndDamage takes unit U, group g returns nothing
    local integer Loop = R2I(udg_KB3D_Reals[0])
    local unit Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
    local attacktype AType = ConvertAttackType(LoadInteger(udg_KB3D_HA, 20, Loop))
    local damagetype DType = ConvertDamageType(LoadInteger(udg_KB3D_HA, 21, Loop))
    local real D = LoadReal(udg_KB3D_HA, 38, Loop)
    local unit U1 = LoadUnitHandle(udg_KB3D_HA, 0, Loop)
    //---------------------------
    if KB3D_Filter(U, U1, Loop) then
        if not(LoadBoolean(udg_KB3D_HA, 44, Loop)) then
            call UnitDamageTarget(Damager, U, D, true, false, AType, DType, null)
        elseif KB3D_Approx(U, U1, Loop) then
            call UnitDamageTarget(Damager, U, D, true, false, AType, DType, null)
        endif
    endif
    //---------------------------
    call GroupRemoveUnit(g, U)
    //---------------------------
    set U1 = null
    set Damager = null
    set AType = null
    set DType = null
endfunction

function KB3D_GiveKBto takes unit U1, unit U2, integer Loop returns nothing
    set udg_KB3D_AoEEndDamage = LoadReal(udg_KB3D_HA, 38, Loop)
    set udg_KB3D_EndwhenDead = LoadBoolean(udg_KB3D_HA, 35, Loop)
    set udg_KB3D_Speed = LoadReal(udg_KB3D_HA, 2, Loop)/0.031250000*.5
    set udg_KB3D_Accel = -udg_KB3D_Speed
    set udg_KB3D_AllowOutSiding = LoadBoolean(udg_KB3D_HA, 34, Loop)
    set udg_KB3D_Angle = (LoadReal(udg_KB3D_HA, 5, Loop)*180/3.14159)
    set udg_KB3D_AoE = LoadReal(udg_KB3D_HA, 29, Loop)
    set udg_KB3D_AoEDamage = LoadReal(udg_KB3D_HA, 32, Loop)
    set udg_KB3D_AttackType = ConvertAttackType(LoadInteger(udg_KB3D_HA, 20, Loop))
    set udg_KB3D_DamageType = ConvertDamageType(LoadInteger(udg_KB3D_HA, 21, Loop))
    set udg_KB3D_Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
    set udg_KB3D_DestroyTree = LoadBoolean(udg_KB3D_HA, 8, Loop)
    set udg_KB3D_DisableUnit = LoadBoolean(udg_KB3D_HA, 6, Loop)
    set udg_KB3D_FaceAngle = LoadBoolean(udg_KB3D_HA, 31, Loop)
    set udg_KB3D_Fx = LoadStr(udg_KB3D_HA, 9, Loop)
    set udg_KB3D_Attach = LoadStr(udg_KB3D_HA, 10, Loop)
    set udg_KB3D_ImpactDamage = LoadReal(udg_KB3D_HA, 17, Loop)
    set udg_KB3D_LineDamage = LoadReal(udg_KB3D_HA, 28, Loop)
    set udg_KB3D_LoopDamage = LoadReal(udg_KB3D_HA, 18, Loop)/0.031250000
    set udg_KB3D_Range = 99999
    set udg_KB3D_Unit = U1
    if LoadBoolean(udg_KB3D_HA, 57, Loop) then
        set udg_KB3D_Zoffset = LoadReal(udg_KB3D_HA, 3, Loop)/1.85 - GetUnitDefaultFlyHeight(U2)
    endif
    //---------------------------
    call TriggerEvaluate( udg_KB3D_Registration )
endfunction

function KB3D_AoEGiveKBto takes unit U1, unit U2, integer Loop returns nothing
    local real x1 = GetUnitX(U1)
    local real y1 = GetUnitY(U1)
    local real x2 = GetUnitX(U2)
    local real y2 = GetUnitY(U2)
    local real P = LoadReal(udg_KB3D_HA, 43, Loop)
    //---------------------------
    set udg_KB3D_AoE = LoadReal(udg_KB3D_HA, 29, Loop)
    set udg_KB3D_EndwhenDead = LoadBoolean(udg_KB3D_HA, 35, Loop)
    set udg_KB3D_Accel = -550*P
    set udg_KB3D_AllowOutSiding = LoadBoolean(udg_KB3D_HA, 34, Loop)
    set udg_KB3D_Angle = Atan2(y1 - y2, x1 - x2)*180/3.14159
    set udg_KB3D_AoEDamage = LoadReal(udg_KB3D_HA, 32, Loop)
    set udg_KB3D_AttackType = ConvertAttackType(LoadInteger(udg_KB3D_HA, 20, Loop))
    set udg_KB3D_DamageType = ConvertDamageType(LoadInteger(udg_KB3D_HA, 21, Loop))
    set udg_KB3D_Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
    set udg_KB3D_DestroyTree = LoadBoolean(udg_KB3D_HA, 8, Loop)
    set udg_KB3D_DisableUnit = LoadBoolean(udg_KB3D_HA, 6, Loop)
    set udg_KB3D_FaceAngle = LoadBoolean(udg_KB3D_HA, 31, Loop)
    set udg_KB3D_Fx = LoadStr(udg_KB3D_HA, 9, Loop)
    set udg_KB3D_Attach = LoadStr(udg_KB3D_HA, 10, Loop)
    set udg_KB3D_ImpactDamage = LoadReal(udg_KB3D_HA, 17, Loop)
    set udg_KB3D_LineDamage = LoadReal(udg_KB3D_HA, 28, Loop)
    set udg_KB3D_LoopDamage = LoadReal(udg_KB3D_HA, 18, Loop)/0.031250000
    set udg_KB3D_Speed = udg_KB3D_AoE*2*P
    set udg_KB3D_Range = udg_KB3D_Speed*2
    set udg_KB3D_Unit = U1
    if LoadBoolean(udg_KB3D_HA, 57, Loop) then
        set udg_KB3D_Zoffset = (udg_KB3D_AoE - SquareRoot(x2 * x1 + y2 * y1)*3.14159/180)*P
    endif
    //---------------------------
    call TriggerEvaluate( udg_KB3D_Registration )
endfunction

function KB3D_AoEKB takes unit U, group g returns nothing
    local integer Loop = R2I(udg_KB3D_Reals[0])
    local unit U1 = LoadUnitHandle(udg_KB3D_HA, 0, Loop)
    local real r
    //---------------------------
    if KB3D_Filter(U, U1, Loop) then
        if not(LoadBoolean(udg_KB3D_HA, 44, Loop)) then
            call KB3D_AoEGiveKBto(U, U1, Loop)
        elseif KB3D_Approx(U, U1, Loop) then
            call KB3D_AoEGiveKBto(U, U1, Loop)
        endif
    endif
    //---------------------------
    call GroupRemoveUnit(g, U)
    //---------------------------
    set U1 = null
endfunction

function KB3D_AoEEndFx takes unit U, string A, string F, group g returns nothing
    local integer Loop = R2I(udg_KB3D_Reals[0])
    local unit U1 = LoadUnitHandle(udg_KB3D_HA, 0, Loop)
    local real x
    local real y
    //---------------------------
    if KB3D_Filter(U, U1, Loop) and (U != null) then
        if not(LoadBoolean(udg_KB3D_HA, 44, Loop)) then
            if ( GetUnitFlyHeight(U) > 20 ) then
                call DestroyEffect(AddSpecialEffectTarget(F, U, A))
            else
                set x = GetUnitX(U)
                set y = GetUnitY(U)
                call DestroyEffect(AddSpecialEffect(F, x, y))
            endif
        elseif KB3D_Approx(U, U1, Loop) then
            if ( GetUnitFlyHeight(U) > 20 ) then
                call DestroyEffect(AddSpecialEffectTarget(F, U, A))
            else
                set x = GetUnitX(U)
                set y = GetUnitY(U)
                call DestroyEffect(AddSpecialEffect(F, x, y))
            endif
        endif
    endif
    //---------------------------
    call GroupRemoveUnit(g, U)
    //---------------------------
    set U1 = null
endfunction

function KB3D_Grpto takes nothing returns nothing
    call GroupAddUnit(udg_KB3D_g, GetEnumUnit())
endfunction

function KB3D_PointBounce takes real BAngle, real x, real y returns real
    local real BAngle1 //bounce angle 1
    local real BAngle2 //bounce angle 2
    local real q //quadrant
    set BAngle = BAngle*0.01745329251994329576923690768489
   
    if 0<BAngle and BAngle<90 then
        set q = 1
    elseif 90<BAngle and BAngle<180 then
        set q = 2
    elseif 180<BAngle and BAngle<270 then
        set q = 3
    elseif 270<BAngle and BAngle<360 then
        set q = 4
    else
        set q = BAngle/90 + 2
    endif
   
    set BAngle1 = q*90 - BAngle
    set BAngle2 = - q*90 + BAngle + 90
   
    if KB3D_isPossiblePathability(x, y, (BAngle - 2*BAngle2), 40) then
        set BAngle = BAngle - 2*BAngle2
    elseif KB3D_isPossiblePathability(x, y, (BAngle + 2*BAngle1), 40) then
        set BAngle = BAngle + 2*BAngle1
    endif
   
    return BAngle
endfunction

function KB3D_Flyover takes real Zi, real Zf, real Yi, real Yf, real Xi, real Xf, real Speed, real dur, integer Loop returns nothing
    local location Li = Location(Xi, Yi)
    local location Lf = Location(Xf, Yf)
    local real Xmax = Speed/0.03125*dur
    local real Ymax = (GetLocationZ(Lf) - GetLocationZ(Li))*GetLocationZ(Lf)/Speed*Xmax ////BEWARE LOCATIONZ
   
    if (GetLocationZ(Lf) - GetLocationZ(Li)) > 0.5 then
        call SaveReal( udg_KB3D_HA, 74, Loop, GetLocationZ(Li) )
        call BJDebugMsg("Sup")
    elseif (GetLocationZ(Lf) - GetLocationZ(Li)) < -0.5 then
        set Ymax = -(GetLocationZ(Lf) - LoadReal( udg_KB3D_HA, 74, Loop))*GetLocationZ(Lf)/Speed*Xmax
        call SaveBoolean( udg_KB3D_HA, 75, Loop, false)
        call BJDebugMsg(R2S(Ymax))
    endif
endfunction

function KB3D_Loop takes integer Loop returns nothing
    //Create all the nessesary locals
    local unit U = LoadUnitHandle(udg_KB3D_HA, 0, Loop)
    local real X = GetUnitX(U)
    local real Y = GetUnitY(U)
    local real Z = GetUnitFlyHeight(U)
    local real x = X
    local real y = Y
    local real z = Z
    local real Range = LoadReal(udg_KB3D_HA, 1, Loop)
    local real Speed = LoadReal(udg_KB3D_HA, 2, Loop)
    local real Zoffset = LoadReal(udg_KB3D_HA, 3, Loop)
    local real Accel = LoadReal(udg_KB3D_HA, 4, Loop)
    local real Angle
    local real ZSpeed = LoadReal(udg_KB3D_HA, 12, Loop)
    local real ZAccel = LoadReal(udg_KB3D_HA, 13, Loop)
    local real ImpactD = LoadReal(udg_KB3D_HA, 17, Loop)
    local real LoopD = LoadReal(udg_KB3D_HA, 18, Loop)
    local real TargetD = LoadReal(udg_KB3D_HA, 19, Loop)
    local real LineD = LoadReal(udg_KB3D_HA, 28, Loop)
    local real AoE = LoadReal(udg_KB3D_HA, 29, Loop)
    local real ZT = LoadReal(udg_KB3D_HA, 26, Loop)
    local real AoED = LoadReal(udg_KB3D_HA, 32, Loop)
    local real Time = LoadReal(udg_KB3D_HA, 41, Loop) + 0.031250000
    local real KillatTime = LoadReal(udg_KB3D_HA, 36, Loop)
    local real StopTime = LoadReal(udg_KB3D_HA, 37, Loop)
    local real AoEEndDamage = LoadReal(udg_KB3D_HA, 38, Loop)
    local real Flyover_dur = LoadReal(udg_KB3D_HA, 73, Loop)
    local unit Target = LoadUnitHandle(udg_KB3D_HA, 5, Loop)
    local unit Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
    local unit u
    local boolean DisableUnit = LoadBoolean(udg_KB3D_HA, 6, Loop)
    local boolean UnpathableStop = LoadBoolean(udg_KB3D_HA, 7, Loop)
    local boolean DestroyTree = LoadBoolean(udg_KB3D_HA, 8, Loop)
    local boolean KillWhenHit = LoadBoolean(udg_KB3D_HA, 24, Loop)
    local boolean EndWhenHit = LoadBoolean(udg_KB3D_HA, 25, Loop)
    local boolean KiOS = LoadBoolean(udg_KB3D_HA, 33, Loop)
    local boolean OS = LoadBoolean(udg_KB3D_HA, 34, Loop)
    local boolean b = true
    local boolean EndwhenDead = LoadBoolean(udg_KB3D_HA, 35, Loop)
    local boolean KBTarget = LoadBoolean(udg_KB3D_HA, 39, Loop)
    local boolean AoEKB = LoadBoolean(udg_KB3D_HA, 40, Loop)
    local boolean KillatEnd = LoadBoolean(udg_KB3D_HA, 46, Loop)
    local boolean GroundDamage = LoadBoolean(udg_KB3D_HA, 47, Loop)
    local boolean EndB = false
    local boolean EndOnObstacle = false
    local boolean Flyover = LoadBoolean(udg_KB3D_HA, 72, Loop)
    local string Fx = LoadStr(udg_KB3D_HA, 9, Loop)
    local string Attach = LoadStr(udg_KB3D_HA, 10, Loop)
    local string EndFx = LoadStr(udg_KB3D_HA, 42, Loop)
    local string AoEEndFx = LoadStr(udg_KB3D_HA, 54, Loop)
    local attacktype AType = ConvertAttackType(LoadInteger(udg_KB3D_HA, 20, Loop))
    local damagetype DType = ConvertDamageType(LoadInteger(udg_KB3D_HA, 21, Loop))
    local trigger EndT = LoadTriggerHandle(udg_KB3D_HA, 55, Loop)
    //end of locals
  
    //Loop Damage Execution
    if LoopD != 0 and Damager != null then
        call UnitDamageTarget(Damager, U, LoopD, true, false, AType, DType, null)
    endif
  
    //Calculate the Angle
    if ( Target == null ) then
        set Angle = LoadReal(udg_KB3D_HA, 5, Loop) + LoadReal(udg_KB3D_HA, 30, Loop)//if there is no unit target
    else
        set Angle = Atan2(GetUnitY(Target) - Y, GetUnitX(Target) - X)//if there is a unit target
    endif
    //
    if LoadBoolean(udg_KB3D_HA, 16, Loop) then
        set Angle = GetUnitFacing(U)*0.0174533
        if LoadBoolean(udg_KB3D_HA, 44, Loop) then
            if GetUnitCurrentOrder(U) != 851986 and GetUnitCurrentOrder(U) != 851971 then
                set b = false
            endif
        else
            set b = false
        endif
    endif
   
    //Make Unit Face Angle
    if LoadBoolean(udg_KB3D_HA, 31, Loop) then
        call SetUnitFacing(U, Angle * 3.141592)
    endif
  
    //Calculate 3D coordinates
    if b then
        set Speed = Speed + ( Accel )//Increase the KB speed depending on the Acceleration
        set Range = Range - ( RAbsBJ(Speed) )//Decrease distance traveled
        set x = X + ( Speed * Cos(Angle) )//new X location of the KBed unit
        set y = Y + ( Speed * Sin(Angle) )//new Y location of the KBed unit
        set ZSpeed = ZSpeed + ( ZAccel )//change the fly changing rate //Acceleration is for smoothness
        set z = Z + ( ZSpeed * 0.031250000 )//new Z Offset of the KBed unit
        set ZT = ZT + ( ZSpeed * 0.031250000 )//Total Height Changings
    endif
    set b = false
   
    if z >= Zoffset then
        call SaveReal(udg_KB3D_HA, 12, Loop, -ZSpeed)
    endif
   
    //Flyover Feature
    //if Flyover then
    //    if LoadBoolean(udg_KB3D_HA, 75, Loop) then
    //        if z-LoadReal(udg_KB3D_HA, 71, Loop) <= 0 and (Speed/0.03125*Flyover_dur) <= Range then
    //            call KB3D_Flyover(Z, z, Y, y, X, x, Speed, Flyover_dur, Loop)
    //        endif
    //    endif
    //endif
   
    //Destroy Trees around the Unit depending on the unit's Collision Size
    if (DestroyTree) or (LoadBoolean(udg_KB3D_HA, 56, Loop)) then
        set udg_KB3D_Reals[0] = I2R(Loop)
        call KB3D_CircleTreeKill( KB3D_InBetween(2*Speed, 5 * KB3D_GetUnitCollision(U), Speed*4), x, y )
    endif
   
    //Move the unit according to the X, Y, Z
    set EndOnObstacle = MoveUnit_3D(U, x, y, z, Zoffset, UnpathableStop, OS, KiOS, Angle, Speed, LoadReal(udg_KB3D_HA, 11, Loop)-Time, Loop)
   
    //Bounce on Point
    if udg_KB3D_B and LoadBoolean(udg_KB3D_HA, 60, Loop) then
        set udg_KB3D_B = false
        set Speed=Speed*.85
        set Angle = KB3D_PointBounce(Angle,x,y)
        if LoadReal(udg_KB3D_HA, 76, Loop) <= 0 then
            call DestroyEffect(AddSpecialEffect(LoadStr(udg_KB3D_HA, 62, Loop), GetUnitX(U), GetUnitY(U)))
            call SaveReal(udg_KB3D_HA, 76, Loop, 10)
        endif
    endif
  
    //Create the Effect on the unit
    if (Fx != "") then
        if ( z > 20 ) then
            if (Attach != "") then
                call DestroyEffect(AddSpecialEffectTarget(Fx, U, Attach))//attach the effect on the unit if he is flying
            endif
        else
            call DestroyEffect(AddSpecialEffect(Fx, x, y))//create the effect on his location if he is not flying
        endif
    endif
  
    //Initiate Impact Damage
    if ( (UnpathableStop) and not ( KB3D_CW(x, y) ) ) and ( (ImpactD != 0) and (Damager != null ) ) then//if the terrain is unpathable or if unpathable stop is disabled then..
        if ( KB3D_CW(x, y) ) then
            call SaveBoolean(udg_KB3D_HA, 23, Loop, true)
        endif
        if ( LoadBoolean(udg_KB3D_HA, 23, Loop) ) then
            call UnitDamageTarget(Damager, U, ImpactD, true, false, AType, DType, null)//Apply Impact Damage to the unit
            call SaveBoolean(udg_KB3D_HA, 23, Loop, false)
        endif
    endif
   
    //Create AoE Grp
    if (AoE != 0) and ((LineD != 0) or (AoED != 0) or LoadBoolean(udg_KB3D_HA, 61, Loop) or LoadBoolean(udg_KB3D_HA, 60, Loop)) then
        set udg_KB3D_g = CreateGroup()
        set udg_KB3D_Reals[0] = I2R(Loop)
        call GroupEnumUnitsInRange(udg_KB3D_g, x, y, RAbsBJ(AoE), Filter(function KB3D_FilterGrp))
        //----------------------------------
        loop
            set u = FirstOfGroup(udg_KB3D_g)
            exitwhen (u == null)
            if (Damager != null) then
                if (LineD != 0) then
                    call KB3D_LineDamageLoop(u, udg_KB3D_g)
                endif
                if (AoED != 0) then
                    call KB3D_AoEDamageLoop(u, udg_KB3D_g)
                endif
            endif
            if not IsUnitInGroup(u, LoadGroupHandle(udg_KB3D_HA, 67, Loop)) and RAbsBJ(AoE)>SquareRoot((GetUnitX(u) - GetUnitX(U)) * (GetUnitX(u) - GetUnitX(U)) + (GetUnitY(u) - GetUnitY(U)) * (GetUnitY(u) - GetUnitY(U))) then
                if LoadBoolean(udg_KB3D_HA, 61, Loop) then
                    call KB3D_BounceOnUnit(u, U, Loop)
                    call GroupAddUnit(LoadGroupHandle(udg_KB3D_HA, 67, Loop),u)
                    call DestroyEffect(AddSpecialEffect(LoadStr(udg_KB3D_HA, 62, Loop), GetUnitX(u), GetUnitY(u)))
                    if LoadBoolean(udg_KB3D_HA, 70, Loop) then
                        set b = true
                        set udg_KB3D_EndisUnit = true
                        set udg_KB3D_EndisNormal = false
                        set udg_KB3D_EndUnit = u
                    endif
                endif
                if LoadBoolean(udg_KB3D_HA, 60, Loop) then
                    set Angle = (Atan2(GetUnitY(u) - GetUnitY(U), GetUnitX(u) - GetUnitX(U))) + Deg2Rad(GetRandomReal(-15,15) + 180)
                    set Speed = Speed*.85
                    call DestroyEffect(AddSpecialEffect(LoadStr(udg_KB3D_HA, 62, Loop), GetUnitX(U), GetUnitY(U)))
                endif
            endif
            call GroupRemoveUnit(udg_KB3D_g,u)
        endloop
        //----------------------------------
        call DestroyGroup(udg_KB3D_g)
        set udg_KB3D_g = null
    endif
  
    //Disable the unit partially
    if ( DisableUnit ) then
        call SetUnitPropWindow(U, 0)
        call SetUnitTurnSpeed(U, 0)
    endif
  
    //Initiate Target-Related Actions
    if (Target != null) then
        if (SquareRoot ( ( GetUnitX(Target) - x ) * ( GetUnitX(Target) - x ) + ( GetUnitY(Target) - y ) * ( GetUnitY(Target) - y ) ) < Speed+2) then//when the target and the unit are close
            if not (TargetD == 0) and not(Damager == null) then//Damage the Target
                call UnitDamageTarget(Damager, Target, TargetD, true, false, AType, DType, null)
                call SaveReal(udg_KB3D_HA, 19, Loop, 0)
            endif
            if KBTarget then//KB the Target
                call KB3D_GiveKBto(Target, U, Loop)
                call SaveBoolean( udg_KB3D_HA, 39, udg_KB3D_Counter, false )
            endif
            if (KillWhenHit) then//Kill the Unit
                call KillUnit(U)
            endif
            if (EndWhenHit) then//End the KB
                call SaveReal(udg_KB3D_HA, 4, Loop, KB3D_AlwaysNeg(Speed))
                call SaveReal(udg_KB3D_HA, 3, Loop, GetUnitFlyHeight(U) - ZT)
            endif
            set udg_KB3D_EndisUnit = true
            set udg_KB3D_EndisNormal = false
        endif
    endif
  
    //Kill the Unit at the time
    if (KillatTime != 0) and ( Time > KillatTime ) then
        call KillUnit(U)
    endif
  
    //Save Changes in the Hashtable
    call SaveReal(udg_KB3D_HA, 1, Loop, Range)
    call SaveReal(udg_KB3D_HA, 2, Loop, Speed)
    call SaveReal(udg_KB3D_HA, 5, Loop, Angle)
    call SaveReal(udg_KB3D_HA, 12, Loop, ZSpeed)
    call SaveReal(udg_KB3D_HA, 26, Loop, ZT)
    call SaveReal(udg_KB3D_HA, 41, Loop, Time)
    call SaveReal(udg_KB3D_HA, 76, Loop, LoadReal(udg_KB3D_HA, 76, Loop)-1)
   
    //Inititate End of the KB
    if ( b or (LoadBoolean(udg_KB3D_HA, 45, Loop) and (Speed <= 2.34)) or ( Range <= 0 ) or ( (StopTime != 0) and ( Time > StopTime ) ) or EndOnObstacle ) then
        call SaveBoolean(udg_KB3D_HA, 100, Loop, false)
        set udg_KB3D_Instances = udg_KB3D_Instances - 1
        if IsUnitType(U, UNIT_TYPE_DEAD) then
            call SetUnitFlyHeight(U, GetUnitDefaultFlyHeight(U), 750 )
        endif
        call SetUnitPropWindow(U, LoadReal(udg_KB3D_HA, 15, Loop)*3.14159/180)
        call SetUnitTurnSpeed(U, GetUnitDefaultTurnSpeed(U))
        if HaveSavedHandle(udg_KB3D_HA, 14, Loop) and not EndB then
            call DestroyEffect(LoadEffectHandle(udg_KB3D_HA, 14, Loop))
        endif
        set b = true
    elseif IsUnitType(U, UNIT_TYPE_DEAD) and (EndwhenDead) then
        call SaveBoolean(udg_KB3D_HA, 100, Loop, false)
        set udg_KB3D_Instances = udg_KB3D_Instances - 1
        if IsUnitType(U, UNIT_TYPE_DEAD) then
            call SetUnitFlyHeight(U, GetUnitDefaultFlyHeight(U), 750 )
        endif
        call SetUnitPropWindow(U, LoadReal(udg_KB3D_HA, 15, Loop)*3.14159/180)
        call SetUnitTurnSpeed(U, GetUnitDefaultTurnSpeed(U))
        if HaveSavedHandle(udg_KB3D_HA, 14, Loop) and not EndB then
            call DestroyEffect(LoadEffectHandle(udg_KB3D_HA, 14, Loop))
        endif
        set b = true
    endif
  
    //variable b refers to if the KB has ended
   
    if b then
        call SetUnitFlyHeight(U, GetUnitFlyHeight(U)-KB3D_InBetween(0,ZT-LoadReal(udg_KB3D_HA, 71, Loop),999), 500)
        if LoadBoolean(udg_KB3D_HA, 44, Loop) then
            call SetUnitFlyHeight(U, GetUnitFlyHeight(U)-KB3D_InBetween(0,(LoadReal(udg_KB3D_HA, 69, Loop)-KB3D_GetCoordinatesZ(x,y)),9999), RAbsBJ(ZSpeed))
        endif
        //----------
        call SaveInteger(udg_KB3D_HA, -5, GetHandleId(U), LoadInteger(udg_KB3D_HA, -5, GetHandleId(U))-1)
        if LoadInteger(udg_KB3D_HA, -5, GetHandleId(udg_KB3D_Unit)) == 0 then
            call SaveBoolean(udg_KB3D_HA, GetHandleId(U), GetHandleId(U), false)
        endif
        //----------
        if (AoEEndDamage != 0) and (Damager != null) and (AoE != 0) then
            set udg_KB3D_g = CreateGroup()
            set udg_KB3D_Reals[0] = I2R(Loop)
            call GroupEnumUnitsInRange(udg_KB3D_g, x, y, RAbsBJ(AoE), null)
            loop
                set u = FirstOfGroup(udg_KB3D_g)
                call KB3D_AoEEndDamage(u, udg_KB3D_g)
                exitwhen (u == null)
            endloop
            call DestroyGroup(udg_KB3D_g)
            set udg_KB3D_g = null
        endif
        //----------
        if (AoEKB) and (AoE != 0) then
            set udg_KB3D_g = CreateGroup()
            set udg_KB3D_Reals[0] = I2R(Loop)
            call GroupEnumUnitsInRange(udg_KB3D_g, x, y, RAbsBJ(AoE), null)
            loop
                set u = FirstOfGroup(udg_KB3D_g)
                call KB3D_AoEKB(u, udg_KB3D_g)
                exitwhen (u == null)
            endloop
            call DestroyGroup(udg_KB3D_g)
            set udg_KB3D_g = null
        endif
        //----------
        if (EndFx != "") then
            if ( z > 20 ) and (Attach != "") then
                call DestroyEffect(AddSpecialEffectTarget(EndFx, U, Attach))//attach the effect on the unit if he is flying
            else
                call DestroyEffect(AddSpecialEffect(EndFx, x, y))//create the effect on his location if he is not flying
            endif
        endif
        //----------
        if (AoEEndFx != "") and (Attach != "") and (AoE > 0) then
            set udg_KB3D_g = CreateGroup()
            set udg_KB3D_Reals[0] = I2R(Loop)
            call GroupEnumUnitsInRange(udg_KB3D_g, x, y, RAbsBJ(AoE), null)
            loop
                set u = FirstOfGroup(udg_KB3D_g)
                call KB3D_AoEEndFx(u, Attach, AoEEndFx, udg_KB3D_g)
                exitwhen (u == null)
           endloop
            call DestroyGroup(udg_KB3D_g)
            set udg_KB3D_g = null
        endif
        //----------
        if (AoEEndFx != "") and (Attach != "") and (AoE > 0) then
            set udg_KB3D_g = CreateGroup()
            set udg_KB3D_Reals[0] = I2R(Loop)
            call GroupEnumUnitsInRange(udg_KB3D_g, x, y, RAbsBJ(AoE), null)
            loop
                set u = FirstOfGroup(udg_KB3D_g)
                call KB3D_AoEEndFx(u, Attach, AoEEndFx, udg_KB3D_g)
                exitwhen (u == null)
            endloop
            call DestroyGroup(udg_KB3D_g)
            set udg_KB3D_g = null
        endif
        //----------
        if GroundDamage and (ImpactD != 0) and z < 75 and (Damager != null) then
            call UnitDamageTarget(Damager, U, ImpactD, true, false, AType, DType, null)
        endif
        //----------
        if (KillatEnd) and not EndB then
            call KillUnit(U)
        endif
        //----------
        if (EndT != null) then
            set udg_KB3D_Unit = U
            set udg_KB3D_Targeted_Unit = Target
            call ConditionalTriggerExecute(EndT)
            set udg_KB3D_Unit = null
            set udg_KB3D_Targeted_Unit = null
            set udg_KB3D_EndUnit = null
            set udg_KB3D_EndisUnpathable = false
            set udg_KB3D_EndisUnit = false
            set udg_KB3D_EndisNormal = true
        endif
    endif
  
    //Function to know if the unit is being KBed by the system
    call SaveInteger(udg_KB3D_HA, -2, GetHandleId(udg_KB3D_Unit), LoadInteger(udg_KB3D_HA, -2, GetHandleId(udg_KB3D_Unit))-1)
    call SaveBoolean(udg_KB3D_HA, -1, GetHandleId(udg_KB3D_Unit), LoadInteger(udg_KB3D_HA, -2, GetHandleId(udg_KB3D_Unit))!=0)
  
    //Clear Instance
    if b then
        call KB3D_ClearInstance(Loop)
    endif
  
    //Clear locals
    set udg_KB3D_B = false
    set U = null
    set Target = null
    set Damager = null
endfunction

function KB3D_Loop_Actions takes nothing returns nothing
    local integer x = 0
    if udg_KB3D_Paused then
    else
        loop
            exitwhen x >= udg_KB3D_Counter
            set x = x + 1
            if ( LoadBoolean(udg_KB3D_HA, 100, x) and not(LoadBoolean(udg_KB3D_HA, 77, x))) then
                call KB3D_Loop(x)
            endif
        endloop
        if ( udg_KB3D_Instances == 0 ) then
            set udg_KB3D_Counter = 0
            call PauseTimer(udg_KB3D_Timer)
        endif
    endif
endfunction

function KB3D_ClearVar takes nothing returns nothing
    set udg_KB3D_HomingMissile = false
    set udg_KB3D_EndOnTargetBounce = false
    set udg_KB3D_Speed_Changer = false
    set udg_KB3D_AoEEndFx = ""
    set udg_KB3D_D_STRUCTURE = false
    set udg_KB3D_D_MECHANICAL = false
    set udg_KB3D_D_ALLY = false
    set udg_KB3D_D_MAGIC_IMMINUE = false
    set udg_KB3D_D_ENEMY = true
    set udg_KB3D_D_RESISTANT = false
    set udg_KB3D_D_FLYING = false
    set udg_KB3D_Accel = 0.00
    set udg_KB3D_AllowOutSiding = false
    set udg_KB3D_Flyover = false
    set udg_KB3D_Flyover_Duration = 0.00
    set udg_KB3D_Angle = 0.00
    set udg_KB3D_AoE = 0.00
    set udg_KB3D_Arc = 0.00
    set udg_KB3D_AoEDamage = 0.00
    set udg_KB3D_AttackType = ATTACK_TYPE_NORMAL
    set udg_KB3D_DamageType = DAMAGE_TYPE_MAGIC
    set udg_KB3D_Damager = null
    set udg_KB3D_DestroyTree = true
    set udg_KB3D_DisableUnit = false
    set udg_KB3D_EndWhenHit = false
    set udg_KB3D_Fx = ""
    set udg_KB3D_Fx_Attach = ""
    set udg_KB3D_EndFx = ""
    set udg_KB3D_Attach = "origin"
    set udg_KB3D_ImpactDamage = 0.00
    set udg_KB3D_KillWhenHit = false
    set udg_KB3D_FaceAngle = false
    set udg_KB3D_KillifOutSider = false
    set udg_KB3D_LineDamage = 0.00
    set udg_KB3D_LoopDamage = 0.00
    set udg_KB3D_Range = 0.00
    set udg_KB3D_Speed = 0.00
    set udg_KB3D_TargetDamage = 0.00
    set udg_KB3D_Targeted_Unit = null
    set udg_KB3D_TrailFx = ""
    set udg_KB3D_Unit = null
    set udg_KB3D_UnpathableStop = true
    set udg_KB3D_Zoffset = 0.00
    set udg_KB3D_AoEEndDamage = 0.00
    set udg_KB3D_AoEKB = false
    set udg_KB3D_EndwhenDead = true
    set udg_KB3D_KBTarget = false
    set udg_KB3D_StopTime = 0.00
    set udg_KB3D_KillatTime = 0.00
    set udg_KB3D_AoEKB_Power = 1.00
    set udg_KB3D_iKB = true
    set udg_KB3D_KillatEnd = false
    set udg_KB3D_GroundDamage = false
    set udg_KB3D_EndTrigger = null
    set udg_KB3D_JumpOverCliff = false
    set udg_KB3D_DestroyDestructables = false
    set udg_KB3D_Line_Fx = ""
    set udg_KB3D_Bounce_Target = false
    set udg_KB3D_Bounce_Unit = false
    set udg_KB3D_Bounce_Power = 1.00
    set udg_KB3D_Bounce_Fx = ""
    set udg_KB3D_EndOnObstacle = false
    set udg_KB3D_EndUnit = null
    set udg_KB3D_RemoveUnit = null
    set udg_KB3D_EndisUnpathable = false
    set udg_KB3D_EndisUnit = false
    set udg_KB3D_EndisNormal = true
endfunction

function KB3D_Registration takes nothing returns boolean
    local real Time
    local real R
    local real R1
    local real dx
    local real dy
    if udg_KB3D_PausedReg then
        return false
    endif
    //------------------------
    if udg_KB3D_Unit == null then
        return false
    endif
    //------------------------
    if udg_KB3D_Fx_Attach != "" then
        set udg_KB3D_Fx = udg_KB3D_Fx_Attach
    endif
    //------------------------
    if udg_KB3D_HomingMissile and udg_KB3D_Targeted_Unit != null then
        set udg_KB3D_Zoffset = GetUnitFlyHeight(udg_KB3D_Targeted_Unit)
        set dx = GetUnitX(udg_KB3D_Unit)-GetUnitX(udg_KB3D_Targeted_Unit)
        set dy = GetUnitY(udg_KB3D_Unit)-GetUnitY(udg_KB3D_Targeted_Unit)
        if udg_KB3D_Zoffset == 0 then
            set udg_KB3D_Zoffset = 100
            set udg_KB3D_Range = SquareRoot( dx * dx + dy * dy)*1.25
        else
            set udg_KB3D_Range = SquareRoot( dx * dx + dy * dy)*2
        endif
        set udg_KB3D_KillatEnd = true
        set udg_KB3D_KillWhenHit = true
        set udg_KB3D_EndWhenHit = true
        set udg_KB3D_FaceAngle = true
        set udg_KB3D_UnpathableStop = false
    endif
    //------------------------
    set udg_KB3D_Arc = KB3D_InBetween(-10, udg_KB3D_Arc, 10)
    set udg_KB3D_AoEKB_Power = KB3D_InBetween(0.01, udg_KB3D_AoEKB_Power, 3)
    //------------------------
    if IsUnitType(udg_KB3D_Unit, UNIT_TYPE_FLYING) then
        set udg_KB3D_UnpathableStop = false
    endif
    //------------------------
    if (udg_KB3D_iKB) and udg_KB3D_Range < 0 then
        if ( udg_KB3D_Targeted_Unit == null ) then
            set udg_KB3D_Angle = udg_KB3D_Angle + 180
        else
            set udg_KB3D_Speed = -1*(udg_KB3D_Speed)
        endif
    endif
    //------------------------
    set udg_KB3D_Range = KB3D_InBetween(0.0000001, RAbsBJ(udg_KB3D_Range), RAbsBJ(udg_KB3D_Range))
    //------------------------
    if (udg_KB3D_iKB) and udg_KB3D_Speed < 0 then
        set udg_KB3D_Speed = KB3D_InBetween(udg_KB3D_Speed, udg_KB3D_Speed, 0)
    else
        set udg_KB3D_Speed = KB3D_InBetween(0.0, RAbsBJ(udg_KB3D_Speed), RAbsBJ(udg_KB3D_Speed))
    endif
    //------------------------
    set udg_KB3D_Counter = udg_KB3D_Counter + 1
    set udg_KB3D_Instances = udg_KB3D_Instances + 1
    call SaveBoolean(udg_KB3D_HA, -1, GetHandleId(udg_KB3D_Unit), true)
    call SaveBoolean(udg_KB3D_HA, 57, udg_KB3D_Counter, (udg_KB3D_Zoffset != 0))
    //------------------------
    if not udg_KB3D_iKB then
        set udg_KB3D_Zoffset = RAbsBJ(udg_KB3D_Zoffset)
    elseif GetUnitFlyHeight(udg_KB3D_Unit)+udg_KB3D_Zoffset < 0 then
        set udg_KB3D_Zoffset = -GetUnitFlyHeight(udg_KB3D_Unit)
    endif
    //------------------------
    set udg_KB3D_StopTime = RAbsBJ(udg_KB3D_StopTime)
    set udg_KB3D_KillatTime = RAbsBJ(udg_KB3D_KillatTime)
    set udg_KB3D_AoE = RAbsBJ(udg_KB3D_AoE)
    //------------------------
    //------------------------
    call SaveUnitHandle( udg_KB3D_HA, 0, udg_KB3D_Counter, udg_KB3D_Unit )
    call SaveReal( udg_KB3D_HA, 1, udg_KB3D_Counter, udg_KB3D_Range )
    call SaveReal( udg_KB3D_HA, 2, udg_KB3D_Counter, udg_KB3D_Speed * 0.031250000 )
    call SaveReal( udg_KB3D_HA, 4, udg_KB3D_Counter, udg_KB3D_Accel * 0.031250000 * 0.031250000 )
    //------------------------
    if ( udg_KB3D_Targeted_Unit == null ) then
        call SaveReal( udg_KB3D_HA, 5, udg_KB3D_Counter, udg_KB3D_Angle * 3.14159 / 180 )
    else
        call SaveUnitHandle( udg_KB3D_HA, 5, udg_KB3D_Counter, udg_KB3D_Targeted_Unit )
        set udg_KB3D_JumpOverCliff = false
    endif
    //------------------------
    call SaveBoolean( udg_KB3D_HA, 6, udg_KB3D_Counter, udg_KB3D_DisableUnit )
    call SaveBoolean( udg_KB3D_HA, 7, udg_KB3D_Counter, udg_KB3D_UnpathableStop )
    call SaveBoolean( udg_KB3D_HA, 8, udg_KB3D_Counter, udg_KB3D_DestroyTree )
    call SaveStr( udg_KB3D_HA, 9, udg_KB3D_Counter, udg_KB3D_Fx )
    call SaveStr( udg_KB3D_HA, 10, udg_KB3D_Counter, udg_KB3D_Attach )
    call SaveBoolean( udg_KB3D_HA, 45, udg_KB3D_Counter, udg_KB3D_Speed>0 )
    //------------------------
    //------------------------
    set udg_KB3D_Speed = KB3D_InBetween(0.01, RAbsBJ(udg_KB3D_Speed), RAbsBJ(udg_KB3D_Speed))
    //------------------------
    if ( udg_KB3D_Accel == 0.00 ) then
        set Time = udg_KB3D_Range / (udg_KB3D_Speed)//calculating time for the knockback if Acceleration = 0
    else
        if ( udg_KB3D_Accel > 0 ) then
            set Time = (-udg_KB3D_Speed-SquareRoot(udg_KB3D_Speed*udg_KB3D_Speed + 2*udg_KB3D_Accel*udg_KB3D_Range))/-udg_KB3D_Accel//calculating time for the knockback if Acceleration > 0*/
        endif
        if ( udg_KB3D_Accel < 0 ) then
            set Time = (-udg_KB3D_Speed+SquareRoot(udg_KB3D_Speed*udg_KB3D_Speed + 2*udg_KB3D_Accel*udg_KB3D_Range))/udg_KB3D_Accel           
        endif
    endif
    //------------------------
    call SaveReal( udg_KB3D_HA, 11, udg_KB3D_Counter, Time )
    call SaveBoolean( udg_KB3D_HA, 100, udg_KB3D_Counter, true )
    //------------------------
    if UnitAddAbility(udg_KB3D_Unit, 'Amrf') then
        call UnitRemoveAbility(udg_KB3D_Unit, 'Amrf')
    endif
    //------------------------
    call SaveReal( udg_KB3D_HA, 3, udg_KB3D_Counter, udg_KB3D_Zoffset )
    call SaveReal( udg_KB3D_HA, 12, udg_KB3D_Counter, (2*udg_KB3D_Zoffset / ( Time / 2)) )
    call SaveReal( udg_KB3D_HA, 13, udg_KB3D_Counter, ( -2 * udg_KB3D_Zoffset / ( Time / 2) ) / ( Time / 2) * 0.031250000 )
    //------------------------
    if not (udg_KB3D_TrailFx == "") and not (udg_KB3D_Attach == "") then
        call SaveEffectHandle(udg_KB3D_HA, 14, udg_KB3D_Counter, AddSpecialEffectTarget(udg_KB3D_TrailFx, udg_KB3D_Unit, udg_KB3D_Attach))
    endif
    //------------------------
    call SaveReal( udg_KB3D_HA, 15, udg_KB3D_Counter, GetUnitDefaultPropWindow(udg_KB3D_Unit) )
    call SaveBoolean(udg_KB3D_HA, 16, udg_KB3D_Counter, udg_KB3D_Speed_Changer)
    call SaveReal( udg_KB3D_HA, 17, udg_KB3D_Counter, udg_KB3D_ImpactDamage )
    call SaveReal( udg_KB3D_HA, 18, udg_KB3D_Counter, udg_KB3D_LoopDamage * 0.031250000 )
    call SaveReal( udg_KB3D_HA, 19, udg_KB3D_Counter, udg_KB3D_TargetDamage )
    call SaveInteger( udg_KB3D_HA, 20, udg_KB3D_Counter, GetHandleId(udg_KB3D_AttackType))
    call SaveInteger( udg_KB3D_HA, 21, udg_KB3D_Counter, GetHandleId(udg_KB3D_DamageType))
    call SaveUnitHandle( udg_KB3D_HA, 22, udg_KB3D_Counter, udg_KB3D_Damager )
    call SaveBoolean( udg_KB3D_HA, 23, udg_KB3D_Counter, true )
    call SaveBoolean( udg_KB3D_HA, 24, udg_KB3D_Counter, udg_KB3D_KillWhenHit )
    call SaveBoolean( udg_KB3D_HA, 25, udg_KB3D_Counter, udg_KB3D_EndWhenHit )
    // 26 used
    call SaveGroupHandle(udg_KB3D_HA, 27, udg_KB3D_Counter, CreateGroup() )
    call SaveReal( udg_KB3D_HA, 28, udg_KB3D_Counter, udg_KB3D_LineDamage )
    call SaveReal( udg_KB3D_HA, 29, udg_KB3D_Counter, RAbsBJ(udg_KB3D_AoE) )
    call SaveReal( udg_KB3D_HA, 30, udg_KB3D_Counter, udg_KB3D_Arc * (3.14159/180) )
    call SaveBoolean( udg_KB3D_HA, 31, udg_KB3D_Counter, udg_KB3D_FaceAngle )
    call SaveReal( udg_KB3D_HA, 32, udg_KB3D_Counter, udg_KB3D_AoEDamage )
    call SaveBoolean( udg_KB3D_HA, 33, udg_KB3D_Counter, udg_KB3D_KillifOutSider )
    //------------------------
    set udg_KB3D_AllowOutSiding = udg_KB3D_KillifOutSider
    //------------------------
    call SaveBoolean( udg_KB3D_HA, 34, udg_KB3D_Counter, udg_KB3D_AllowOutSiding )
    //------------------------
    if not udg_KB3D_EndwhenDead then
        set udg_KB3D_EndwhenDead = udg_KB3D_KillatTime > udg_KB3D_StopTime
    endif
    //------------------------
    call SaveBoolean( udg_KB3D_HA, 35, udg_KB3D_Counter, udg_KB3D_EndwhenDead )
    call SaveReal( udg_KB3D_HA, 36, udg_KB3D_Counter, udg_KB3D_KillatTime )
    call SaveReal( udg_KB3D_HA, 37, udg_KB3D_Counter, udg_KB3D_StopTime )
    call SaveReal( udg_KB3D_HA, 38, udg_KB3D_Counter, udg_KB3D_AoEEndDamage )
    call SaveBoolean( udg_KB3D_HA, 39, udg_KB3D_Counter, udg_KB3D_KBTarget )
    call SaveBoolean( udg_KB3D_HA, 40, udg_KB3D_Counter, udg_KB3D_AoEKB )
    //41 used
    call SaveStr(udg_KB3D_HA, 42, udg_KB3D_Counter, udg_KB3D_EndFx )
    call SaveReal( udg_KB3D_HA, 43, udg_KB3D_Counter, udg_KB3D_AoEKB_Power )
    call SaveBoolean( udg_KB3D_HA, 44, udg_KB3D_Counter, udg_KB3D_iKB )
    call SaveBoolean( udg_KB3D_HA, 46, udg_KB3D_Counter, udg_KB3D_KillatEnd )
    call SaveBoolean( udg_KB3D_HA, 47, udg_KB3D_Counter, udg_KB3D_GroundDamage )
    call SaveBoolean( udg_KB3D_HA, 48, udg_KB3D_Counter, udg_KB3D_D_STRUCTURE )
    call SaveBoolean( udg_KB3D_HA, 49, udg_KB3D_Counter, udg_KB3D_D_MECHANICAL )
    call SaveBoolean( udg_KB3D_HA, 50, udg_KB3D_Counter, udg_KB3D_D_MAGIC_IMMINUE )
    call SaveBoolean( udg_KB3D_HA, 51, udg_KB3D_Counter, udg_KB3D_D_ALLY )
    call SaveBoolean( udg_KB3D_HA, 52, udg_KB3D_Counter, udg_KB3D_JumpOverCliff )
    //call SaveBoolean( udg_KB3D_HA, 53, udg_KB3D_Counter, false )
    call SaveStr( udg_KB3D_HA, 54, udg_KB3D_Counter, udg_KB3D_AoEEndFx )
    call SaveTriggerHandle( udg_KB3D_HA, 55, udg_KB3D_Counter, udg_KB3D_EndTrigger )
    call SaveBoolean( udg_KB3D_HA, 56, udg_KB3D_Counter, udg_KB3D_DestroyDestructables )
    //57 used
    call SaveStr( udg_KB3D_HA, 58, udg_KB3D_Counter, udg_KB3D_Line_Fx )
    call SaveReal( udg_KB3D_HA, 59, udg_KB3D_Counter, udg_KB3D_Bounce_Power )
    call SaveBoolean( udg_KB3D_HA, 60, udg_KB3D_Counter, udg_KB3D_Bounce_Unit )
    call SaveBoolean( udg_KB3D_HA, 61, udg_KB3D_Counter, udg_KB3D_Bounce_Target )
    call SaveStr( udg_KB3D_HA, 62, udg_KB3D_Counter, udg_KB3D_Bounce_Fx )
    call SaveBoolean( udg_KB3D_HA, 63, udg_KB3D_Counter, udg_KB3D_D_ENEMY )
    call SaveBoolean( udg_KB3D_HA, 64, udg_KB3D_Counter, udg_KB3D_D_RESISTANT )
    call SaveBoolean( udg_KB3D_HA, 65, udg_KB3D_Counter, udg_KB3D_D_FLYING )
    call SaveBoolean( udg_KB3D_HA, 66, udg_KB3D_Counter, udg_KB3D_EndOnObstacle )
    //------------------------
    if udg_KB3D_Bounce_Target then
        call SaveGroupHandle(udg_KB3D_HA, 67, udg_KB3D_Counter, CreateGroup())
    endif
    //------------------------
    call SaveReal( udg_KB3D_HA, 68, udg_KB3D_Counter, KB3D_GetCoordinatesZ(GetUnitX(udg_KB3D_Unit), GetUnitY(udg_KB3D_Unit)) )
    call SaveReal( udg_KB3D_HA, 69, udg_KB3D_Counter, KB3D_GetCoordinatesZ(GetUnitX(udg_KB3D_Unit), GetUnitY(udg_KB3D_Unit)) )
    call SaveBoolean( udg_KB3D_HA, 70, udg_KB3D_Counter, udg_KB3D_EndOnTargetBounce )
    call SaveReal(udg_KB3D_HA, 71, udg_KB3D_Counter, GetUnitFlyHeight(udg_KB3D_Unit))
    call SaveBoolean(udg_KB3D_HA, 72, udg_KB3D_Counter, udg_KB3D_Flyover)
    call SaveReal(udg_KB3D_HA, 73, udg_KB3D_Counter, udg_KB3D_Flyover_Duration)
    //74 used
    call SaveBoolean(udg_KB3D_HA, 75, udg_KB3D_Counter, udg_KB3D_Flyover)
    call SaveReal(udg_KB3D_HA, 76, udg_KB3D_Counter, 0)
    call SaveBoolean(udg_KB3D_HA, 77, udg_KB3D_Counter, false)
   
    //------------------------
    if ( udg_KB3D_Counter == 1 ) then
        call TimerStart(udg_KB3D_Timer, 0.031250000, true, function KB3D_Loop_Actions )
    endif
    //------------------------
    set udg_KB3D_Time = Time
    //------------------------
    //------------------------
    call SaveInteger(udg_KB3D_HA, -5, GetHandleId(udg_KB3D_Unit), LoadInteger(udg_KB3D_HA, -5, GetHandleId(udg_KB3D_Unit))+1)
    call SaveBoolean(udg_KB3D_HA, GetHandleId(udg_KB3D_Unit), GetHandleId(udg_KB3D_Unit), true)
    //------------------------
    //------------------------
    //------------------------
    call KB3D_ClearVar()
    return false
endfunction

function KB3D_RemoveUnit takes nothing returns nothing
    local integer x = 1
    loop
    exitwhen x > udg_KB3D_Counter
        if LoadUnitHandle(udg_KB3D_HA, 0, x) == udg_KB3D_RemoveUnit then
            call SaveReal(udg_KB3D_HA, 1, x, 0)
        endif
        set x = x + 1
    endloop
endfunction

function KB3D_Pause takes nothing returns nothing
    call SaveBoolean(udg_KB3D_HA, 77, udg_KB3D_PauseID, true)
    set udg_KB3D_PauseID = -1
endfunction

function KB3D_Resume takes nothing returns nothing
    call SaveBoolean(udg_KB3D_HA, 77, udg_KB3D_PauseID, false)
    set udg_KB3D_PauseID = -1
endfunction

function KB3D_PauseAll takes nothing returns nothing
    set udg_KB3D_Paused = true
endfunction

function KB3D_ResumeAll takes nothing returns nothing
    set udg_KB3D_Paused = false
endfunction

function KB3D_PauseRegistration takes nothing returns nothing
    set udg_KB3D_PausedReg = true
endfunction

function KB3D_ResumeRegistration takes nothing returns nothing
    set udg_KB3D_PausedReg = false
endfunction

//===========================================================================
function InitTrig_KB3D takes nothing returns nothing
    ////////REGISTRATION
    set udg_KB3D_Registration = CreateTrigger(  )
    call TriggerAddCondition( udg_KB3D_Registration, Condition(function KB3D_Registration) )
    set udg_KB3D_Harvester = CreateUnit(Player(15), 'hpea', 0, 0, 0)
    call ShowUnit(udg_KB3D_Harvester, false)
    call UnitAddAbility(udg_KB3D_Harvester, 'Aloc')
    call UnitAddAbility(udg_KB3D_Harvester, 'Ahar')
    call UnitRemoveAbility(udg_KB3D_Harvester, 'Amov')
    set udg_KB3D_HA = InitHashtable()
    ////////Check Walkability System by PnF
    set udg_CP_Rect = Rect(0, 0, 128.00, 128.00)
    set udg_CP_Item = CreateItem('wtlg', 0, 0)
    call SetItemVisible( udg_CP_Item, false )
    ////////InitReals
    set udg_KB3D_Reals[1] = GetRectMaxX(bj_mapInitialPlayableArea)
    set udg_KB3D_Reals[2] = GetRectMinX(bj_mapInitialPlayableArea)
    set udg_KB3D_Reals[3] = GetRectMaxY(bj_mapInitialPlayableArea)
    set udg_KB3D_Reals[4] = GetRectMinY(bj_mapInitialPlayableArea)
    set udg_KB3D_Reals[5] = GetRectMaxX(GetWorldBounds())
    set udg_KB3D_Reals[6] = GetRectMinX(GetWorldBounds())
    set udg_KB3D_Reals[7] = GetRectMaxY(GetWorldBounds())
    set udg_KB3D_Reals[8] = GetRectMinY(GetWorldBounds())
    //Initiate Default Values
    call KB3D_ClearVar()
endfunction

V. 3.2.1 Update Changelog:
  • New Function: KB3D_RemoveUnit
    After setting the variable KB3D_RemoveUnit to the unit of your choice, executing the function KB3D_RemoveUnit will automatically cancel all KB instances on that specific unit
  • You can Know what caused the End of a KB in the EndTrigger by checking the following Booleans: "KB3D_EndisNormal" "KB3D_EndisUnit" "KB3D_EndisUnpathable"
    EndisUnit refers to an End related to a TargetBounce or the KBed Unit hitting the Target Unit, the Target Unit or TargetBounce Unit can be known by using the variable: "KB3D_EndUnit"
    EndisNormal refers to a normal, MaxRange reached, or 0 Speed End
    EndisUnpathable refers to any unpathable terrain, which can be a tree, a destructable or cliff, or any other path changer
  • New Functions: "KB3D_Pause" "KB3D_Resume"
    After getting the ID of the KB you want to pause/resume, setting the variable KB3D_PauseID to the ID you have and then calling one of the functions above will either pause the KB or resume it, careful using it while having DisableUnit ON
  • New Functions: "KB3D_PauseAll" "KB3D_ResueAll"
    Executing either function will Pause/Resume ALL Knockbacks, including newly registered ones
  • New Functions: "KB3D_PauseRegistration" "KB3D_ResumeRegistration"
    Executing either function will disable/enable registrating any new KB


Keywords:
Knockback, knock back, knock-back, 3D, Z, System, Fly, Jump, Projectile, wave, 5/5, JASS, GUI, Multi, Movement, MMS, KB3D
Contents

KB3D - MMS 3D (Map)

Reviews
17:03, 3rd Oct 2013 PurgeandFire: A nice, smooth, full-featured knockback system.
Level 6
Joined
Jan 4, 2014
Messages
227
Unit1 is a projectile, it will hit a unit2, the KB ends, how to get unit2 (witout using KB3D_Target_Unit) ???
 
Level 6
Joined
Jan 4, 2014
Messages
227
Congratulation ! its not causing DeSync anymore :) The final result is some times VISUALLY wrong but it does not matter !

Thanks for your awsome system, and happy new year !!!!
 
Level 6
Joined
Jan 4, 2014
Messages
227
Good day ! i need a bit of help about a trigger pleas :)

here is a video of what i actually have :
http://www.youtube.com/watch?v=EgBPn8NyqnQ&feature=youtu.be

i use this trigger :
  • Shadow Rush 1
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to (==) Shadow Rush 2
    • Actions
      • Set KB3D_Attach = origin
      • Set KB3D_Accel = -150.00
      • Set KB3D_Bounce_Target = True
      • Set KB3D_Bounce_Fx = Abilities\Spells\Other\Volcano\VolcanoDeath.mdl
      • Set KB3D_DestroyDestructables = True
      • Set KB3D_Bounce_Unit = False
      • Set KB3D_Angle = (Facing of (Triggering unit))
      • Set KB3D_DisableUnit = True
      • Set KB3D_DestroyTree = True
      • Set KB3D_FaceAngle = True
      • Set KB3D_Range = (Distance between (Position of (Triggering unit)) and (Target point of ability being cast))
      • Set KB3D_Speed = 2000.00
      • Set KB3D_Targeted_Unit = No unit
      • Set KB3D_Unit = (Triggering unit)
      • Set KB3D_Zoffset = 0.00
      • Set KB3D_Fx = Abilities\Weapons\AvengerMissile\AvengerMissile.mdl
      • Set KB3D_TrailFx = Abilities\Weapons\AvengerMissile\AvengerMissile.mdl
      • Set KB3D_Damager = (Triggering unit)
      • Set KB3D_LoopDamage = 0.00
      • Set KB3D_LineDamage = 0.00
      • Set KB3D_AoE = 250.00
      • Set KB3D_ImpactDamage = 0.00
      • Set KB3D_AttackType = Magic
      • Set KB3D_DamageType = Magic
      • Set KB3D_KillatEnd = False
      • Custom script: call ExecuteFunc( "KB3D_Registration" )
1 - i want my hero to stop when it hits an enemy unit
2 - i want my hero to bounce only the unit that it hits at the end (only 1 unit)
3 - i need a way to detect what is that unit (the unit that caused the end of the KB and that is being bounced) so that i can use it at KB3D_EndTrigger
- i tried KB3D_Target_Unit but it does not work ^^

can you pleas correct my trigger ??
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
Here are the stuff you will need to use
1. KB3D_EndonBounce
2. Same as 1.
3. Well KB3D does not include such function as far as I remember, but, as an alternative, do the following in the EndTrigger:

Check the nearest unit that checks all the conditions to the KB3D_Unit, that unit will be the unit you are looking for
 
Level 6
Joined
Jan 4, 2014
Messages
227
Thanks :) thats exactly what i was looking for, the third solution is good enough for the moment, but it will be awsome if you make something like KB3D_EndUnit that can be used in KB3D_EndTrigger.
Good Luck :)
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
KB3D Year Changelog

With the year ending, here is the overall recap, of all KB3D's changelog history

Some might find it useful, as it will reveal some features that were not really brought to light

v. 1.0.0
Initial Release
v. 1.0.1
  • Now Flying units will not go for a height lower than their default one
  • Trigger optimizations
v. 1.1.0
  • Added possibility to apply DPS on knockbacked unit
  • Added Possibility of Impact damage on obstacles
  • Added Trail Effect that will stay on KBed unit during the knock-back
  • Trigger Optimization
v. 1.1.1
Added more documentation and improved scripts
v. 1.2.0

  • Approval Changes made of which:
  • Made the Attack/Damage Type more user friendly
  • Some Trigger Optimization
  • Fixed a bug where trail Fxs where re-destroyed when knockbacking other units
  • Added a timer instead of a trigger loop
    And More:
  • Now units can not go out of map bounds
  • Better Scripting
v. 1.2.1
Quick update fixing a bug where Jump ability triggered Wave ability
v. 1.3.0
  • Impact Damage Reworked
  • Target Damage is now working
  • Added Possibility to Kill the KBed unit when he hits the targeted unit (for missiles mainly)
  • Added Possibility to stop the KB when the KBed unit hits the targeted unit
  • Fixed a bug where Angle-based Knock-backs were using a homing based KB
  • Made it possible to know the Time of knock-back at registration
  • Fixed a Massive bug where the KB3D System Stopped Working
  • Line Damage is now here
  • Better Documentation
v. 1.3.1
  • Trigger Fixes
  • Added some more examples in the Test Map
v. 1.3.2
Added Arc possibility along with Face Angle possibility
v. 1.3.3
  • Added AoEDamage possibility (DPS in an AoE)
  • Trigger optimizations
v. 1.3.4
Critical Update: Added Variable Creator Trigger
v. 1.3.5
  • Added 2 new functions (AllowOutofPlayableBounds and KillifOutofPlayableBounds)
  • Bug Fixes
v. 1.4.0
  • Trigger Optimization
  • Bug Fixes
  • Approved
v. 1.4.1
Trigger Fixes
v. 1.4.2
Bug Fixes
v. 1.5.0
You can now choose to:
  • KB the Targeted Unit when it is hit
  • KB units in an AoE at end of the KB, stacks with target KB
  • Create an Fx at the end of the KB
  • When the KB will End (at which time) [0 == disabled]
  • When will the KBed unit will be killed if he is still KBed [0 == disabled]
  • Damage enemy units in an AoE at the End of the KB
  • Choose whether or not to stop the KB if the unit is dead [true by default]
And: now Trees won't get destroyed if the unit is higher than their occlude Height and trigger optimization
v. 1.5.1
Fixing Bug with KillatTime and StopatTime
v. 1.5.2
Bug Fix with the New Features
v. 1.5.2
  • Smoother, and more intelligent AoE KB
  • Way better documentation and Trigger Optimization
v. 1.6.0
3 New Features of which:
  1. KillatEnd - Kills the KBed Unit at the End of the KB
  2. AoEKB_Power - Intensity of the AoEKB at the End of the KB (Real value from 0.01 to 3.00)
  3. iKB - Makes, if true, all the KB turn intelligent and work intelligently (see the Script comments for more info
And more:
  • Less Lag with Destroying Trees
  • Now Flying Units will, Always ignore pathability
  • Overall Scripting is enhanced
  • The Action that Registered the KB has been changed to a Custom Script Line: "call TriggerEvaluate( udg_KB3D_Registration )"
  • Bug Fix: Default values were not taken on the First KB in the Map
v. 1.6.X
2 New Features of which:
  1. Ground Damage, if true, damages the KBed unit when it hits the ground by ImpactDamage
  2. Damage Filtering:
    • KB3D_D_STRUCTURE : Allow Targeting of Structures
    • KB3D_D_MECHANICAL : Allow Targeting of Mechanicals
    • KB3D_D_MAGIC_IMMINUE : Allow Targeting of Magic Imminues
    • KB3D_D_ALLY : Allow Targeting of Allied Units
And more:
  • Bug Fixes
  • Trigger Optimizations
  • Overall Scripting is enhanced
v. 1.7.0
2 New Features of which:
  1. Jump Over Cliffs, Allows the KBed unit to go over cliffs if he has more than 150 fly height and IF there is a possible location where he can land in a pathable point, not recommended with >0 Acceleration
  2. AoE End Effect, creates Effects on target units in the AoE at the End of the KB
And more:
  • Changed ForGroup to FirstofGroup
  • Trigger Optimizations
  • Enhanced Tree Destroy
v. 1.7.1

  • Changed nulls to True function, trigger optimization
  • Fixed Resource Image at Hive
v. 1.7.2

  • Fixed compatibility issues with normal WE and optimized the script
  • Improved the JumpOverCliff function
v. 1.8.0
New Features::
  1. KB3D_EndTrigger
  2. KB3D_Line_Fx
  3. KB3D_DestroyDestructables
  4. KB3D_D_ENEMY
  5. KB3D_D_FLYINGS
  6. KB3D_Bounce_Target
  7. KB3D_Bounce_Unit
  8. KB3D_Bounce_Fx
Also, Lots of system improvements, not just optimizations, but usability improvements
v. 1.8.1

  • Improved Scripting
  • Fixed the Features' Descriptions
v. 1.8.2

  • Bug Fixes
  • Now the 'hidden' builder doesn't harvest trees <bug fix>
v. 1.8.3

  • Fixed Lag when destroying trees
  • Reduced Lag with the Bounce feature
  • KB3D_DestroyTree is now TRUE by default
v. 1.8.4
Feature to know if a unit is being KBed by the system is now functional, can be used by loading from the KB3D hashtable the boolean, with the handle Id of the unit in both parent and child key
v. 1.9.0

  • 3 new features:
    • KB3D_Speed_Changer
    • KB3D_EndOnTargetBounce
    • KB3D_HomingMissile
  • KB3D_JumpOverCliffs now requires iKB to run
  • Z Performences are now Advanced
  • REMOVED the lag from Bounce feature and fixed a bug with Target_Bounce
  • iKB now supports negative Zoffset
  • Positive Acceleration Fix, Time feature now functions 100%
  • Uncompatibility with KB3D v. 1.8.X and older versions is fixed
  • Way Better Scripting and enhancements


Updated the Bounce System to simulate real bounces as of in real life rather than just changing the Angle of the movement by a random value

KB3D V. 3.0.0 Update

  • Fixed a Bug with GetLocationZ causing desync
  • Improved and Fixed bugs with Bounce feature
  • Improved the Code here and there
Updated again to v. 3.1.0

- Fixed the Desync problems from GetLocationZ


JASS:
function KB3D_GetCoordinatesZ takes real x, real y returns real
    local location L = Location(x,y)
    local real r = 0
    local integer I = 0
    local boolean B = true
    loop 
        exitwhen I >= 12
        if IsLocationVisibleToPlayer( L , Player(I)) then
        else
            set B = false
        endif
        set I = I + 1
    endloop
    if B then
        set r = GetLocationZ(L)
    endif
    call RemoveLocation(L)
    set L = null
    return r
endfunction
V. 3.1.1 Update

"Just in case" fix for the function:

JASS:
function KB3D_GetCoordinatesZ takes real x, real y returns real
    local location L = Location(x,y)
    local real r = 0
    local integer I = 0
    local integer t = 12
    local boolean B = true
    loop 
        exitwhen I == 12
        if GetPlayerSlotState(Player(I)) != ConvertPlayerSlotState(1) then
            set t = t - 1
        else
            if IsLocationFoggedToPlayer( L , Player(I)) then
                set B = false
                set t = t - 1
            endif
        endif
        set I = I + 1
    endloop
    if B or t == 0 then
        set r = GetLocationZ(L)
    endif
    call RemoveLocation(L)
    set L = null
    return r
endfunction
V. 3.2.0 Update Changelog:
  • Fixed DestroyDestructable affecting DestroyTree
  • Now Bounce Effects won't trigger if an effect occurred in the past 0.3 seconds
  • Fixed BouncePower using the default value of it, 1.0
  • Fixed EndWhenDead being based on KillatTime and StopTime

Other Notices:
  • ThunderClap turned out not being bugged and stucking units on ~50 units above the ground
  • FireBoulder's weird movement is still a mystery till now
 
Level 6
Joined
Jan 4, 2014
Messages
227
Good Day ! i have a question pleas, if the triggering unit (a hero) is the projectile an its a homing projectile, will it always die at the end of the KB ? since i set KB3D_killatEnd to false and it always die.
Btw, the spell is barathum "Charge of Darkness" from DotA.
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
the option "homing missile" automatically overrides some options, one of them is killatend, basically you will need to set the options needed for the projectile yourself without using "homing missile"

this is the code of homing missile:
JASS:
    if udg_KB3D_Targeted_Unit != null and udg_KB3D_HomingMissile then
        set udg_KB3D_Zoffset = GetUnitFlyHeight(udg_KB3D_Targeted_Unit)
        set dx = GetUnitX(udg_KB3D_Unit)-GetUnitX(udg_KB3D_Targeted_Unit)
        set dy = GetUnitY(udg_KB3D_Unit)-GetUnitY(udg_KB3D_Targeted_Unit)
        if udg_KB3D_Zoffset == 0 then
            set udg_KB3D_Zoffset = 100
            set udg_KB3D_Range = SquareRoot( dx * dx + dy * dy)*1.25
        else
            set udg_KB3D_Range = SquareRoot( dx * dx + dy * dy)*2
        endif
        set udg_KB3D_KillatEnd = true
        set udg_KB3D_KillWhenHit = true
        set udg_KB3D_EndWhenHit = true
        set udg_KB3D_FaceAngle = true
        set udg_KB3D_UnpathableStop = false
    endif

the list of features is overrides:
  1. KB3D_Zoffset
  2. KB3D_KillatEnd
  3. KB3D_KillWhenHit
  4. KB3D_EndWhenHit
  5. KB3D_FaceAngle
  6. KB3D_UnpathableStop

EDIT:

Note that this part of the code:
JASS:
        set udg_KB3D_Zoffset = GetUnitFlyHeight(udg_KB3D_Targeted_Unit)
        set dx = GetUnitX(udg_KB3D_Unit)-GetUnitX(udg_KB3D_Targeted_Unit)
        set dy = GetUnitY(udg_KB3D_Unit)-GetUnitY(udg_KB3D_Targeted_Unit)
        if udg_KB3D_Zoffset == 0 then
            set udg_KB3D_Zoffset = 100
            set udg_KB3D_Range = SquareRoot( dx * dx + dy * dy)*1.25
        else
            set udg_KB3D_Range = SquareRoot( dx * dx + dy * dy)*2
        endif
basically gives the movement an arc if the target has a flying height
 

Deleted member 219079

D

Deleted member 219079

JASS2 uses short circulated condition checking, thus:
if udg_KB3D_Targeted_Unit != null and udg_KB3D_HomingMissile then
Is slower than:
if udg_KB3D_HomingMissile and udg_KB3D_Targeted_Unit != null then

But overall nice project this far :)
 
Last edited by a moderator:
Level 23
Joined
Apr 16, 2012
Messages
4,041
micro, not macro :D

and yes, this is so silly that it should be forgotten.

Its even more silly optimization than having 2 letter functon names insead of 4 or so. Jass is already so slow that doing (A != B) or C compared to C or (A != null) is literally neglitable
 
Level 6
Joined
Jan 4, 2014
Messages
227
Thanks TDW i love when u understand me :) what i will do is this :

//set udg_KB3D_KillatEnd = true
//set udg_KB3D_KillWhenHit = true

and this :

//set udg_KB3D_Zoffset = 100

and set them manually if i need them.
 
Level 6
Joined
Jan 4, 2014
Messages
227
hi TDW ! i have some features to request :

1 - Add and ID for each KnockBack Entry in your knockback table.
2 - Add a function to remove unit from knockback table (all entries).
3 - Add a function to end a specific knockback using the ID i told you before.
4 - Add a KB3D_EndUnitGroup that countain the units that ended the knockback.
5 - Add KB3D_EndisDestructible KB3D_EndisTree KB3D_EndisUnpathable KB3D_EndisMaxRange Booleans to know what caused the end of the knockback.
6 - Add a function to change the target of a homing missile during the knockback.

Take your time and good luck :)
 
Level 6
Joined
Jan 4, 2014
Messages
227
OK ! Thanks Bro :) i just need an exemple pleas.

- About number 6 what i'm planing to do is to create a Dummy wich is the target and its attached to the target targeted by the Player, when i want to change the target i just attach the dummy to another Unit, just like barathum change target when the targeted unit is dead.
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
Oh, easy way then:
After registering the KB instance, save into a new variable the value of KB3D_Counter
Then when you want to change target, just save the new unit into the hashtable of KB3D:
SaveUnit(KB3D_HA, 5, Instance ID, new unit)
The rest is automated
 
Level 6
Joined
Jan 4, 2014
Messages
227
You are welcome any time bro, ask me anytime you want :)
well, second think is for an ability that freezes the targeted units ( freezes them in space and time ), i then remove all KB instances of the unit.

EDIT : But hey ! i got an idea what if you add functions like :

1 - KB3D_Pause(integer instance ID)
2 - KB3D_Resume(integer instance ID)
3 - KB3D_PauseAll()
4 - KB3D_ResumeAll()
5 - KB3D_PauseRegistration()

i know i can simulate it with creating another knockbacks, but this is better and easier.
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
KB3D Update

V. 3.2.1 Update Changelog:
  • New Function: KB3D_RemoveUnit
    After setting the variable KB3D_RemoveUnit to the unit of your choice, executing the function KB3D_RemoveUnit will automatically cancel all KB instances on that specific unit
  • You can Know what caused the End of a KB in the EndTrigger by checking the following Booleans: "KB3D_EndisNormal" "KB3D_EndisUnit" "KB3D_EndisUnpathable"
    EndisUnit refers to an End related to a TargetBounce or the KBed Unit hitting the Target Unit, the Target Unit or TargetBounce Unit can be known by using the variable: "KB3D_EndUnit"
    EndisNormal refers to a normal, MaxRange reached, or 0 Speed End
    EndisUnpathable refers to any unpathable terrain, which can be a tree, a destructable or cliff, or any other path changer
  • New Functions: "KB3D_Pause" "KB3D_Resume"
    After getting the ID of the KB you want to pause/resume, setting the variable KB3D_PauseID to the ID you have and then calling one of the functions above will either pause the KB or resume it, careful using it while having DisableUnit ON
  • New Functions: "KB3D_PauseAll" "KB3D_ResueAll"
    Executing either function will Pause/Resume ALL Knockbacks, including newly registered ones
  • New Functions: "KB3D_PauseRegistration" "KB3D_ResumeRegistration"
    Executing either function will disable/enable registrating any new KB
  • Improved System
    -AoE Damage and Bounce AoE no longer have a different AoE (which resulted sometimes in units getting damaged but not bounced against
    -Fixed the AoE where trees were destroyed so it's more consistent with High values Speed


Edit: This version may contain some bugs, i cleared most of the ones i noticed but i feel there are some i missed
 
Level 6
Joined
Jan 4, 2014
Messages
227
Wow Wow Wow ! Amazing ! Thanks Bro :)

1 - i will do a LAN Test in 2 weeks max and give you a full report.
2 - if using the system is paused using KB3D_PauseAll and i register a new KB it will not execute ? and when if i use KB3D_ResumeAll what i registred is executed ?
3 - Typo error in "KB3D_ResueAll"
4 - what do you use to disable units ? (stun ? pause ? ...) so that i can reverse it if some thing goes wrong.

Thats All Thanks Again :)
 
Level 5
Joined
May 12, 2014
Messages
133
Hey, I'm having a problem using your system. Inside of the test map, I'm trying to make the Wave spell hit air units. So far, I haven't been able to.
What am I doing wrong?

I took the example 4 trigger (Wave) and edited it slightly.
  • KB3D Example 4
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Wave
    • Actions
      • Unit - Create 1 Footman for Player 1 (Red) at (Position of (Triggering unit)) facing (Target point of ability being cast)
      • Set KB3D_Attach = origin
      • Set KB3D_Line_Fx = Abilities\Weapons\RedDragonBreath\RedDragonMissile.mdl
      • Set KB3D_D_MECHANICAL = True
      • Set KB3D_D_FLYING = True
      • Set KB3D_Accel = -250.00
      • Set KB3D_AllowOutSiding = True
      • Set KB3D_KillifOutSider = True
      • Set KB3D_Angle = (Facing of (Last created unit))
      • Set KB3D_DestroyTree = True
      • Set KB3D_DisableUnit = True
      • Set KB3D_FaceAngle = True
      • Set KB3D_Range = 3000.00
      • Set KB3D_Speed = 1500.00
      • Set KB3D_Targeted_Unit = No unit
      • Set KB3D_Unit = (Last created unit)
      • Set KB3D_UnpathableStop = False
      • Set KB3D_Zoffset = 0.00
      • Set KB3D_TrailFx = <Empty String>
      • Set KB3D_Damager = (Triggering unit)
      • Set KB3D_LoopDamage = 0.00
      • Set KB3D_LineDamage = 75.00
      • Set KB3D_AoE = 250.00
      • Set KB3D_ImpactDamage = 0.00
      • Set KB3D_AttackType = Magic
      • Set KB3D_DamageType = Magic
      • Set KB3D_KillatEnd = True
      • Custom script: call ExecuteFunc( "KB3D_Registration" )
      • Game - Display to (All players) the text: (Travel Time: + ((String(KB3D_Time)) + s))


Also, I have another question. Is it possible to include a DDS with this? I want to use this in my map, but I don't want heroes to be gaining lifesteal from spells they cast! I've sort of figured out a workaround, but it would be much easier if a DDS could be somehow included. Especially since that line damage is soooooo convenient!
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
1. KB3D_iKB is an enabled feature by default, this is it's description:
JASS:
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//            iKB, intelligent KB informations:                            //
//                                                                         //
//     iKB, makes some features in KB3D act intelligently, those features: //
//                                                                         //
//       -Range: usually always positive, it will be available in negative //
//               values, it will, if negative, flip the Angle (+180 d)     //
//       -Speed: usually always positive, it will be available in negative //
//               values, it will act normally, just the KBed unit will     //
//               move backward if the current speed is negative            //
//       -Height: usually always positive, it will be available in negative//
//               values, it will, if negative, make the unit go down       //
//               instead of up                                             //
//       -Damages:                                                         //
//       AoEEndDamage, AoEDamage, LineDamage, ImpactDamage, TargetDamage   //
//                                                                         //
//             All those values ^ will turn intelligent, by this, it means //
//             that if the Target of the Damage is not in approximated     //
//             height (Z) of the KBed Unit, the damage won't occur         //
//       -AoEKB, usually KBs all units in the AoE, it will choose only     //
//        Units that are close to it by the height, Z offset               //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////

so basically if the missile is not "near from all axises" from a unit, it won't damage it
thus turning it off will fix your issue

2.sorry to say that but adding a DDS is somehow, "too much" for this already huge system

you can work alongside a DDS from hive, since you can choose the damage type, damage dealer and targets in KB3D, so you can easily detect them in the DDS

alternatively, if i got your point about lifesteal, you can make a projectile owned by the caster and make that same projectile damage the targets with KB3D instead of the caster
 
Level 5
Joined
May 12, 2014
Messages
133
Well... That is one smart system! Thanks for the quick reply.
I'm pretty sure this means I need to learn this thing a lot more!
 
Level 4
Joined
Sep 12, 2008
Messages
111
Is it possible to include your own loop trigger? If a unit gets knocked back then it will loop the custom trigger on top of the knock back.
 
[jass=]
function KB3D_KillEnumDest takes nothing returns nothing
local destructable D = GetEnumDestructable()
//---------------------------
if GetDestructableLife(D)>0 and ( KB3D_Tree_Check(D) ) and (GetUnitFlyHeight(LoadUnitHandle(udg_KB3D_HA, 0, R2I(udg_KB3D_Reals[0]))) < GetDestructableOccluderHeight(D)) and LoadBoolean(udg_KB3D_HA, 8, R2I(udg_KB3D_Reals[0])) then
call KillDestructable(D)
elseif /*not(KB3D_CW(GetDestructableX(D),GetDestructableY(D))) and*/ GetDestructableLife(D)>0 and not(KB3D_Tree_Check(D)) and LoadBoolean(udg_KB3D_HA, 56, R2I(udg_KB3D_Reals[0])) then
call KillDestructable(D)
endif
set D = null
endfunction
[/code]


Seems to be a problem with saving however it somehow works beforehand.
 
Level 6
Joined
Jan 4, 2014
Messages
227
here at 36:48 : https://youtu.be/R4hzpTcs9h0?t=2208 There is a terrain deformation, it may be the cause of the desync, and here is the triggers you told me to send you :

Spell 1 (Cast by Vayne):

  • Tumble
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to (==) Tumble
    • Actions
      • Custom script: local location P2
      • Custom script: set P2 = GetSpellTargetLoc()
      • Set J = (Owner of (Triggering unit))
      • Set I = (Player number of J)
      • Set P = (Position of (Triggering unit))
      • Set D = (Distance between P and (P2))
      • Set D2 = (Angle from P to (P2))
      • Unit - Make (Triggering unit) face D2 over 0.00 seconds
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • D Greater than (>) 450.00
          • Then - Actions
            • Set KB3D_Range = 450.00
          • Else - Actions
            • Set KB3D_Range = (Distance between P and (P2))
      • Set KB3D_UnpathableStop = False
      • Set KB3D_DestroyDestructables = False
      • Set KB3D_DisableUnit = True
      • Set KB3D_FaceAngle = True
      • Set KB3D_Speed = 2000.00
      • Set KB3D_Angle = D2
      • Set KB3D_Unit = (Triggering unit)
      • Set KB3D_KillatEnd = False
      • Set KB3D_TrailFx = Abilities\Spells\Undead\FreezingBreath\FreezingBreathMissile.mdl
      • Set KB3D_EndTrigger = Tumble 2 <gen>
      • Custom script: call ExecuteFunc( "KB3D_Registration" )
      • Custom script: call RemoveLocation(udg_P)
      • Custom script: call RemoveLocation(P2)
End of knockback 1 :

  • Tumble 2
    • Events
    • Conditions
    • Actions
      • Unit - Create 1 Caster Dummy for (Owner of KB3D_Unit) at (Center of (Playable map area)) facing Default building facing (270.0) degrees
      • Unit - Add Max AS to (Last created unit)
      • Unit - Order (Last created unit) to Orc Shaman - Bloodlust KB3D_Unit
      • Unit - Add Tumble Buff to (Last created unit)
      • Unit - Order (Last created unit) to Human Priest - Inner Fire KB3D_Unit
      • Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (KB3D_Unit has buff Final Hour ) Equal to (==) True
          • Then - Actions
            • Unit - Order EngineDummy to Human Sorceress - Invisibility KB3D_Unit
          • Else - Actions
Spell 2 (Cast by Fireblood):

  • Slam
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to (==) Slam
    • Actions
      • Set P = (Position of (Triggering unit))
      • Set P2 = (Target point of ability being cast)
      • Set KB3D_GroundDamage = True
      • Set KB3D_Accel = 0.00
      • Set KB3D_Angle = (Angle from P to P2)
      • Set KB3D_DestroyTree = True
      • Set KB3D_DisableUnit = True
      • Set KB3D_Attach = chest
      • Set KB3D_Range = (Distance between P and P2)
      • Set KB3D_Speed = 1200.00
      • Set KB3D_Targeted_Unit = No unit
      • Set KB3D_Unit = (Triggering unit)
      • Set KB3D_UnpathableStop = False
      • Set KB3D_Zoffset = 700.00
      • Set KB3D_EndFx = Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
      • Set KB3D_EndTrigger = Slam End Trigger <gen>
      • Custom script: call ExecuteFunc( "KB3D_Registration" )
      • Custom script: call RemoveLocation(udg_P)
      • Custom script: call RemoveLocation(udg_P2)
The end of knockback 2 :

  • Slam End Trigger
    • Events
    • Conditions
    • Actions
      • Set P3 = (Position of KB3D_Unit)
      • Unit - Create 1 Lift Dummy for (Owner of KB3D_Unit) at P3 facing Default building facing (270.0) degrees
      • Unit - Add a 2.00 second Generic expiration timer to (Last created unit)
      • Unit - Add Slam Dummy Spell to (Last created unit)
      • Unit - Set level of Slam Dummy Spell for (Last created unit) to (Level of Slam for KB3D_Unit)
      • Unit - Order (Last created unit) to Human Mountain King - Thunder Clap
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
Please fix: When the flying unit is being KBed make it return to it's default flying height. Sometimes when you KBed flying units twice or multiple times the height of the flying units is already touching the floor when the KB is finished.
 
Level 7
Joined
Aug 11, 2010
Messages
269
Whenever I use the arrow model with the homing projectile option the arrow doesn't face the target. I need to fix this since it's really annoying. The missile will follow the target and everything just fine, just not FACE them.
And here's my script.

  • HELR Aimed Shot Effect
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to [Hero - Elven Ranger] - Aimed Shot
    • Actions
      • -------- - - - Set Important Variables - - - --------
      • Set TempPoint = (Position of (Triggering unit))
      • -------- - - - Spell Effect - - - --------
      • Unit - Create 1 [Hero - Elven Ranger] - Aimed Shot - (Projectile Dummy) for Neutral Passive at TempPoint facing Default building facing degrees
        • -------- - - - Spell Effect - - - --------
        • -------- - - - KB3D Data - - - --------
        • Set KB3D_Unit = (Last created unit)
        • Set KB3D_Targeted_Unit = (Target unit of ability being cast)
        • Set KB3D_HomingMissile = True
        • Set KB3D_FaceAngle = True
        • Set KB3D_DisableUnit = True
        • Set KB3D_Speed = 600.00
        • Set KB3D_Accel = 100.00
        • Set KB3D_EndTrigger = HELR Aimed Shot Collide <gen>
        • Set KB3D_AllowOutSiding = False
        • Set KB3D_EndWhenHit = True
        • Set KB3D_KillWhenHit = True
        • Custom script: call ExecuteFunc( "KB3D_Registration" )
        • -------- - - - - - - - - - - - - --------
        • Custom script: call RemoveLocation(udg_TempPoint)
        • -------- - - - - - - - - - - - - --------
 
Level 7
Joined
Aug 11, 2010
Messages
269
That's because your projectile dummy is "facing Default building facing degrees"

Change it to whatever the angle is from TempPoint to the position of (Target unit of abiliyt being cast)

You would think that were true, but it doesn't work like that unfortunately. Here's what I got below this, followed by the script.

Edit: I also just now tried putting the facingAngle true and it yielded the same results.

89xYFQk.jpg
  • HELR Aimed Shot Effect
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to [Hero - Elven Ranger] - Aimed Shot
    • Actions
      • -------- - - - Set Important Variables - - - --------
      • Set TempPointArray[1] = (Position of (Triggering unit))
      • Set TempPointArray[2] = (Position of (Target unit of ability being cast))
      • -------- - - - Spell Effect - - - --------
      • Unit - Create 1 [Hero - Elven Ranger] - Aimed Shot - (Projectile Dummy) for Neutral Passive at TempPointArray[1] facing (Angle from TempPointArray[1] to TempPointArray[2]) degrees
      • -------- - - - Spell Effect - - - --------
      • -------- - - - KB3D Data - - - --------
      • Set KB3D_Unit = (Last created unit)
      • Set KB3D_Targeted_Unit = (Target unit of ability being cast)
      • Set KB3D_HomingMissile = True
      • Set KB3D_FaceAngle = False
      • Set KB3D_DisableUnit = True
      • Set KB3D_Speed = 600.00
      • Set KB3D_Accel = 100.00
      • Set KB3D_EndTrigger = HELR Aimed Shot Collide <gen>
      • Set KB3D_AllowOutSiding = False
      • Set KB3D_EndWhenHit = True
      • Set KB3D_KillWhenHit = True
      • Custom script: call ExecuteFunc( "KB3D_Registration" )
      • -------- - - - - - - - - - - - - --------
      • -------- - - - - - - - - - - - - --------
 
Last edited:
Level 7
Joined
Aug 11, 2010
Messages
269
That's odd. Does it only happen for this unit/effect? If not, then the system is probably making the dummy units face that direction for whatever reason.
Nope. It happens for all the effects that I seen. Units, too. Theoretically if you modified the Zap ability with a slower projectile (so you can see it) and the priestess of the moon arrow, it should do the same as it's doing for me. Likewise, any other effect seems to be doing the same.
 
Level 7
Joined
Aug 11, 2010
Messages
269
Well if it happens for all the effects, then its the system's fault. I can see quickly that in the code it uses SetUnitFacing(), but given the complexity of a knockback system, I don't know what it is really for.
How strange. Oh well, I guess for now I'll just use BPower's GUI system. It seems to work fine, though, sadly, doesn't have arcing projectiles. Beggars can't be chooses I guess, haha! Thanks for your help though, +rep.
 
Top