• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

KB3D - Knock back 3D

Status
Not open for further replies.
Level 16
Joined
Jul 31, 2012
Messages
2,217
RELIVE

Chobibo, Malhorne Barry the Moose

We are back to work

(we need to add the timer thing PnF told me in the review which is the one chobibo told us before, anw, here are the codes and test map)

DOWNLOAD

JASS:
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           Knock-Back 3D  v. 1.2.0     [JASS - GUI]                      //
//                                                by JAD aka DotCa         //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           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 have default values:                       //
//                                                                         //
//     - KB3D_DestroyTree      == FALSE by defalut                         //
//     - KB3D_DisableUnit      == FALSE by defalut                         //
//     - KB3D_UnpathaableStop  == TRUE by defalut                          //
//                                                                         //
//  The System also uses Always positive values for some configurations    //
//  to not make the knockback go worng, those configurations are:          //
//                                                                         //
//         "KB3D_Range"  -  "KB3D_Speed"  -  "KB3D_ZOffset"                //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           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                        //
//    *Nestharus for his GetCollision function                             //
//    *Rheiko for Beta Stages Testings                                     //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           How to Import?                                                //
//                                                                         //
//  1. Check that Create Unkown Variables is ticked in your WE Settings    //
//  2. Copy the Paste this Trigger                                         //
//  3. Congratulations, the System is now implemented in your map          //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           How to Use?                                                   //
//                                                                         //
//  1. There are 3 Examples of use in the KB3D Example Folder              //
//  2. Documentations are there in each of the 3 examples to help you      //
//  3. The KB3D System is an Ultra-Purpose System where you can use it for://
//     -Projectiles, the system supports homming 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                                     //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           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 SaveAttackTypeHandle takes hashtable hash, integer parentKey, integer childKey, attacktype at returns nothing
    call SaveInteger(hash, parentKey, childKey, GetHandleId(at))
endfunction
function LoadAttackTypeHandle takes hashtable hash, integer parentKey, integer childKey returns attacktype
    return ConvertAttackType(LoadInteger(hash, parentKey, childKey))
endfunction

function SaveDamageTypeHandle takes hashtable hash, integer parentKey, integer childKey, damagetype dt returns nothing
    call SaveInteger(hash, parentKey, childKey, GetHandleId(dt))
endfunction
function LoadDamageTypeHandle takes hashtable hash, integer parentKey, integer childKey returns damagetype
    return ConvertDamageType(LoadInteger(hash, parentKey, childKey))
endfunction

function KB3D_AlwaysNeg takes real R returns real//Used for redering some values always lower than 0
    if R > 0 then
        set R = R * -1
    endif
    return R
endfunction

function KB3D_AlwaysPos takes real R returns real//Used for redering some values always higher than 0
    if R < 0 then
        set R = R * -1
    endif
    return R
endfunction

function KB3D_InBetween takes real Min, real R, real Max returns real//Used to maintain values between 2 others
    if R < Min then
        set R = Min
    else
        if R > Max then
            set R = Max
        endif
    endif
    return R
endfunction

function KB3D_RegisterUnitCollision takes unit u, real x, real y, integer i returns real //Somehow a library for UnitCollision function
    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//Used to know the collision of a unit //Credits to Netharus// converted by malhorne
    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_Registration takes nothing returns boolean//register an instance in the System
    local real Time
    local real R
    local real R1
    set udg_KB3D_Range = KB3D_AlwaysPos(udg_KB3D_Range)
    set udg_KB3D_Speed = KB3D_AlwaysPos(udg_KB3D_Speed) * 0.031250000
    set udg_KB3D_Counter = udg_KB3D_Counter + 1
    set udg_KB3D_Instances = udg_KB3D_Instances + 1
    set udg_KB3D_Zoffset = 1.85 * KB3D_AlwaysPos(udg_KB3D_Zoffset)
    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 )
    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 )
    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_Fx_Attach )
    if ( udg_KB3D_Accel == 0.00 ) then
        set Time = udg_KB3D_Range / (udg_KB3D_Speed / 0.031250000)//calculating time for the knockback if Acceleration = 0
    else
        if ( udg_KB3D_Accel > 0 ) then
            set Time = (( -2*(udg_KB3D_Speed / 0.031250000) + SquareRoot((4*udg_KB3D_Speed / 0.031250000) + (8*udg_KB3D_Accel*udg_KB3D_Range ) ) / (2*udg_KB3D_Accel) ))//calculating time for the knockback if Acceleration > 0
        endif
        if ( udg_KB3D_Accel < 0 ) then
            set R = ( - 1 * (udg_KB3D_Speed / 0.031250000) / udg_KB3D_Accel )
            set R1 = (0.5 * udg_KB3D_Accel * R * R) + ((udg_KB3D_Speed / 0.031250000) * R)
            if R1 < udg_KB3D_Range then
                set Time = R//calculating time for the knockback if Acceleration < 0 and if the speed will be = 0 before reaching max range
            else
                set Time = KB3D_AlwaysPos(( -2*(udg_KB3D_Speed / 0.031250000) + SquareRoot(KB3D_AlwaysPos((4*(udg_KB3D_Speed / 0.031250000)*(udg_KB3D_Speed / 0.031250000)) + (8*udg_KB3D_Accel*udg_KB3D_Range) )) ) / (2*udg_KB3D_Accel) )//calculating time for the knockback if Acceleration < 0 and if the speed will be > 0 before reaching max range
            endif
        endif
    endif
    call SaveReal( udg_KB3D_HA, 11, udg_KB3D_Counter, Time )
    call SaveBoolean( udg_KB3D_HA, 15, udg_KB3D_Counter, true )
    if UnitAddAbility(udg_KB3D_Unit, 'Amrf') then
        call UnitRemoveAbility(udg_KB3D_Unit, 'Amrf')
    endif
    if ( udg_KB3D_Counter == 1 ) then
        call EnableTrigger(udg_KB3D_Loop)
    endif
    call SaveReal( udg_KB3D_HA, 3, udg_KB3D_Counter, udg_KB3D_Zoffset )
    call SaveReal( udg_KB3D_HA, 12, udg_KB3D_Counter, (udg_KB3D_Zoffset / ( Time / 2)) )
    call SaveReal( udg_KB3D_HA, 13, udg_KB3D_Counter, KB3D_AlwaysNeg(( -1 * udg_KB3D_Zoffset / ( Time / 2) ) / ( Time / 2)) * 0.031250000 )
    if not (udg_KB3D_TrailFx == "") and not (udg_KB3D_Fx_Attach == "") then
        call SaveEffectHandle(udg_KB3D_HA, 14, udg_KB3D_Counter, AddSpecialEffectTarget(udg_KB3D_TrailFx, udg_KB3D_Unit, udg_KB3D_Fx_Attach))
    endif
    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 SaveAttackTypeHandle( udg_KB3D_HA, 20, udg_KB3D_Counter, udg_KB3D_AttackType )
    call SaveDamageTypeHandle( udg_KB3D_HA, 21, udg_KB3D_Counter, udg_KB3D_DamageType )
    call SaveUnitHandle( udg_KB3D_HA, 22, udg_KB3D_Counter, udg_KB3D_Damager )
    //Nulling
    set udg_KB3D_Accel = 0.00
    set udg_KB3D_Angle = 0.00
    set udg_KB3D_DestroyTree = false
    set udg_KB3D_DisableUnit = false
    set udg_KB3D_Fx = ""
    set udg_KB3D_Fx_Attach = ""
    set udg_KB3D_TrailFx = ""
    set udg_KB3D_Range = 0.00
    set udg_KB3D_Speed = 0.00
    set udg_KB3D_Targeted_Unit = null
    set udg_KB3D_Unit = null
    set udg_KB3D_UnpathableStop = true
    set udg_KB3D_Zoffset = 0.00
    return false
endfunction

function KB3D_Tree_Check takes destructable D returns boolean //Checks if a destructable is a tree
    local boolean B = false
    call IssueTargetOrder( udg_KB3D_Harvester, "harvest", D )
    if ( GetUnitCurrentOrder(udg_KB3D_Harvester) == OrderId("harvest") ) then
        set B = true
    endif
    call IssueImmediateOrder(udg_KB3D_Harvester, "stop")
    return B
endfunction

function KB3D_KillifTree takes destructable D returns nothing //Kills a destructable if it is a tree
    if ( KB3D_Tree_Check(D) ) then
        call KillDestructable(D)
    endif
endfunction

function KB3D_KillEnumDest takes nothing returns nothing //Function used in Enumeration loop
    call KB3D_KillifTree(GetEnumDestructable())
endfunction

function KB3D_CircleTreeKill takes real radius, real x, real y returns nothing//To destroy trees around the unit
    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_CW_Loop takes nothing returns nothing//function for item group loop for Check Walkability System
    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//Check Walkability System by PnF
    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
    set udg_CP_PointIsWalkable = ((x2-x)*(x2-x) + (y2-y)*(y2-y) <= 100) and (not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY))
    return udg_CP_PointIsWalkable
endfunction

function MoveUnit_3D takes unit U, real x, real y, real z, boolean B returns nothing
    call SetUnitFlyHeight(U, KB3D_InBetween(GetUnitDefaultFlyHeight(U), z, 9999), 0)
    if ( not(B) or ( KB3D_CW(x, y) ) ) then
        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]))
    endif
endfunction

function KB3D_Loop takes integer Loop returns nothing//Main Trigger Loop
    //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
    local real y
    local real 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 unit Target = LoadUnitHandle(udg_KB3D_HA, 5, Loop)
    local unit Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
    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 string Fx = LoadStr(udg_KB3D_HA, 9, Loop)
    local string Attach = LoadStr(udg_KB3D_HA, 10, Loop)
    local attacktype AType = LoadAttackTypeHandle(udg_KB3D_HA, 20, Loop)
    local damagetype DType = LoadDamageTypeHandle(udg_KB3D_HA, 21, Loop)
    //end of locals
    if not (LoopD == 0) and not (Damager == null ) then//damage target with loop damage
        call UnitDamageTarget(Damager, U, LoopD, true, false, AType, DType, WEAPON_TYPE_WHOKNOWS)
    endif
    if ( Target == null ) then//know the angle of knockback line
        set Angle = LoadReal(udg_KB3D_HA, 5, Loop)//if there is no unit target
    else
        set Angle = Atan2(GetUnitY(Target) - Y, GetUnitX(Target) - X)//if there is a unit target
    endif
    set Speed = Speed + ( Accel )//Increase the KB speed depending on the Acceleration
    set Range = Range - ( Speed )//Decrease distance traveled
    set ZSpeed = ZSpeed + ( ZAccel )//change the fly changing rate //Acceleration is for smoothness
    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 z = Z + ( ZSpeed * 0.031250000 )//new Z Offset of the KBed unit
    call MoveUnit_3D(U, x, y, z, UnpathableStop)//Move the unit according to the X, Y, Z
    if (DestroyTree) then//Check if Destroy Tree is enabled
        call KB3D_CircleTreeKill( 4 * KB3D_GetUnitCollision(U), x, y )//Destroy trees around target
    endif
    if not (Fx == "") then//create an effect on the unit
        if ( z > 20 ) then
            if not (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
    if ( (UnpathableStop) and not ( KB3D_CW(x, y) ) ) and (not (ImpactD == 0) and not (Damager == null ) and ( KB3D_CW(x, y) )) then//if the terrain is unpathable or if unpathable stop is disabled then..
        call UnitDamageTarget(Damager, U, ImpactD * 0.031250000, true, false, AType, DType, WEAPON_TYPE_WHOKNOWS)//Apply Impact Damage to the unit
    endif
    if ( DisableUnit ) then//disable the unit partially
        call SetUnitPropWindow(U, 0)
        call SetUnitTurnSpeed(U, 0)
    endif
    ////// Stop All
    if ( (Speed <= 0) or ( Range <= 0 ) or ( GetWidgetLife(U) <= 0 ) ) then
        call SaveBoolean(udg_KB3D_HA, 15, Loop, false)
        set udg_KB3D_Instances = udg_KB3D_Instances - 1
        call SaveReal(udg_KB3D_HA, 0, -1 * GetHandleId(U), LoadReal(udg_KB3D_HA, 0, -1 * GetHandleId(U))-1)
        call SetUnitFlyHeight(U, KB3D_InBetween(GetUnitDefaultFlyHeight(U), z - 15, 9999), 0)
        if ( GetWidgetLife(U) <= 0 ) then
            call SetUnitFlyHeight(U, GetUnitDefaultFlyHeight(U), 750 )
        endif
        if DisableUnit then
            call SetUnitPropWindow(U, GetUnitDefaultPropWindow(U))
            call SetUnitTurnSpeed(U, GetUnitDefaultTurnSpeed(U))
        endif
        if HaveSavedHandle(udg_KB3D_HA, 14, Loop) then
            call DestroyEffect(LoadEffectHandle(udg_KB3D_HA, 14, Loop))
            call RemoveSavedHandle(udg_KB3D_HA, 14, Loop)
        endif
    else
        ////// Save Changes
        call SaveReal(udg_KB3D_HA, 1, Loop, Range)
        call SaveReal(udg_KB3D_HA, 2, Loop, Speed)
        call SaveReal(udg_KB3D_HA, 12, Loop, ZSpeed)
    endif
    ////// Clear
    set U = null
    set Target = null
endfunction

function KB3D_Loop_Actions takes nothing returns boolean//loop triggerer
    local integer x = 0
    loop
        exitwhen x >= udg_KB3D_Counter
        set x = x + 1
        if ( LoadBoolean(udg_KB3D_HA, 15, x) ) then
            call KB3D_Loop(x)
        endif
    endloop
    if ( udg_KB3D_Instances == 0 ) then
        set udg_KB3D_Counter = 0
        call DisableTrigger(GetTriggeringTrigger())
    endif
    return false
endfunction

//===========================================================================
function InitTrig_KB3D takes nothing returns nothing
    ////////LOOP
    set udg_KB3D_Loop = CreateTrigger(  )
    call TriggerRegisterTimerEvent( udg_KB3D_Loop, 0.031250000, true )
    call TriggerAddCondition( udg_KB3D_Loop, Condition(function KB3D_Loop_Actions) )
    call DisableTrigger( udg_KB3D_Loop )
    ////////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')
    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)
endfunction
 
Level 22
Joined
Sep 24, 2005
Messages
4,821

JASS:
// Just fix the syntax errors, I did this on notepad++ so it's not validated.
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           Knock-Back 3D  v. 1.2.0     [JASS - GUI]                      //
//                                                by JAD aka DotCa         //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           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 have default values:                       //
//                                                                         //
//     - KB3D_DestroyTree      == FALSE by defalut                         //
//     - KB3D_DisableUnit      == FALSE by defalut                         //
//     - KB3D_UnpathaableStop  == TRUE by defalut                          //
//                                                                         //
//  The System also uses Always positive values for some configurations    //
//  to not make the knockback go worng, those configurations are:          //
//                                                                         //
//         "KB3D_Range"  -  "KB3D_Speed"  -  "KB3D_ZOffset"                //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           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                        //
//    *Nestharus for his GetCollision function                             //
//    *Rheiko for Beta Stages Testings                                     //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           How to Import?                                                //
//                                                                         //
//  1. Check that Create Unkown Variables is ticked in your WE Settings    //
//  2. Copy the Paste this Trigger                                         //
//  3. Congratulations, the System is now implemented in your map          //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           How to Use?                                                   //
//                                                                         //
//  1. There are 3 Examples of use in the KB3D Example Folder              //
//  2. Documentations are there in each of the 3 examples to help you      //
//  3. The KB3D System is an Ultra-Purpose System where you can use it for://
//     -Projectiles, the system supports homming 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                                     //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           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 SaveAttackTypeHandle takes hashtable hash, integer parentKey, integer childKey, attacktype at returns nothing
    call SaveInteger(hash, parentKey, childKey, GetHandleId(at))
endfunction
function LoadAttackTypeHandle takes hashtable hash, integer parentKey, integer childKey returns attacktype
    return ConvertAttackType(LoadInteger(hash, parentKey, childKey))
endfunction

function SaveDamageTypeHandle takes hashtable hash, integer parentKey, integer childKey, damagetype dt returns nothing
    call SaveInteger(hash, parentKey, childKey, GetHandleId(dt))
endfunction
function LoadDamageTypeHandle takes hashtable hash, integer parentKey, integer childKey returns damagetype
    return ConvertDamageType(LoadInteger(hash, parentKey, childKey))
endfunction

function KB3D_AlwaysNeg takes real R returns real//Used for redering some values always lower than 0
    if R > 0 then
        set R = R * -1
    endif
    return R
endfunction

function KB3D_AlwaysPos takes real R returns real//Used for redering some values always higher than 0
    if R < 0 then
        set R = R * -1
    endif
    return R
endfunction

function KB3D_InBetween takes real Min, real R, real Max returns real//Used to maintain values between 2 others
    if R < Min then
        set R = Min
    else
        if R > Max then
            set R = Max
        endif
    endif
    return R
endfunction

function KB3D_RegisterUnitCollision takes unit u, real x, real y, integer i returns real //Somehow a library for UnitCollision function
    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//Used to know the collision of a unit //Credits to Netharus// converted by malhorne
    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 //Checks if a destructable is a tree
    local boolean B = false
    call IssueTargetOrder( udg_KB3D_Harvester, "harvest", D )
    if ( GetUnitCurrentOrder(udg_KB3D_Harvester) == OrderId("harvest") ) then
        set B = true
    endif
    call IssueImmediateOrder(udg_KB3D_Harvester, "stop")
    return B
endfunction

function KB3D_KillifTree takes destructable D returns nothing //Kills a destructable if it is a tree
    if ( KB3D_Tree_Check(D) ) then
        call KillDestructable(D)
    endif
endfunction

function KB3D_KillEnumDest takes nothing returns nothing //Function used in Enumeration loop
    call KB3D_KillifTree(GetEnumDestructable())
endfunction

function KB3D_CircleTreeKill takes real radius, real x, real y returns nothing//To destroy trees around the unit
    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_CW_Loop takes nothing returns nothing//function for item group loop for Check Walkability System
    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//Check Walkability System by PnF
    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
    set udg_CP_PointIsWalkable = ((x2-x)*(x2-x) + (y2-y)*(y2-y) <= 100) and (not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY))
    return udg_CP_PointIsWalkable
endfunction

function MoveUnit_3D takes unit U, real x, real y, real z, boolean B returns nothing
    call SetUnitFlyHeight(U, KB3D_InBetween(GetUnitDefaultFlyHeight(U), z, 9999), 0)
    if ( not(B) or ( KB3D_CW(x, y) ) ) then
        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]))
    endif
endfunction

function KB3D_Loop takes integer Loop returns nothing//Main Trigger Loop
    //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
    local real y
    local real 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 unit Target = LoadUnitHandle(udg_KB3D_HA, 5, Loop)
    local unit Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
    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 string Fx = LoadStr(udg_KB3D_HA, 9, Loop)
    local string Attach = LoadStr(udg_KB3D_HA, 10, Loop)
    local attacktype AType = LoadAttackTypeHandle(udg_KB3D_HA, 20, Loop)
    local damagetype DType = LoadDamageTypeHandle(udg_KB3D_HA, 21, Loop)
    //end of locals
    if not (LoopD == 0) and not (Damager == null ) then//damage target with loop damage
        call UnitDamageTarget(Damager, U, LoopD, true, false, AType, DType, WEAPON_TYPE_WHOKNOWS)
    endif
    if ( Target == null ) then//know the angle of knockback line
        set Angle = LoadReal(udg_KB3D_HA, 5, Loop)//if there is no unit target
    else
        set Angle = Atan2(GetUnitY(Target) - Y, GetUnitX(Target) - X)//if there is a unit target
    endif
    set Speed = Speed + ( Accel )//Increase the KB speed depending on the Acceleration
    set Range = Range - ( Speed )//Decrease distance traveled
    set ZSpeed = ZSpeed + ( ZAccel )//change the fly changing rate //Acceleration is for smoothness
    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 z = Z + ( ZSpeed * 0.031250000 )//new Z Offset of the KBed unit
    call MoveUnit_3D(U, x, y, z, UnpathableStop)//Move the unit according to the X, Y, Z
    if (DestroyTree) then//Check if Destroy Tree is enabled
        call KB3D_CircleTreeKill( 4 * KB3D_GetUnitCollision(U), x, y )//Destroy trees around target
    endif
    if not (Fx == "") then//create an effect on the unit
        if ( z > 20 ) then
            if not (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
    if ( (UnpathableStop) and not ( KB3D_CW(x, y) ) ) and (not (ImpactD == 0) and not (Damager == null ) and ( KB3D_CW(x, y) )) then//if the terrain is unpathable or if unpathable stop is disabled then..
        call UnitDamageTarget(Damager, U, ImpactD * 0.031250000, true, false, AType, DType, WEAPON_TYPE_WHOKNOWS)//Apply Impact Damage to the unit
    endif
    if ( DisableUnit ) then//disable the unit partially
        call SetUnitPropWindow(U, 0)
        call SetUnitTurnSpeed(U, 0)
    endif
    ////// Stop All
    if ( (Speed <= 0) or ( Range <= 0 ) or ( GetWidgetLife(U) <= 0 ) ) then
        call SaveBoolean(udg_KB3D_HA, 15, Loop, false)
        set udg_KB3D_Instances = udg_KB3D_Instances - 1
        call SaveReal(udg_KB3D_HA, 0, -1 * GetHandleId(U), LoadReal(udg_KB3D_HA, 0, -1 * GetHandleId(U))-1)
        call SetUnitFlyHeight(U, KB3D_InBetween(GetUnitDefaultFlyHeight(U), z - 15, 9999), 0)
        if ( GetWidgetLife(U) <= 0 ) then
            call SetUnitFlyHeight(U, GetUnitDefaultFlyHeight(U), 750 )
        endif
        if DisableUnit then
            call SetUnitPropWindow(U, GetUnitDefaultPropWindow(U))
            call SetUnitTurnSpeed(U, GetUnitDefaultTurnSpeed(U))
        endif
        if HaveSavedHandle(udg_KB3D_HA, 14, Loop) then
            call DestroyEffect(LoadEffectHandle(udg_KB3D_HA, 14, Loop))
            call RemoveSavedHandle(udg_KB3D_HA, 14, Loop)
        endif
    else
        ////// Save Changes
        call SaveReal(udg_KB3D_HA, 1, Loop, Range)
        call SaveReal(udg_KB3D_HA, 2, Loop, Speed)
        call SaveReal(udg_KB3D_HA, 12, Loop, ZSpeed)
    endif
    ////// Clear
    set U = null
    set Target = null
endfunction

function KB3D_Loop_Actions takes nothing returns boolean//loop triggerer
    local integer x = 0
    loop
        exitwhen x >= udg_KB3D_Counter
        set x = x + 1
        if ( LoadBoolean(udg_KB3D_HA, 15, x) ) then
            call KB3D_Loop(x)
        endif
    endloop
    if ( udg_KB3D_Instances == 0 ) then
        set udg_KB3D_Counter = 0
        //call DisableTrigger(GetTriggeringTrigger())
		call PauseTimer(udg_KB3D_Loop_Timer)
    endif
    return false
endfunction

// Registration moved here so that the timer can call the loop function.
function KB3D_Registration takes nothing returns boolean//register an instance in the System
    local real Time
    local real R
    local real R1
    set udg_KB3D_Range = KB3D_AlwaysPos(udg_KB3D_Range)
    set udg_KB3D_Speed = KB3D_AlwaysPos(udg_KB3D_Speed) * 0.031250000
    set udg_KB3D_Counter = udg_KB3D_Counter + 1
    set udg_KB3D_Instances = udg_KB3D_Instances + 1
    set udg_KB3D_Zoffset = 1.85 * KB3D_AlwaysPos(udg_KB3D_Zoffset)
    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 )
    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 )
    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_Fx_Attach )
    if ( udg_KB3D_Accel == 0.00 ) then
        set Time = udg_KB3D_Range / (udg_KB3D_Speed / 0.031250000)//calculating time for the knockback if Acceleration = 0
    else
        if ( udg_KB3D_Accel > 0 ) then
            set Time = (( -2*(udg_KB3D_Speed / 0.031250000) + SquareRoot((4*udg_KB3D_Speed / 0.031250000) + (8*udg_KB3D_Accel*udg_KB3D_Range ) ) / (2*udg_KB3D_Accel) ))//calculating time for the knockback if Acceleration > 0
        endif
        if ( udg_KB3D_Accel < 0 ) then
            set R = ( - 1 * (udg_KB3D_Speed / 0.031250000) / udg_KB3D_Accel )
            set R1 = (0.5 * udg_KB3D_Accel * R * R) + ((udg_KB3D_Speed / 0.031250000) * R)
            if R1 < udg_KB3D_Range then
                set Time = R//calculating time for the knockback if Acceleration < 0 and if the speed will be = 0 before reaching max range
            else
                set Time = KB3D_AlwaysPos(( -2*(udg_KB3D_Speed / 0.031250000) + SquareRoot(KB3D_AlwaysPos((4*(udg_KB3D_Speed / 0.031250000)*(udg_KB3D_Speed / 0.031250000)) + (8*udg_KB3D_Accel*udg_KB3D_Range) )) ) / (2*udg_KB3D_Accel) )//calculating time for the knockback if Acceleration < 0 and if the speed will be > 0 before reaching max range
            endif
        endif
    endif
    call SaveReal( udg_KB3D_HA, 11, udg_KB3D_Counter, Time )
    call SaveBoolean( udg_KB3D_HA, 15, udg_KB3D_Counter, true )
    if UnitAddAbility(udg_KB3D_Unit, 'Amrf') then
        call UnitRemoveAbility(udg_KB3D_Unit, 'Amrf')
    endif
    if ( udg_KB3D_Counter == 1 ) then
        //call EnableTrigger(udg_KB3D_Loop)
		call TimerStart(udg_KB3D_Loop_Timer, 0.031250000, true, function KB3D_Loop_Actions )
    endif
    call SaveReal( udg_KB3D_HA, 3, udg_KB3D_Counter, udg_KB3D_Zoffset )
    call SaveReal( udg_KB3D_HA, 12, udg_KB3D_Counter, (udg_KB3D_Zoffset / ( Time / 2)) )
    call SaveReal( udg_KB3D_HA, 13, udg_KB3D_Counter, KB3D_AlwaysNeg(( -1 * udg_KB3D_Zoffset / ( Time / 2) ) / ( Time / 2)) * 0.031250000 )
    if not (udg_KB3D_TrailFx == "") and not (udg_KB3D_Fx_Attach == "") then
        call SaveEffectHandle(udg_KB3D_HA, 14, udg_KB3D_Counter, AddSpecialEffectTarget(udg_KB3D_TrailFx, udg_KB3D_Unit, udg_KB3D_Fx_Attach))
    endif
    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 SaveAttackTypeHandle( udg_KB3D_HA, 20, udg_KB3D_Counter, udg_KB3D_AttackType )
    call SaveDamageTypeHandle( udg_KB3D_HA, 21, udg_KB3D_Counter, udg_KB3D_DamageType )
    call SaveUnitHandle( udg_KB3D_HA, 22, udg_KB3D_Counter, udg_KB3D_Damager )
    //Nulling
    set udg_KB3D_Accel = 0.00
    set udg_KB3D_Angle = 0.00
    set udg_KB3D_DestroyTree = false
    set udg_KB3D_DisableUnit = false
    set udg_KB3D_Fx = ""
    set udg_KB3D_Fx_Attach = ""
    set udg_KB3D_TrailFx = ""
    set udg_KB3D_Range = 0.00
    set udg_KB3D_Speed = 0.00
    set udg_KB3D_Targeted_Unit = null
    set udg_KB3D_Unit = null
    set udg_KB3D_UnpathableStop = true
    set udg_KB3D_Zoffset = 0.00
    return false
endfunction

//===========================================================================
function InitTrig_KB3D takes nothing returns nothing
	// Timer implementation
	// set udg_KB3D_Loop_Timer=CreateTimer() // Variable Editor already assigns a new timer handle at declaration.
	
    ////////LOOP
    //set udg_KB3D_Loop = CreateTrigger(  )
    //call TriggerRegisterTimerEvent( udg_KB3D_Loop, 0.031250000, true )
    //call TriggerAddCondition( udg_KB3D_Loop, Condition(function KB3D_Loop_Actions) )
    //call DisableTrigger( udg_KB3D_Loop )
    ////////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')
    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)
endfunction
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Hey, you forgot to credit Vexorian on the GetUnitCollision function, Nestharus improved the accuracyprecision, but Vexorian was the origin of the script, here is proof: [GetUnitCollisonSize]

Oh, isn't there something like: PasuTimer?
JASS:
function KB3D_Loop_Actions takes nothing returns boolean//loop triggerer
    local integer x = 0
    loop
        exitwhen x >= udg_KB3D_Counter
        set x = x + 1
        if ( LoadBoolean(udg_KB3D_HA, 15, x) ) then
            call KB3D_Loop(x)
        endif
    endloop
    if ( udg_KB3D_Instances == 0 ) then
        set udg_KB3D_Counter = 0
        //call DisableTrigger(GetTriggeringTrigger())
        call PauseTimer(udg_KB3D_Loop_Timer)
    endif
    return false
endfunction
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
Is there a problem with the prop window still or not ?
Since i'll have to work for school and for a request (and many others but i'm already late so they can still wait xD (no i'm just trolling since i have to test and improve many things even recode the entire first request in the spell workshop ...) ) :)
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
JASS:
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           Knock-Back 3D  v. 1.3.0     [JASS - GUI]                      //
//                                                by JAD aka DotCa         //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           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 have default values:                       //
//                                                                         //
//     - KB3D_DestroyTree      == FALSE by default                         //
//     - KB3D_DisableUnit      == FALSE by default                         //
//     - KB3D_UnpathaableStop  == TRUE  by default                         //
//                                                                         //
//  The System also uses Always positive values for some configurations    //
//  to not make the knockback go worng, those configurations are:          //
//                                                                         //
//         "KB3D_Range"  -  "KB3D_Speed"  -  "KB3D_ZOffset"                //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           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                  //
//    *Rheiko for Beta Stages Testings                                     //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           How to Import?                                                //
//                                                                         //
//  1. Check that Create Unknown Variables is ticked in your WE Settings   //
//  2. Copy the Paste this Trigger                                         //
//  3. Congratulations, the System is now implemented in your map          //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           How to Use?                                                   //
//                                                                         //
//  1. There are 3 Examples of use in the KB3D Example Folder              //
//  2. Documentations are there in each of the 3 examples 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                                     //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           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 SaveAttackTypeHandle takes hashtable hash, integer parentKey, integer childKey, attacktype at returns nothing
    call SaveInteger(hash, parentKey, childKey, GetHandleId(at))
endfunction
function LoadAttackTypeHandle takes hashtable hash, integer parentKey, integer childKey returns attacktype
    return ConvertAttackType(LoadInteger(hash, parentKey, childKey))
endfunction

function SaveDamageTypeHandle takes hashtable hash, integer parentKey, integer childKey, damagetype dt returns nothing
    call SaveInteger(hash, parentKey, childKey, GetHandleId(dt))
endfunction
function LoadDamageTypeHandle takes hashtable hash, integer parentKey, integer childKey returns damagetype
    return ConvertDamageType(LoadInteger(hash, parentKey, childKey))
endfunction

function KB3D_AlwaysNeg takes real R returns real//Used for redering some values always lower than 0
    if R > 0 then
        set R = R * -1
    endif
    return R
endfunction

function KB3D_AlwaysPos takes real R returns real//Used for redering some values always higher than 0
    if R < 0 then
        set R = R * -1
    endif
    return R
endfunction

function KB3D_InBetween takes real Min, real R, real Max returns real//Used to maintain values between 2 others
    if R < Min then
        set R = Min
    else
        if R > Max then
            set R = Max
        endif
    endif
    return R
endfunction

function KB3D_RegisterUnitCollision takes unit u, real x, real y, integer i returns real //Somehow a library for UnitCollision function
    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//Used to know the collision of a unit //Credits to Netharus// converted by malhorne
    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 //Checks if a destructable is a tree
    local boolean B = false
    call IssueTargetOrder( udg_KB3D_Harvester, "harvest", D )
    if ( GetUnitCurrentOrder(udg_KB3D_Harvester) == OrderId("harvest") ) then
        set B = true
    endif
    call IssueImmediateOrder(udg_KB3D_Harvester, "stop")
    return B
endfunction

function KB3D_KillifTree takes destructable D returns nothing //Kills a destructable if it is a tree
    if ( KB3D_Tree_Check(D) ) then
        call KillDestructable(D)
    endif
endfunction

function KB3D_KillEnumDest takes nothing returns nothing //Function used in Enumeration loop
    call KB3D_KillifTree(GetEnumDestructable())
endfunction

function KB3D_CircleTreeKill takes real radius, real x, real y returns nothing//To destroy trees around the unit
    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_CW_Loop takes nothing returns nothing//function for item group loop for Check Walkability System
    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//Check Walkability System by PnF
    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
    set udg_CP_PointIsWalkable = ((x2-x)*(x2-x) + (y2-y)*(y2-y) <= 100) and (not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY))
    return udg_CP_PointIsWalkable
endfunction

function MoveUnit_3D takes unit U, real x, real y, real z, boolean B returns nothing
    call SetUnitFlyHeight(U, KB3D_InBetween(GetUnitDefaultFlyHeight(U), z, 9999), 0)
    if ( not(B) or ( KB3D_CW(x, y) ) ) then
        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]))
    endif
endfunction

function KB3D_Loop takes integer Loop returns nothing//Main Trigger Loop
    //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
    local real y
    local real 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 R
    local unit Target = LoadUnitHandle(udg_KB3D_HA, 5, Loop)
    local unit Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
    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 string Fx = LoadStr(udg_KB3D_HA, 9, Loop)
    local string Attach = LoadStr(udg_KB3D_HA, 10, Loop)
    local attacktype AType = LoadAttackTypeHandle(udg_KB3D_HA, 20, Loop)
    local damagetype DType = LoadDamageTypeHandle(udg_KB3D_HA, 21, Loop)
    //end of locals
    if not (LoopD == 0) and not (Damager == null ) then//damage target with loop damage
        call UnitDamageTarget(Damager, U, LoopD, true, false, AType, DType, WEAPON_TYPE_WHOKNOWS)
    endif
    if ( Target == null ) then//know the angle of knockback line
        set Angle = LoadReal(udg_KB3D_HA, 5, Loop)//if there is no unit target
    else
        set Angle = Atan2(GetUnitY(Target) - Y, GetUnitX(Target) - X)//if there is a unit target
    endif
    set Speed = Speed + ( Accel )//Increase the KB speed depending on the Acceleration
    set Range = Range - ( Speed )//Decrease distance traveled
    set ZSpeed = ZSpeed + ( ZAccel )//change the fly changing rate //Acceleration is for smoothness
    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 z = Z + ( ZSpeed * 0.031250000 )//new Z Offset of the KBed unit
    call MoveUnit_3D(U, x, y, z, UnpathableStop)//Move the unit according to the X, Y, Z
    if (DestroyTree) then//Check if Destroy Tree is enabled
        call KB3D_CircleTreeKill( KB3D_InBetween(100, 4 * KB3D_GetUnitCollision(U), 500), x, y )//Destroy trees around target
    endif
    if not (Fx == "") then//create an effect on the unit
        if ( z > 20 ) then
            if not (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
    if ( (UnpathableStop) and not ( KB3D_CW(x, y) ) ) and (not (ImpactD == 0) and not (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, WEAPON_TYPE_WHOKNOWS)//Apply Impact Damage to the unit
            call SaveBoolean(udg_KB3D_HA, 23, Loop, false)
        endif
    endif
    if ( DisableUnit ) then//disable the unit partially
        call SetUnitPropWindow(U, 0)
        call SetUnitTurnSpeed(U, 0)
    endif
    if not(Target == null) then
        if (SquareRoot ( ( GetUnitX(Target) - x ) * ( GetUnitX(Target) - x ) + ( GetUnitY(Target) - y ) * ( GetUnitY(Target) - y ) ) < KB3D_InBetween(25, KB3D_GetUnitCollision(U), 999)) then
            if not (TargetD == 0) and not(Damager == null) then
                call UnitDamageTarget(Damager, U, TargetD, true, false, AType, DType, WEAPON_TYPE_WHOKNOWS)
                call SaveReal(udg_KB3D_HA, 19, Loop, 0)
            endif
            if (KillWhenHit) then
                call KillUnit(U)
            endif
            if (EndWhenHit) then
                call SaveReal(udg_KB3D_HA, 4, Loop, Speed / 0.030000000)
                call SaveReal(udg_KB3D_HA, 13, Loop, ZSpeed / 0.030000000)
            endif
        endif
    endif
    ////// Stop All
    if ( (Speed <= 0) or ( Range <= 0 ) or ( GetWidgetLife(U) <= 0 ) ) then
        call SaveBoolean(udg_KB3D_HA, 15, Loop, false)
        set udg_KB3D_Instances = udg_KB3D_Instances - 1
        call SaveReal(udg_KB3D_HA, 0, -1 * GetHandleId(U), LoadReal(udg_KB3D_HA, 0, -1 * GetHandleId(U))-1)
        call SetUnitFlyHeight(U, KB3D_InBetween(GetUnitDefaultFlyHeight(U), z - 15, 9999), 0)
        if ( GetWidgetLife(U) <= 0 ) then
            call SetUnitFlyHeight(U, GetUnitDefaultFlyHeight(U), 750 )
        endif
        set R = GetUnitDefaultPropWindow(U)
        call SetUnitPropWindow(U, R)
        call SetUnitTurnSpeed(U, GetUnitDefaultTurnSpeed(U))
        if HaveSavedHandle(udg_KB3D_HA, 14, Loop) then
            call DestroyEffect(LoadEffectHandle(udg_KB3D_HA, 14, Loop))
            call RemoveSavedHandle(udg_KB3D_HA, 14, Loop)
        endif
    else
        ////// Save Changes
        call SaveReal(udg_KB3D_HA, 1, Loop, Range)
        call SaveReal(udg_KB3D_HA, 2, Loop, Speed)
        call SaveReal(udg_KB3D_HA, 12, Loop, ZSpeed)
    endif
    ////// Clear
    set U = null
    set Target = null
endfunction

function KB3D_Loop_Actions takes nothing returns nothing//loop triggerer
    local integer x = 0
    loop
        exitwhen x >= udg_KB3D_Counter
        set x = x + 1
        if ( LoadBoolean(udg_KB3D_HA, 15, 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
endfunction

function KB3D_Registration takes nothing returns boolean//register an instance in the System
    local real Time
    local real R
    local real R1
    set udg_KB3D_Range = KB3D_AlwaysPos(udg_KB3D_Range)
    set udg_KB3D_Speed = KB3D_AlwaysPos(udg_KB3D_Speed)
    set udg_KB3D_Counter = udg_KB3D_Counter + 1
    set udg_KB3D_Instances = udg_KB3D_Instances + 1
    set udg_KB3D_Zoffset = 1.85 * KB3D_AlwaysPos(udg_KB3D_Zoffset)
    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 )
    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_Fx_Attach )
    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 = (( -2*(udg_KB3D_Speed) + SquareRoot((4*udg_KB3D_Speed) + (8*udg_KB3D_Accel*udg_KB3D_Range ) ) / (2*udg_KB3D_Accel) ))//calculating time for the knockback if Acceleration > 0
        endif
        if ( udg_KB3D_Accel < 0 ) then
            set R = ( - 1 * (udg_KB3D_Speed) / udg_KB3D_Accel )
            set R1 = (0.5 * udg_KB3D_Accel * R * R) + ((udg_KB3D_Speed) * R)
            if R1 < udg_KB3D_Range then
                set Time = R//calculating time for the knockback if Acceleration < 0 and if the speed will be = 0 before reaching max range
            else
                set Time = KB3D_AlwaysPos(( -2*(udg_KB3D_Speed) + SquareRoot(KB3D_AlwaysPos((4*(udg_KB3D_Speed)*(udg_KB3D_Speed)) + (8*udg_KB3D_Accel*udg_KB3D_Range) )) ) / (2*udg_KB3D_Accel) )//calculating time for the knockback if Acceleration < 0 and if the speed will be > 0 before reaching max range
            endif
        endif
    endif
    call SaveReal( udg_KB3D_HA, 11, udg_KB3D_Counter, Time )
    call SaveBoolean( udg_KB3D_HA, 15, 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, (udg_KB3D_Zoffset / ( Time / 2)) )
    call SaveReal( udg_KB3D_HA, 13, udg_KB3D_Counter, KB3D_AlwaysNeg(( -1 * udg_KB3D_Zoffset / ( Time / 2) ) / ( Time / 2)) * 0.031250000 )
    if not (udg_KB3D_TrailFx == "") and not (udg_KB3D_Fx_Attach == "") then
        call SaveEffectHandle(udg_KB3D_HA, 14, udg_KB3D_Counter, AddSpecialEffectTarget(udg_KB3D_TrailFx, udg_KB3D_Unit, udg_KB3D_Fx_Attach))
    endif
    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 SaveAttackTypeHandle( udg_KB3D_HA, 20, udg_KB3D_Counter, udg_KB3D_AttackType )
    call SaveDamageTypeHandle( udg_KB3D_HA, 21, udg_KB3D_Counter, 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 )
    if (udg_KB3D_KillWhenHit) then
        set udg_KB3D_EndWhenHit = true
    endif
    call SaveBoolean( udg_KB3D_HA, 25, udg_KB3D_Counter, udg_KB3D_EndWhenHit )
    //Nulling
    set udg_KB3D_Accel = 0.00
    set udg_KB3D_Angle = 0.00
    set udg_KB3D_DestroyTree = false
    set udg_KB3D_DisableUnit = false
    set udg_KB3D_Fx = ""
    set udg_KB3D_Fx_Attach = ""
    set udg_KB3D_TrailFx = ""
    set udg_KB3D_Range = 0.00
    set udg_KB3D_Speed = 0.00
    set udg_KB3D_Targeted_Unit = null
    set udg_KB3D_Unit = null
    set udg_KB3D_UnpathableStop = true
    set udg_KB3D_Zoffset = 0.00
    if ( udg_KB3D_Counter == 1 ) then
        call TimerStart(udg_KB3D_Timer, 0.031250000, true, function KB3D_Loop_Actions )
    endif
    return 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')
    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)
endfunction
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
JASS:
local rect r = Rect(enter coordinates)
local group g = CreateGroup()
local unit FoG
call GroupEnumUnitsInRect(g,r,null)
loop
    set FoG = FirstOfGroup(g)
    exitwhen FoG == null
    call GroupRemoveUnit(g,FoG)
    call UnitDamageTarget(...)
endloop
call DestroyGroup(g)
call RemoveRect(r)
set g = null
set r = null
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
hmmmmm, i start to understand... but i don't think that's the thing we should do
tell me if i'm wrong: at cast, we create a group and save it, then while looping, we remove the units in the group and damage them... if that's the case, the the homing system in the knockback will not work perfectly with it, meaning the rect will change...
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
JASS:
    struct Missile
        unit missile
        unit caster
        boolean first
        boolean ally
        real radius
        real X
        real Y
        integer steps
        real dmg
        
        private static method Periodic takes nothing returns nothing
            local timer t = GetExpiredTimer()
            local thistype this = tab[t]
            local real x = GetUnitX(missile) + X
            local real y = GetUnitY(missile) + Y
            local group g = CreateGroup()
            local unit u
            call SetUnitPosition(missile, x, y)
            call GroupEnumUnitsInRange(g, x, y, radius, null)
            loop
                set u = FirstOfGroup(g)
                exitwhen u == null
                call GroupRemoveUnit(g, u)
                if ally or not IsUnitAlly( u, GetOwningPlayer(caster) ) then
                    call UnitDamageTarget( caster, u, dmg, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_MAGIC, null )
                    if first then
                        call RemoveUnit(u)
                        call tab.flush(t)
                        call PauseTimer(t)
                        call DestroyTimer(t)
                        set caster = null
                        set missile = null
                        call this.destroy()
                    endif
                endif
            endloop
            set steps = steps - 1
            if steps == 0 then
                call RemoveUnit(u)
                call tab.flush(t)
                call PauseTimer(t)
                call DestroyTimer(t)
                set caster = null
                set missile = null
                call this.destroy()
            endif
            call DestroyGroup(g)
            set g = null
            set t = null
        endmethod
        
        static method Instanciate takes unit m, unit c, boolean b, boolean b1, real r, real x, real y, real speed, real dmg returns nothing
            local thistype this = thistype.allocate()
            local real dist
            local real angle
            local timer t = CreateTimer()
            set tab[t] = this
            set missile = m
            set caster = c
            set first = b
            set ally = b1
            set radius = r
            set dmg = dmg
            set angle = Atan2( y-GetUnitY(m), x-GetUnitX(m) )
            set dist = SquareRoot( (x-GetUnitX(m))*(x-GetUnitX(m)) + (y-GetUnitY(m))*(y-GetUnitY(m)) )
            set steps = R2I( dist/speed /FPS )
            set X = speed * FPS * Cos(angle)
            set Y = speed * FPS * Sin(angle)
            call TimerStart( t, FPS, true, function thistype.Periodic )
            set t = null
        endmethod
    endstruct
This is vJASS but works just convert this to JASS.
In this code i use Table by Vexorian and FPS = 0.031250000
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
for instance, my knowledge stops at JASS, vJASS isn't implemented in my brain's Library yet :p
so mr barry, can you convert it :p cuz i don't undestand it at all

And this is what i have done till now:

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

And if you need the newest code:
JASS:
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           Knock-Back 3D  v. 1.3.0     [JASS - GUI]                      //
//                                                by JAD aka DotCa         //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           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 have default values:                       //
//                                                                         //
//     - KB3D_DestroyTree      == FALSE by default                         //
//     - KB3D_DisableUnit      == FALSE by default                         //
//     - KB3D_UnpathaableStop  == TRUE  by default                         //
//                                                                         //
//  The System also uses Always positive values for some configurations    //
//  to not make the knockback go worng, those configurations are:          //
//                                                                         //
//         "KB3D_Range"  -  "KB3D_Speed"  -  "KB3D_ZOffset"                //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           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                  //
//    *Rheiko for Beta Stages Testings                                     //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           How to Import?                                                //
//                                                                         //
//  1. Check that Create Unknown Variables is ticked in your WE Settings   //
//  2. Copy the Paste this Trigger                                         //
//  3. Congratulations, the System is now implemented in your map          //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           How to Use?                                                   //
//                                                                         //
//  1. There are 3 Examples of use in the KB3D Example Folder              //
//  2. Documentations are there in each of the 3 examples 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                                     //
//                                                                         //
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
//                                                                         //
//           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 SaveAttackTypeHandle takes hashtable hash, integer parentKey, integer childKey, attacktype at returns nothing
    call SaveInteger(hash, parentKey, childKey, GetHandleId(at))
endfunction
function LoadAttackTypeHandle takes hashtable hash, integer parentKey, integer childKey returns attacktype
    return ConvertAttackType(LoadInteger(hash, parentKey, childKey))
endfunction

function SaveDamageTypeHandle takes hashtable hash, integer parentKey, integer childKey, damagetype dt returns nothing
    call SaveInteger(hash, parentKey, childKey, GetHandleId(dt))
endfunction
function LoadDamageTypeHandle takes hashtable hash, integer parentKey, integer childKey returns damagetype
    return ConvertDamageType(LoadInteger(hash, parentKey, childKey))
endfunction

function KB3D_AlwaysNeg takes real R returns real//Used for redering some values always lower than 0
    if R > 0 then
        set R = R * -1
    endif
    return R
endfunction

function KB3D_AlwaysPos takes real R returns real//Used for redering some values always higher than 0
    if R < 0 then
        set R = R * -1
    endif
    return R
endfunction

function KB3D_InBetween takes real Min, real R, real Max returns real//Used to maintain values between 2 others
    if R < Min then
        set R = Min
    else
        if R > Max then
            set R = Max
        endif
    endif
    return R
endfunction

function KB3D_RegisterUnitCollision takes unit u, real x, real y, integer i returns real //Somehow a library for UnitCollision function
    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//Used to know the collision of a unit //Credits to Netharus// converted by malhorne
    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 //Checks if a destructable is a tree
    local boolean B = false
    call IssueTargetOrder( udg_KB3D_Harvester, "harvest", D )
    if ( GetUnitCurrentOrder(udg_KB3D_Harvester) == OrderId("harvest") ) then
        set B = true
    endif
    call IssueImmediateOrder(udg_KB3D_Harvester, "stop")
    return B
endfunction

function KB3D_KillifTree takes destructable D returns nothing //Kills a destructable if it is a tree
    if ( KB3D_Tree_Check(D) ) then
        call KillDestructable(D)
    endif
endfunction

function KB3D_KillEnumDest takes nothing returns nothing //Function used in Enumeration loop
    call KB3D_KillifTree(GetEnumDestructable())
endfunction

function KB3D_CircleTreeKill takes real radius, real x, real y returns nothing//To destroy trees around the unit
    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_CW_Loop takes nothing returns nothing//function for item group loop for Check Walkability System
    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//Check Walkability System by PnF
    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
    set udg_CP_PointIsWalkable = ((x2-x)*(x2-x) + (y2-y)*(y2-y) <= 100) and (not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY))
    return udg_CP_PointIsWalkable
endfunction

function KB3D_ClearInstance takes integer i returns nothing
    local integer x = 0
    loop
        exitwhen x > 30
        call RemoveSavedHandle(udg_KB3D_HA, x, i)
        set x = x +1
    endloop
endfunction

function MoveUnit_3D takes unit U, real x, real y, real z, boolean B returns nothing
    call SetUnitFlyHeight(U, KB3D_InBetween(GetUnitDefaultFlyHeight(U), z, 9999), 0)
    if ( not(B) or ( KB3D_CW(x, y) ) ) then
        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]))
    endif
endfunction

function KB3D_Loop takes integer Loop returns nothing//Main Trigger Loop
    //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
    local real y
    local real 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 unit Target = LoadUnitHandle(udg_KB3D_HA, 5, Loop)
    local unit Damager = LoadUnitHandle(udg_KB3D_HA, 22, Loop)
    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 string Fx = LoadStr(udg_KB3D_HA, 9, Loop)
    local string Attach = LoadStr(udg_KB3D_HA, 10, Loop)
    local attacktype AType = LoadAttackTypeHandle(udg_KB3D_HA, 20, Loop)
    local damagetype DType = LoadDamageTypeHandle(udg_KB3D_HA, 21, Loop)
    //end of locals
    if not (LoopD == 0) and not (Damager == null ) then//damage target with loop damage
        call UnitDamageTarget(Damager, U, LoopD, true, false, AType, DType, WEAPON_TYPE_WHOKNOWS)
    endif
    if ( Target == null ) then//know the angle of knockback line
        set Angle = LoadReal(udg_KB3D_HA, 5, Loop)//if there is no unit target
    else
        set Angle = Atan2(GetUnitY(Target) - Y, GetUnitX(Target) - X)//if there is a unit target
    endif
    set Speed = Speed + ( Accel )//Increase the KB speed depending on the Acceleration
    set Range = Range - ( Speed )//Decrease distance traveled
    set ZSpeed = ZSpeed + ( ZAccel )//change the fly changing rate //Acceleration is for smoothness
    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 z = Z + ( ZSpeed * 0.031250000 )//new Z Offset of the KBed unit
    call MoveUnit_3D(U, x, y, z, UnpathableStop)//Move the unit according to the X, Y, Z
    if (DestroyTree) then//Check if Destroy Tree is enabled
        call KB3D_CircleTreeKill( KB3D_InBetween(100, 4 * KB3D_GetUnitCollision(U), 500), x, y )//Destroy trees around target
    endif
    if not (Fx == "") then//create an effect on the unit
        if ( z > 20 ) then
            if not (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
    if ( (UnpathableStop) and not ( KB3D_CW(x, y) ) ) and (not (ImpactD == 0) and not (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, WEAPON_TYPE_WHOKNOWS)//Apply Impact Damage to the unit
            call SaveBoolean(udg_KB3D_HA, 23, Loop, false)
        endif
    endif
    if ( DisableUnit ) then//disable the unit partially
        call SetUnitPropWindow(U, 0)
        call SetUnitTurnSpeed(U, 0)
    endif
    if not(Target == null) then
        if (SquareRoot ( ( GetUnitX(Target) - x ) * ( GetUnitX(Target) - x ) + ( GetUnitY(Target) - y ) * ( GetUnitY(Target) - y ) ) < KB3D_InBetween(25, KB3D_GetUnitCollision(U), 999)) then
            if not (TargetD == 0) and not(Damager == null) then
                call UnitDamageTarget(Damager, Target, TargetD, true, false, AType, DType, WEAPON_TYPE_WHOKNOWS)
                call SaveReal(udg_KB3D_HA, 19, Loop, 0)
            endif
            if (KillWhenHit) then
                call KillUnit(U)
            endif
            if (EndWhenHit) then
                call SaveReal(udg_KB3D_HA, 4, Loop, Speed / 0.030000000)
                call SaveReal(udg_KB3D_HA, 13, Loop, ZSpeed / 0.030000000)
            endif
        endif
    endif
    ////// Stop All
    if ( (Speed <= 0) or ( Range <= 0 ) or ( GetWidgetLife(U) <= 0 ) ) then
        call SaveBoolean(udg_KB3D_HA, 55, Loop, false)
        set udg_KB3D_Instances = udg_KB3D_Instances - 1
        call SetUnitFlyHeight(U, KB3D_InBetween(GetUnitDefaultFlyHeight(U), z - 15, 9999), 0)
        if ( GetWidgetLife(U) <= 0 ) then
            call SetUnitFlyHeight(U, GetUnitDefaultFlyHeight(U), 750 )
        endif
        call SetUnitPropWindow(U, LoadReal(udg_KB3D_HA, 15, Loop))
        call SetUnitTurnSpeed(U, GetUnitDefaultTurnSpeed(U))
        if HaveSavedHandle(udg_KB3D_HA, 14, Loop) then
            call DestroyEffect(LoadEffectHandle(udg_KB3D_HA, 14, Loop))
        endif
        call KB3D_ClearInstance(Loop)
    else
        ////// Save Changes
        call SaveReal(udg_KB3D_HA, 1, Loop, Range)
        call SaveReal(udg_KB3D_HA, 2, Loop, Speed)
        call SaveReal(udg_KB3D_HA, 12, Loop, ZSpeed)
    endif
    ////// Clear
    set U = null
    set Target = null
endfunction

function KB3D_Loop_Actions takes nothing returns nothing//loop triggerer
    local integer x = 0
    loop
        exitwhen x >= udg_KB3D_Counter
        set x = x + 1
        if ( LoadBoolean(udg_KB3D_HA, 55, 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
endfunction

function KB3D_Registration takes nothing returns boolean//register an instance in the System
    local real Time
    local real R
    local real R1
    set udg_KB3D_Range = KB3D_InBetween(0.01, KB3D_AlwaysPos(udg_KB3D_Range), KB3D_AlwaysPos(udg_KB3D_Range))
    set udg_KB3D_Speed = KB3D_InBetween(0.01, KB3D_AlwaysPos(udg_KB3D_Speed), KB3D_AlwaysPos(udg_KB3D_Speed))
    set udg_KB3D_Counter = udg_KB3D_Counter + 1
    set udg_KB3D_Instances = udg_KB3D_Instances + 1
    set udg_KB3D_Zoffset = 1.85 * KB3D_AlwaysPos(udg_KB3D_Zoffset)
    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 )
    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_Fx_Attach )
    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 = (( -2*(udg_KB3D_Speed) + SquareRoot((4*udg_KB3D_Speed) + (8*udg_KB3D_Accel*udg_KB3D_Range ) ) / (2*udg_KB3D_Accel) ))//calculating time for the knockback if Acceleration > 0
        endif
        if ( udg_KB3D_Accel < 0 ) then
            set R = ( - 1 * (udg_KB3D_Speed) / udg_KB3D_Accel )
            set R1 = (0.5 * udg_KB3D_Accel * R * R) + ((udg_KB3D_Speed) * R)
            if R1 < udg_KB3D_Range then
                set Time = R//calculating time for the knockback if Acceleration < 0 and if the speed will be = 0 before reaching max range
            else
                set Time = KB3D_AlwaysPos(( -2*(udg_KB3D_Speed) + SquareRoot(KB3D_AlwaysPos((4*(udg_KB3D_Speed)*(udg_KB3D_Speed)) + (8*udg_KB3D_Accel*udg_KB3D_Range) )) ) / (2*udg_KB3D_Accel) )//calculating time for the knockback if Acceleration < 0 and if the speed will be > 0 before reaching max range
            endif
        endif
    endif
    call SaveReal( udg_KB3D_HA, 11, udg_KB3D_Counter, Time )
    call SaveBoolean( udg_KB3D_HA, 55, 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, (udg_KB3D_Zoffset / ( Time / 2)) )
    call SaveReal( udg_KB3D_HA, 13, udg_KB3D_Counter, KB3D_AlwaysNeg(( -1 * udg_KB3D_Zoffset / ( Time / 2) ) / ( Time / 2)) * 0.031250000 )
    if not (udg_KB3D_TrailFx == "") and not (udg_KB3D_Fx_Attach == "") then
        call SaveEffectHandle(udg_KB3D_HA, 14, udg_KB3D_Counter, AddSpecialEffectTarget(udg_KB3D_TrailFx, udg_KB3D_Unit, udg_KB3D_Fx_Attach))
    endif
    call SaveReal( udg_KB3D_HA, 15, udg_KB3D_Counter, GetUnitDefaultPropWindow(udg_KB3D_Unit) )
    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 SaveAttackTypeHandle( udg_KB3D_HA, 20, udg_KB3D_Counter, udg_KB3D_AttackType )
    call SaveDamageTypeHandle( udg_KB3D_HA, 21, udg_KB3D_Counter, 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 )
    if (udg_KB3D_KillWhenHit) then
        set udg_KB3D_EndWhenHit = true
    endif
    call SaveBoolean( udg_KB3D_HA, 25, udg_KB3D_Counter, udg_KB3D_EndWhenHit )
    //Nulling
    set udg_KB3D_Accel = 0.00
    set udg_KB3D_Angle = 0.00
    set udg_KB3D_DestroyTree = false
    set udg_KB3D_DisableUnit = false
    set udg_KB3D_Fx = ""
    set udg_KB3D_Fx_Attach = ""
    set udg_KB3D_TrailFx = ""
    set udg_KB3D_Range = 0.00
    set udg_KB3D_Speed = 0.00
    set udg_KB3D_Targeted_Unit = null
    set udg_KB3D_Unit = null
    set udg_KB3D_UnpathableStop = true
    set udg_KB3D_Zoffset = 0.00
    if ( udg_KB3D_Counter == 1 ) then
        call TimerStart(udg_KB3D_Timer, 0.031250000, true, function KB3D_Loop_Actions )
    endif
    set udg_KB3D_Time = Time
    return 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')
    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)
endfunction
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
not for today :/
i will do this on the weekend, or next week since i don't have school :p
but for now, just tell me a specification that can be useful for the system
something like what i added:
KillWhenHit
EndwhenHit
Imapact/Loop/Target/Line Damage
GetTimeforKnockback

some useful things :)
 
Status
Not open for further replies.
Top