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

Jump System v. 1.0.1.6

Here is a jumping system that
  • Does not pause units, pausing is bad
  • Allows the unit to jump in place, unlike other jump systems
  • Supports collision with units and destructables, can be turned off
  • Uses real life physics equation
  • Allows the user to define the maximum jump height, jump duration and gravity, unlike other jump systems

JASS:
library Jump requires CTL, IsTerrainWalkable optional GetUnitCollision, Table
    /*      
     *      Jumping v. 1.0.1.6 by Maker
     *          -Does not pause units
     *          -Allows jumping in place
     *          -Real life physics equation for the jump arc
     *          -Supports collision with destructables and units
     *
     *      function IsPointJumpable takes real x, real y returns boolean
     *          -Tells if the point is walkable
     *
     *      static method start takes unit un, real x1, real y1, real maxZ, real time, real gravity returns thistype
     *          - un        = unit that jumps
     *          - x1, y1    = coordinates to jump to
     *          - maxZ      = height of the arc
     *          - time      = duration of the jump
     *          - gravity   = well, duh
     *  
     *      method setUnitCollisionHeight takes real h returns nothing
     *          - Overrides the global U_COL_Z variable for the jump instance
     *            If set to 0, the jumping unit won't collide with units
     *            while being in air
     *
     *      method setDestructableCollisionDistance takes real d returns nothing
     *          - Overrides the global D_COL_D variable for the jump instance
     *            If set to 0, the jumping unit won't collide with destructables
     *            while being in air
     *
     *      You can catch the ending of the jump and register it for a trigger like this:
     *          call TriggerRegisterVariableEvent(trigger, "EVENT_JUMP_FINISH", EQUAL, 1)
     *
     *      Import this library and required CTL and IsTerrainWalkable libraries from resources folder.
     *      I recommend also importing GetUnitCollision and Table libraries from resources folder.
     *
     *      Credits
     *      CTL, GetUniCollision    :   Nestharus
     *      IsTerrainWalkable       :   anitarf and Vexorian
     *      Table                   :   Bribe
     */
    globals
        // Tolerance distance for pathability
        private constant    real        TOL                 = 1    
        // Minimum flying heigh for colliding with units. If set to 0 then won't collide with units.
        private constant    real        U_COL_Z             = 96 
        // Collision distance with units. Uses this if GetUnitCollision library is not used
        private constant    real        U_COL_D             = 96   
        // Collision distance with destructables. If set to 0 then won't collide with destructables.
        private constant    real        D_COL_D             = 96  
        // Maximum collision radius of units in the map. 196 for tier 3 Town Halls etc.
        private constant    real        MAX_RAD             = 196
        // Moves the unit to nearest pathable point when landing
        private constant    boolean     PATHING_LAND        = false 
        // Is the turn speed locked when jumping
        private constant    boolean     LOCK_FACING         = true
        
        private             rect        rct                 = Rect(0,0,0,0)
        private             group       enu                 = CreateGroup()
        private             location    loc                 = Location(0,0)
                            real        EVENT_JUMP_FINISH   = 0
                            unit        EVENT_JUMP_UNIT     = null
        private             real        flh                 = 0
        private             boolean     b                   = false
    endglobals
    
    private function GetLocZ takes real x, real y returns real
        call MoveLocation(loc, x, y)
        return GetLocationZ(loc)
    endfunction
    
    private function DestructableFilter takes nothing returns boolean
        if GetDestructableLife(GetFilterDestructable()) > 0 and GetDestructableOccluderHeight(GetFilterDestructable()) > flh then
            set b = true
        endif
        return false
    endfunction
    
    function IsPointJumpable takes real x, real y returns boolean
        if not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) then
            return IsTerrainWalkable(x, y)
        endif
        return false
    endfunction
    
    struct Jump extends array
        private static unit array u         // Jumping unit  
        private static real array z0        // Location Z at jump origin point
        private static real array sx        // The x component of speed
        private static real array sy        // The y  component of speed
        private static real array t         // Elapsed jump time
        private static real array dt        // How much "time" is passed during each loop
        private static real array g         // Gravity
        private static real array sinZ      // Z angle
        private static real array endX      // Targeted x
        private static real array endY      // Targeted y  
        private static real array tEnd      // Jump end time
        private static real array dfh       // Default flying height
        private static real array col       // Collision size of the unit
        private static real array colUZ     // Minimum height to collide with other units
        private static real array colDD     // Minimum distance to collide with destructables
        private static real array pw        // Propulsion window of the unit
        private static real array ts        // Turn speed of the unit
    
        method setUnitCollisionHeight takes real h returns nothing
            set colUZ[this] = h
        endmethod
    
        method setDestructableCollisionDistance takes real d returns nothing
            set colDD[this] = d
        endmethod
        
        implement CTL
            local real x
            local real y
            local real z
            local real fh
            local unit un
        implement CTLExpire
            set x = GetUnitX(u[this]) + sx[this]
            set y = GetUnitY(u[this]) + sy[this]
            set z = GetLocZ(x, y) - z0[this]
            set t[this] = t[this] + dt[this]
            set fh = sinZ[this] * t[this] - g[this] * t[this] * t[this] / 2. - z + dfh[this]
            if t[this] < tEnd[this] then
                set b = false
                if colDD[this] > 0 then
                    call SetRect(rct, x-colDD[this], y-colDD[this], x+colDD[this], y+colDD[this])
                    call EnumDestructablesInRect(rct, function DestructableFilter, null)
                endif
                if fh < colUZ[this] and not b then
                    set flh = fh
                    call GroupEnumUnitsInRange(enu, x, y, MAX_RAD, null)
                    call GroupRemoveUnit(enu, u[this])
                    loop
                        set un = FirstOfGroup(enu)
                        exitwhen un == null or b
                        if IsUnitInRange(un, u[this], col[this]+1) and not IsUnitType(un, UNIT_TYPE_DEAD) and not IsUnitType(un, UNIT_TYPE_FLYING) then
                            set b = true
                            set un = null
                            set sx[this] = 0
                            set sy[this] = 0
                            set endX[this] = GetUnitX(u[this])
                            set endY[this] = GetUnitY(u[this])
                            call GroupClear(enu)
                        else
                            call GroupRemoveUnit(enu, un)
                        endif
                    endloop
                    if not b then
                        call SetUnitX(u[this], x)
                        call SetUnitY(u[this], y)
                    endif
                elseif not b then
                    call SetUnitX(u[this], x)
                    call SetUnitY(u[this], y)
                else
                    set sx[this] = 0
                    set sy[this] = 0
                    set endX[this] = GetUnitX(u[this])
                    set endY[this] = GetUnitY(u[this])
                endif
                call SetUnitFlyHeight(u[this], fh, 0)
            else
                static if PATHING_LAND then
                    call SetUnitPosition(u[this], endX[this], endY[this])
                else
                    call SetUnitX(u[this], endX[this])
                    call SetUnitY(u[this], endY[this])
                endif
                static if LOCK_FACING then
                    call SetUnitTurnSpeed(u[this], ts[this])
                endif
                call SetUnitPropWindow(u[this], pw[this])
                call SetUnitFlyHeight(u[this], dfh[this], 0)
                set EVENT_JUMP_UNIT = u[this]
                set EVENT_JUMP_FINISH = 0
                set EVENT_JUMP_FINISH = 1
                set EVENT_JUMP_UNIT = null
                set u[this] = null
                call destroy()
            endif
        implement CTLNull
        implement CTLEnd
    
        static method start takes unit un, real x1, real y1, real maxZ, real time, real gravity returns thistype
            local thistype this = create()
            local real x0 = GetUnitX(un)
            local real y0 = GetUnitY(un)
            local real angle = Atan2(y1-y0, x1-x0)
            local real dist = SquareRoot((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0))
            local real speed = dist/time  * 0.031250000
            local real z1 = GetLocZ(x1, y1)
            
            set u[this] = un
            set t[this] = 0
            set endX[this] = x1
            set endY[this] = y1
            set g[this] = gravity
            set z0[this] = GetLocZ(x0, y0)
            set sx[this] = Cos(angle) * speed
            set sy[this] = Sin(angle) * speed
            set dfh[this] = GetUnitDefaultFlyHeight(un)
            
            static if LIBRARY_GetUnitCollision then
                set col[this] = GetUnitCollision(un)
            else
                set col[this] = U_COL_D
            endif
            set colDD[this] = D_COL_D
            set colUZ[this] = U_COL_Z
            
            if z0[this] < z1 then
                set maxZ = maxZ + z1 - z0[this]
            endif
            
            set sinZ[this] = SquareRoot(maxZ*2*gravity)
            set tEnd[this] = (sinZ[this]+SquareRoot(sinZ[this]*sinZ[this]-2*gravity*(z1-z0[this]))) / gravity
            set dt[this] = 0.03125000*(tEnd[this]-t[this]) / time
            static if LOCK_FACING then
                set ts[this] = GetUnitTurnSpeed(un)
                call SetUnitTurnSpeed(un, 0)
            endif
            set pw[this] = GetUnitPropWindow(un)
            call SetUnitPropWindow(un, 0)
            if UnitAddAbility(un, 'Arav') and UnitRemoveAbility(un, 'Arav') then
            endif
            
            return this
        endmethod
    endstruct
endlibrary




JASS:
scope JumpSpellvJASS

    globals
        private string EFF = "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl"
        private constant integer AID = 'A000'
        private constant integer OID = 852121
        private unit HARVESTER
        private group ENU = CreateGroup()
        private constant real gravity = 100
        private constant real time      = 0.6
        private constant real maxHeight = 220
        private constant real AOE   = 300
        private rect REC
    endglobals

    struct JumpingStomp extends array
    
        private static method DestructableFilter takes nothing returns boolean
            if GetDestructableLife(GetFilterDestructable()) > 0 then
                call IssueTargetOrder(HARVESTER, "harvest", GetFilterDestructable())
                if GetUnitCurrentOrder(HARVESTER) == OrderId("harvest") then
                    call KillDestructable(GetFilterDestructable())
                endif
                call IssueImmediateOrder(HARVESTER, "stop")
            endif
        return false
    endmethod
    
        private static method onFinish takes nothing returns boolean
            local real x
            local real y
            if not IsUnitType(EVENT_JUMP_UNIT, UNIT_TYPE_DEAD) then
                set x = GetUnitX(EVENT_JUMP_UNIT)
                set y = GetUnitY(EVENT_JUMP_UNIT)
                call DestroyEffect(AddSpecialEffect(EFF, x, y))
                call SetRect(REC, x-AOE, y-AOE, x+AOE, y+AOE)
                call EnumDestructablesInRect(REC, function thistype.DestructableFilter, null)
            endif
            return false
        endmethod
        
        private static method onCast takes nothing returns boolean
            if not IsUnitType(EVENT_JUMP_UNIT, UNIT_TYPE_DEAD) then
                call Jump.start(GetTriggerUnit(), GetSpellTargetX(), GetSpellTargetY(), maxHeight, time, gravity)
            endif
            return false
        endmethod
        
        private static method onOrder takes nothing returns boolean
            if GetIssuedOrderId() == OID and not IsPointJumpable(GetOrderPointX(), GetOrderPointY()) then
                call PauseUnit(GetTriggerUnit(), true)
                call IssueImmediateOrder(GetTriggerUnit(), "stop")
                call PauseUnit(GetTriggerUnit(), false)
                call SimError(GetTriggerPlayer(), "Can't jump there.")
            endif
            return false
        endmethod
    
        private static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            call TriggerRegisterVariableEvent(t, "EVENT_JUMP_FINISH", EQUAL, 1)
            call TriggerAddCondition(t, function thistype.onFinish)
            
            set t = CreateTrigger()
            call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
            call TriggerAddCondition(t, function thistype.onOrder)
            
            call RegisterSpellEffectEvent(AID, function thistype.onCast)
            
            set HARVESTER = CreateUnit(Player(15), 'hpea', 0, 0, 0)
            call UnitAddAbility(HARVESTER, 'Aloc')
            call ShowUnit(HARVESTER, false)
        endmethod
    endstruct
endscope


  • JumpAbilSetup
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- -------------------------------------------------- --------
      • -------- Register a trigger to run when the jump lands --------
      • -------- -------------------------------------------------- --------
      • Set JUMP_FINISH_TRIGGER = JumpAbilFinish <gen>
      • Custom script: call TriggerRegisterVariableEvent(udg_JUMP_FINISH_TRIGGER, "EVENT_JUMP_FINISH", EQUAL, 1.00 )
      • -------- -------------------------------------------------- --------
      • -------- Effect to use when the jump lands --------
      • -------- -------------------------------------------------- --------
      • Set JUMP_EFFECT = Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
      • -------- -------------------------------------------------- --------
      • -------- For cutting trees --------
      • -------- -------------------------------------------------- --------
      • Unit - Create 1 Peasant for Neutral Passive at (Center of (Playable map area)) facing Default building facing degrees
      • Set HARVESTER = (Last created unit)
      • Custom script: call UnitAddAbility(udg_HARVESTER, 'Aloc')
      • Unit - Hide HARVESTER
  • JumpAbilOrder
    • Events
      • Unit - A unit Is issued an order targeting a point
    • Conditions
      • (Issued order) Equal to (Order(flamestrike))
      • (Level of Jump GUI for (Triggering unit)) Not equal to 0
    • Actions
      • Set loc = (Target point of issued order)
      • Custom script: if not IsPointJumpable(GetLocationX(udg_loc), GetLocationY(udg_loc)) then
      • Unit - Pause (Triggering unit)
      • Unit - Order (Triggering unit) to Stop
      • Unit - Unpause (Triggering unit)
      • Custom script: call SimError(GetTriggerPlayer(), "Can't jump there.")
      • Custom script: endif
      • Custom script: call RemoveLocation(udg_loc)
      • Custom script: set udg_loc = null
  • JumpAbilStart
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Jump GUI
    • Actions
      • Custom script: call Jump.start(GetTriggerUnit(), GetSpellTargetX(), GetSpellTargetY(), 150, 0.6, 80)
  • JumpAbilFinish
    • Events
    • Conditions
    • Actions
      • -------- -------------------------------------------------- --------
      • -------- Get the unit that finished jumping --------
      • -------- -------------------------------------------------- --------
      • Custom script: set udg_u = EVENT_JUMP_UNIT
      • -------- -------------------------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (u is alive) Equal to True
        • Then - Actions
          • Set loc = (Position of u)
          • Special Effect - Create a special effect at loc using JUMP_EFFECT
          • Custom script: set bj_wantDestroyGroup = true
          • Unit Group - Pick every unit in (Units within 200.00 of loc) and do (Actions)
            • Loop - Actions
              • Set u2 = (Picked unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (u2 is alive) Equal to True
                  • (u2 is A flying unit) Equal to False
                  • (u2 belongs to an enemy of (Owner of u)) Equal to True
                • Then - Actions
                  • Unit - Cause u to damage u2, dealing 100.00 damage of attack type Spells and damage type Normal
                • Else - Actions
          • Set RECT = (Region centered at loc with size (300.00, 300.00))
          • Destructible - Pick every destructible in RECT and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Current life of (Picked destructible)) Greater than 0.00
                • Then - Actions
                  • Unit - Order HARVESTER to Harvest (Picked destructible)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Current order of HARVESTER) Equal to (Order(harvest))
                    • Then - Actions
                      • Destructible - Kill (Picked destructible)
                    • Else - Actions
                      • Unit - Order HARVESTER to Stop
                • Else - Actions
          • Custom script: call RemoveRect(udg_RECT)
          • Custom script: call RemoveLocation(udg_loc)
          • Custom script: set udg_RECT = null
        • Else - Actions





IsTerrainWalkable - Vexorian, Anitarf
CTL, GetUnitCollision - Nestharus




v1.0.0.1 @ 22.02.2013
-Now uses (optional) GetUnitCollisionSize library for more accurate collision detection with units.
v1.0.0.2 @ 24.02.2013
-Now resets the prop window of units correctly.
v1.0.0.3 @ 24.02.2013
-Now sets the flying height of units that have default flying height greater than 0 correctly.
v1.0.0.4 @ 03.03.2013
-Now resets the propulsion window of the jumper correctly
-Changed from IsUnitInRangeXY to IsUnitInRange for better collision detection for units
v1.0.1.4 @ 04.06.2013
-Added two new methods to be able to override the global collision settings for a jump instance
v1.0.1.5 @ 08.06.2013
-if LIBRARY_GetUnitCollision then->static if LIBRARY_GetUnitCollision then
v1.0.1.6 @ 11.07.2013
-Now resets turn speed correctly


Keywords:
jump, jumping, leap, leaping, maker
Contents

Just another Warcraft III map (Map)

Reviews
19:04, 18th Feb 2013 Magtheridon96: Approved. Useful, sufficient and efficient.

Moderator

M

Moderator

19:04, 18th Feb 2013
Magtheridon96: Approved.
Useful, sufficient and efficient.
 
Level 3
Joined
Jan 1, 2013
Messages
43
Hey can you tell me about it...
  • Custom script: call Jump.start(GetTriggerUnit(), GetSpellTargetX(), GetSpellTargetY(), 150, 0.6, 80)
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
Hey can you tell me about it...
  • Custom script: call Jump.start(GetTriggerUnit(), GetSpellTargetX(), GetSpellTargetY(), 150, 0.6, 80)

Sure, what do you need to know?

The function takes unit, x, y, maxZ, time, gravity.

Unit is the jumping unit, x and y are the coordinates of the location you want to jump to, maxZ is the height of the jump, time is how long the jump takes and gravity is the force that pulls the unit down.
 
Level 6
Joined
Oct 23, 2011
Messages
182
SetUnitPropWindow() uses RAD value, while GetUnitPropWindow() returns DEG value.

SetUnitPropWindow(u[this], GetUnitDefaultPropWindow(u[this]))
to
SetUnitPropWindow(u[this], bj_DEGTORAD * GetUnitDefaultPropWindow(u[this]))

It's not a random suggestion =P
I've confirmed it myself
 
Level 37
Joined
Mar 6, 2006
Messages
9,240
Two new methods:
JASS:
    /*      method setUnitCollisionHeight takes real h returns nothing
     *          - Overrides the global U_COL_Z variable for the jump instance
     *            If set to 0, the jumping unit won't collide with units
     *            while being in air
     *
     *      method setDestructableCollisionDistance takes real d returns nothing
     *          - Overrides the global D_COL_D variable for the jump instance
     *            If set to 0, the jumping unit won't collide with destructables
     *            while being in air                                                 */
 
Level 6
Joined
Aug 14, 2016
Messages
174
I have a problems, when i adding for my map, ErrorMessage:Can't jump there, but i jump in a ground, not a ciff, when i click items to reload weapons, unit flying and flying to the middle map!!:confused::confused:
 
Level 6
Joined
Aug 14, 2016
Messages
174
Do units not collide in mid-air if they're near similar heights while jumping?
1:No, i don't change anything, it pefectly i want, but the text only say:Can't jump there.
2:When i using flamestrike -> grenade, the units flying everywhere i want and no ErrorMessage, but get a glitch, jump through outside the maps.
Edit:Jump through boundary.
 
1:No, i don't change anything, it pefectly i want, but the text only say:Can't jump there.
2:When i using flamestrike -> grenade, the units flying everywhere i want and no ErrorMessage, but get a glitch, jump through outside the maps.
Edit:Jump through boundary.
I didn't post above to reply to you, having a few problems too though that is weird, all I can suggest is making it yourself or finding a new system to use.
 
Top