1. Are you planning to upload your awesome spell or system to Hive? Please review the rules here.
    Dismiss Notice
  2. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  3. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  4. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  5. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  6. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  7. The results are out! Check them out.
    Dismiss Notice
  8. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  9. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  10. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Unit Acceleration System v0.16 (GUI Friendly)

Submitted by Diehard@Azeroth
This bundle is marked as approved. It works and satisfies the submission rules.
This system accelerates units based on terrain height, and drags units down if they are going down terrain such as a mountain (in the map), basically any higher terrain that has a relatively fair amount of difference in Z which makes the unit become dragged by gravity.

I used to increase or decrease acceleration, but it seems there was a bug in that because when a unit accelerates down a mountain, it will be able to pass over a part of the mountain that it shouldnt be able to pass because of how steep the location is; which the unit would have not been able to pass before deaccelerating down the mountain. Of course this bug happens only if you move down a mountain and then up the mountain really fast.

Anyways, thats why i included the drag aspect of the acceleration, and the higher the movespeed is, the faster the drag will be, cus im basing the acceleration on the same concept of V = Vo + at.

Hope you enjoy the system, its MUI, Lagless and is GUI-Friendly. made many directions, most for GUI users since the system is vJASS.

please give credits if you use it in your map

also guys, you may need to remove acceleration at times like for example, a unit jumps, and when he finishes jumping, add his acceleration back again; instructions are in the trigger section in the map.

BTW ANY OF U GUYS CAN EDIT THIS SYSTEM AS LONG AS YOU GIVE CREDITS TO ME AS THE ORIGINAL CREATOR, il fix any bugs and add extra functions if wanted, but probably not adding much extra features; unless if there is a special request to do so.

Credits:
-------------------------------------------------------------------------------------

Elejrk@hiveworkshop.com for helping me find several bugs and fix the drag and telling me to make the system's description better

Revolve, Shendoo2 and D4RK_G4ND4LF for finding a minor bug in the acceleration of units

The_Reborn_Devil for telling me to show others that my system is MUI by adding acceleration to the other rifleman

-------------------------------------------------------------------------------------

Here is code:
Code (vJASS):
library Acceleration initializer Init
   
    globals
        private timer t = CreateTimer()
        private group accelUnits = CreateGroup()
        private location Zloc = Location(0.,0.)
        private integer maxAccel = 0
        private constant real checkDist = 10.
        private timer d = CreateTimer()
        private constant group dragGroup = CreateGroup()
        private integer maxDrag = 0
        private hashtable ht = InitHashtable()
        private boolexpr kbBoolexpr
        private unit draggedUnit = null
        private unit tempFilter = null
        private boolexpr True
        private rect r = null
        private constant real DEGTORAD = 3.14159/180
       
        // CONFIGURABLES
       
        private constant real NoDrag = 10. //maximum difference in Z that cannot cause any drag, basically, the higher this value is, the lower
        // a terrain infront of the unit will be needed to drag the unit down, and vice versa. Values less than 0 wont work.
       
        private constant real dragIteration = 0.03 // drag timer periodic iteration
        private constant real tIteration = 0.30 // timer periodic iteration
       
        private constant real gravity = -9.81 // gravity's real value, make it lower to lower the acceleration/deacceleration change
        // END CONFIGURABLES
       
        private constant real dragGravity = gravity*dragIteration*-1
        private DN dat
    endglobals
   
   
    private function GetLocZ takes real x, real y returns real
        call MoveLocation(Zloc, x, y)
        return GetLocationZ(Zloc)
    endfunction
   
    private function returnTrue takes nothing returns boolean
        return true
    endfunction
   
    private function returnBoolean takes nothing returns boolean
        set tempFilter = GetFilterUnit()
        return GetUnitFlyHeight(tempFilter) <= 25 and IsUnit(tempFilter, draggedUnit) == false
    endfunction
   
    struct DN // Destructable detection
    integer dN = 0

        private static method returnValue takes nothing returns nothing
            set dat.dN = dat.dN + 1
        endmethod
   
        static method DestructablesNearby takes real x, real y returns boolean
            set dat = DN.allocate()
            set r = Rect(x-100, y-100, x+100, y+100)
            call EnumDestructablesInRect(r, True, function DN.returnValue)
            call RemoveRect(r)
            if dat.dN > 0 then
                return true
            else
                return false
            endif
        endmethod
   
    endstruct
   
    private function UnitsNearby takes real x, real y, unit dragged returns boolean
        local group nGroup = CreateGroup()
        local unit n
        set draggedUnit = dragged
        call GroupEnumUnitsInRange(nGroup, x, y, 60, kbBoolexpr)
        set n = FirstOfGroup(nGroup)
        call DestroyGroup(nGroup)
        set nGroup = null
        set draggedUnit = null
        if n == null then
            return false
        else
            set n = null
            return true
        endif
    endfunction
   
    private function coreDrag takes nothing returns nothing
        local unit e = GetEnumUnit()
        local integer i = GetHandleId(e)
        local real a = LoadReal(ht, i, 2)
        local real x = GetUnitX(e)
        local real y = GetUnitY(e)
        local real x2 = x+checkDist*Cos(a)
        local real y2 = y+checkDist*Sin(a)
        local real diffZ = GetLocZ(x2,y2)-GetLocZ(x,y)
        local real drag = LoadReal(ht, i, 1)
        local real x3 = x+drag*Cos(a)
        local real y3 = y+drag*Sin(a)
        if diffZ < -NoDrag and UnitsNearby(x2, y2, e) == false and DN.DestructablesNearby(x2, y2) == false and IsTerrainPathable(x3,y3, PATHING_TYPE_WALKABILITY) == false then
            set drag = drag + dragGravity
            call SaveReal(ht, i, 1, drag)
            call SetUnitX(e, x3)
            call SetUnitY(e, y3)
        else
            call GroupRemoveUnit(dragGroup, e)
            call SaveBoolean(ht, i, 0, false)
            set maxDrag = maxDrag - 1
            if maxDrag == 0 then
                call PauseTimer(d)
            endif
        endif
        set e = null
    endfunction
   
    private function DragUnits takes nothing returns nothing
        call ForGroup(dragGroup, function coreDrag)
    endfunction
   
    private function coreAccel takes nothing returns nothing
        local unit e = GetEnumUnit()
        local integer i = GetHandleId(e)
        local real f = GetUnitFacing(e)*DEGTORAD
        local real x = GetUnitX(e)
        local real y = GetUnitY(e)
        local real x2 = x+checkDist*Cos(f)
        local real y2 = y+checkDist*Sin(f)
        local real defaultSpeed = GetUnitDefaultMoveSpeed(e)
        local real diffZ = GetLocZ(x2,y2)-GetLocZ(x,y)
        local real newSpeed = defaultSpeed+(gravity*diffZ)
        if diffZ < -NoDrag and IsTerrainPathable(x2,y2, PATHING_TYPE_WALKABILITY) == false then
            if LoadBoolean(ht, i, 0) == false then
                call SaveBoolean( ht, i, 0, true )
                call SaveReal( ht, i, 1, dragGravity )
                call SaveReal( ht, i, 2, f )
                set maxDrag = maxDrag + 1
                call GroupAddUnit(dragGroup, e)
                call TimerStart(d, dragIteration, true, function DragUnits)
            endif
        else
            if LoadBoolean( ht, i, 0 ) == false then
                call SetUnitMoveSpeed(e, newSpeed)
            else
                call SetUnitMoveSpeed(e, defaultSpeed)
            endif
        endif
        set e = null
    endfunction
   
    private function AccelerateUnits takes nothing returns nothing
        call ForGroup(accelUnits, function coreAccel)
    endfunction
   
    function AddUnitAcceleration takes unit u returns nothing
        if u == null then
            return
        endif
        call GroupAddUnit(accelUnits, u)
        set maxAccel = maxAccel + 1
        call TimerStart(t, tIteration, true, function AccelerateUnits)
    endfunction

    function RemoveUnitAcceleration takes unit u returns nothing
        if u == null then
            return
        endif
        call GroupRemoveUnit(accelUnits, u)
        call SetUnitMoveSpeed( u, GetUnitDefaultMoveSpeed(u) )
        set maxAccel = maxAccel - 1
        if maxAccel == 0 then
            call PauseTimer(t)
        endif
    endfunction
   
    //-----------------------------------------------------------------
    private function Init takes nothing returns nothing
        set kbBoolexpr = Condition(function returnBoolean)
        set True = Condition(function returnTrue)
    endfunction
   
endlibrary

------------------------------------------------
- may add a function to access drag acceleration

ChangeLog:
Version 1
EDIT: Remembered to flush the child hashtable of dragged units.
EDIT2: Mesed up in a JASS line for adding acceleration to all units in map :p
EDIT3: Made units being dragged get stopped by units in their way, and be able to continue their drag only after their path is safe. Only problem here is that warcraft uses 2d distance for unit collision, so it may look wierd in REALLY RARE situations.
EDIT4 (IMPORTANT): Added destructable collision while on drag.
EDIT5: made coding slightly more efficient by using a hardcoded radius for finding nearby units and destructables.
EDIT6: made it so ranged units can stil attack while being dragged down.
EDIT7: Fixed Boolexpr Leak since i used null in destructable check

Version 0.12
EDIT8: added an initial velocity for drag as it should be done
Version 0.13
timer iteration changed to 0.30 from 0.15
Version 0.14
Slightly improved coding efficiency.
Version 0.15
private group dragGroup is now constant
Version 0.16
the rect r is now a global variable
made a constant DEGTORAD variable instead of the bj_DEGTORAD

Keywords:
acceleration, Diehard@Azeroth, height, physics
Contents

Acceleration System v0.16 (Map)

Reviews
Moderator
17:37, 28th Oct 2009 The_Reborn_Devil: Seems like a quite simple yet useful system. The coding looks good although for better efficiency please inline some of the functions. I couldn't find any leaks or bugs, but it would be better if you added...
  1. 17:37, 28th Oct 2009
    The_Reborn_Devil:

    Seems like a quite simple yet useful system. The coding looks good although for better efficiency please inline some of the functions.
    I couldn't find any leaks or bugs, but it would be better if you added the other rifleman to the acceleration thing as well to really show that it's MUI.

    Status: Approved.
    Rating: Useful [3.7/5].

    The efficiency thing isn't actually needed as this isn't a big physics engine :D
     
  2. xxdingo93xx

    xxdingo93xx

    Joined:
    Sep 8, 2007
    Messages:
    746
    Resources:
    2
    Maps:
    1
    Spells:
    1
    Resources:
    2
    Post the code here please.
     
  3. Catch_ya

    Catch_ya

    Joined:
    May 21, 2009
    Messages:
    982
    Resources:
    1
    Spells:
    1
    Resources:
    1
    This is really good... Didn't found any bugs. Also its not a long library its readable to me and im GUI user :) +REP for you. I'm gonna use this for my map and ofc credits, it gives such a realistic moving.
     
  4. Revolve

    Revolve

    Joined:
    Jun 11, 2007
    Messages:
    935
    Resources:
    11
    Icons:
    8
    Skins:
    1
    Maps:
    1
    Tutorials:
    1
    Resources:
    11
    I think I've found a bug. I don't know much about spells, but tis was the bug;
    When I ordered the footman to go down, he moved about 1/3 of the way, and stopped. I pressed again, he moved another 1/3 of the way, and stopped. I don't know if this is supposed to happen, if it is, then you should really consider fixing it.
    Otherwise it was awsome :D
     
  5. D4RK_G4ND4LF

    D4RK_G4ND4LF

    Joined:
    Feb 4, 2009
    Messages:
    1,196
    Resources:
    20
    Models:
    3
    Spells:
    15
    Tutorials:
    2
    Resources:
    20
    same

    in case I want to use this system for heroes only...
    would I have to remove them from the group every time they die and add them again as soon as they revive? cause they still are the same unit but I don't know how this will work with the enumeration stuff

    5/5 (cause I think you'll fix the bug mentioned by Revolve pretty fast anyway) :grin:
     
  6. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    suuup guys ! glad you like it bros, well thats not really a bug gandalf cus the difference in height is not steep enough to make him go down further, so he stopped; the final velocity would have to mix in tho

    but yea il consider fixing it, but im thinking its supposed to happen, happy you like it guys

    anyways il post the code dingo ^^

    and catch: im really glad you like it and u were able to use it even when u are a GUI user ^^

    ---------------------------------------------------------------------------------------

    maybe im supposed to add a final velocity to when he cant be dragged down any further? hmm yea maybe so; what do u guys think? especially you gandalf, ur pretty good with ur maths :D // btw i think its supposed to happen but im thinking he also has to deaccelerate at his stop over time, and not instantly >_<

    edit:

    i think i need to make a comparison with the final velocity and the amount of distance that has normal terrain height, but for that i would need to use loops or instant iterations that are calculated from the units position to infront of his original drag angle, personally i dont think its worth it since i need to do the check every drag, il try to do it.

    * and guys, there is a bug pertaining to the changing movement speed, the animation seems crappy when the ms is changed, the unit flashes a bit, im not sure i can fix this, maybe its because of the terrains height, since its over wc's normal limits and becomes a bit buggy >_>

    o sorry Gandalf, to reply to ur bug >_> sry :D, yea i mean its preferrable, so no iterations will be done at that time; and as i remember a hero doesnt have a corpse, so since that happens it wont be able to be dragged down when its dead, so yea its just preferrable xP

    -------------------------------------------------------------------------------------------
    btw i noticed there was a bug in dragged units, so if multiple units have been dragged, they need to be knocked down by others so the path can be clear and the movement wotn be bugged.
     
    Last edited: Oct 24, 2009
  7. eleljrk

    eleljrk

    Joined:
    Aug 27, 2009
    Messages:
    461
    Resources:
    4
    Maps:
    1
    Spells:
    3
    Resources:
    4
    Can you add a "Run" extra, like typing -run he starts to run, and he loose some type of Mana, but not mana, just a real / integer, and when it comes to 0 he stops runing and its regenerated. Its regenerated all the time without when he is running.

    That would be cool.. ;) +rep anyway

    EDIT:

    To add
    Hidden text
    Hello!
    just use this code: [ HIDDEN="Hidden text"]Hello![/HIDDEN] without the space.
     
  8. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    thanks man :p, yea i can do that, but thatll be another type of system :p and the bugs im working on right now are a bit hard or atleast time-consuming, anyways man yea sure il make that kind of system after i get to fix this ^^
     
  9. eleljrk

    eleljrk

    Joined:
    Aug 27, 2009
    Messages:
    461
    Resources:
    4
    Maps:
    1
    Spells:
    3
    Resources:
    4
    Yah, its gonna be like a new system, but then its gonna be even more awesome ;)

    One of the good things is that it dont lagg..

    I found something that looks like a bug, when the units are collision on the way to the top they sometimes jumps a bit..
     
  10. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    yea man that is what im trying to fix, im going to make the unit being dragged knock back nearby units so it wont happen ^^

    EDIT: Still working on knockback, but just wanted to say, i fixed the bug that Revolve and Gandalf told me ^^ was problem with some drag comparisons. Problem is the knockback has to be a monopoly effect, so il try using a premade knockback system >_< maybe dusks, problem is he has many libraries and may confuse GUI users., he also uses unit user index, sigh >_<

    edit2: il just make the unit come to a stop if he collides with another unit, since the knockback monopoly effect would need alot of functions
     
    Last edited: Oct 24, 2009
  11. eleljrk

    eleljrk

    Joined:
    Aug 27, 2009
    Messages:
    461
    Resources:
    4
    Maps:
    1
    Spells:
    3
    Resources:
    4
    Good idea, but add
    Your Topic
    to your code.. :s
     
  12. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    lul, thanks for reminding xP ok it does work now, but the problem is, since the world editor mostly uses 2D distance for unit collision, it may look wierd how a unit below another may stop him from being dragged to the ground, only for really high heights in small places that you wouldnt be able to even initially go up because of the deacceleration. well ima update..
     
    Last edited: Oct 24, 2009
  13. StaberFire

    StaberFire

    Joined:
    Jun 28, 2008
    Messages:
    683
    Resources:
    8
    Icons:
    4
    Skins:
    1
    Spells:
    3
    Resources:
    8
    When you order a move to a location past a drag spot and the unit gets dragged to the bottom, the unit does not continue to move the the ordered location.
     
  14. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    yea man, thats cus units are supposed to stop dragged units from moving, if u move the unit out of the way, he will continue being dragged; im going to add a knockback as an alternative to it, but im going to have to do a monopoly effect for it, so this is the simple and most effective solution for now. Hope ur not dissapointed :p i may have to create my own knockback system for this... sigh lul il prob use silvenons cus hes a pretty good coder;

    btw guys whats up with me not being able to copy/paste a JASS function into the acceleration map? it doesnt seem to show correctly, the indentations... trying to put Silvenons KB into the map so i can actually work on it... please help :p
     
    Last edited: Oct 24, 2009
  15. Shendoo2

    Shendoo2

    Joined:
    Aug 1, 2008
    Messages:
    464
    Resources:
    0
    Resources:
    0
    I found a bug, when you go down the hill and you want to run to the corner of you map, you stop as soon as you get to the bottom of the hill.

    Ex. Start at the top of the hill, and go to your mini map and click once in you corner so your unit will move there. He stops as soon as he gets to the bottom of the hill.

    Otherwise good system +rep
     
  16. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    oh yea man, its not because of you turning, its because the difference in height disallows you to continue sliding, i havent really included too much advanced physics, cus thatll be final velocity able to surpass the almost flat land;

    thanks man for positive comments
     
    Last edited: Oct 25, 2009
  17. eleljrk

    eleljrk

    Joined:
    Aug 27, 2009
    Messages:
    461
    Resources:
    4
    Maps:
    1
    Spells:
    3
    Resources:
    4
    Ok, ive desided to use this system for my new project.. A LOTR map, so if you would like to VM or maby PM me new updates, i would be very pleased!

    Anyway, try to fix writed bugs over here..
     
  18. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    yea man ofc, im glad ur using it for a map of yours mate ^^ btw ill be making it more efficient, even tho it already is, but il try to make it 100% efficient >_> since someone is actually planning to use this in a map of theirs :p im really happy you like it )
     
  19. eleljrk

    eleljrk

    Joined:
    Aug 27, 2009
    Messages:
    461
    Resources:
    4
    Maps:
    1
    Spells:
    3
    Resources:
    4
    Epicness ;)
    There is not so much more to say.. ^^
    Rep and Rate is already made.. xD