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. We have recently started the 16th edition of the Mini Mapping Contest. The theme is mini RPG. Do check it out and have fun.
    Dismiss Notice
  5. Choose your ride to damnation in the 5th Special Effect Contest Poll.
    Dismiss Notice
  6. The winners of the 13th Techtree Contest have been announced!
    Dismiss Notice
  7. The 13th Music Contest Poll is up! Vote for the best tracks in this symphony of frost and flame.
    Dismiss Notice
  8. Race against the odds and Reforge, Don't Refund. The 14th Techtree Contest has begun!
    Dismiss Notice
  9. 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. Catch_ya

    Catch_ya

    Joined:
    May 21, 2009
    Messages:
    982
    Resources:
    1
    Spells:
    1
    Resources:
    1
    So diehard the only problem with this right know is a need of more documentation and and make it more configureable and make unit move after dragged i dunno what it means but this seems like a simple thing for you ^^ :D its getting better all the time mate

    I dont download it yet.. Or i have the oldest version but I wait to the last update ^^
     
  2. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    hehe thanks man, i only changed timer iteration from 0.30 to 0.15 cus some newbs may not be able to do so, since its smoother this way ^^

    as for the documentation the problem is u gotta grasp the concept of how it works to be able to know how to change it so well ;P just know about the gravity constant since it decreases the acceleration/deacceleration rate, and the NoDrag variable which determines how steep a place needs to be so units can be dragged down (i put 10, as in the diff in Z between a place and another needs to be over 10)

    just tell me what u need and il tell you how to configure ;P
    thanks for positive review mate, and we should really play bnet sometime >_>

    btw im creating a realistic systems pack, combining this with them too so i hope ulll like it ^^
     
  3. Catch_ya

    Catch_ya

    Joined:
    May 21, 2009
    Messages:
    982
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Yea the gravity and NoDag variable people must test some different values to get an idea of how much it changes each number if you understand me ^^ ..

    About the B.net SURE! i'll pm you..
     
  4. Anachron

    Anachron

    Joined:
    Sep 9, 2007
    Messages:
    6,221
    Resources:
    66
    Icons:
    49
    Packs:
    2
    Tools:
    1
    Maps:
    3
    Spells:
    9
    Tutorials:
    1
    JASS:
    1
    Resources:
    66
    Would be cool if you could actually just recreate the wc3 game engine.
     
  5. YourNameHere

    YourNameHere

    Joined:
    Apr 29, 2007
    Messages:
    745
    Resources:
    4
    Maps:
    1
    Spells:
    2
    JASS:
    1
    Resources:
    4
    Oh yeah! Let's ask Blizzard for the sourcecode.
     
  6. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    Problem is theyr constant lol; so giving the option to do so ingame will decrease programming efficienecy >_>

    So Anachron maybe we can do a 3d movement system with all physics included, but i cant do it alone at all, i need ur programming help along with ur math help xD

    btw i updated to 0.14 cus i improved coding efficiency slightly >_>
     
  7. Zealon

    Zealon

    Joined:
    Mar 13, 2010
    Messages:
    1,142
    Resources:
    0
    Resources:
    0
    Wow nice idea!
     
  8. medion555

    medion555

    Joined:
    Jun 20, 2008
    Messages:
    467
    Resources:
    0
    Resources:
    0
    How can i let it affect every unit that is entering the map ?
     
  9. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    @Zealon

    Thanks alot bro, Im sure you have some cool ideas of your own that you will be able to do when you get good at coding ;)

    @medion555

    A unit enters map, then add the accelleration to the entering, or better yet triggering unit. Just make sure to remove acceleration if a unit dies. Also add acceleration to all the units that are preset in the map in the map Init. BTW if a hero dies no need to remove acceleration if he will be revived. Good luck ^^
     
  10. medion555

    medion555

    Joined:
    Jun 20, 2008
    Messages:
    467
    Resources:
    0
    Resources:
    0
    thx for the quick reply i changed the map ini trigger event to when a unit enterws playable map region and when i wanted to test the map a lot of errors occured
     
  11. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    np :) Ok you have to:

    Make another trigger for the Unit Enters Playable Map Area and then copy paste this
    Code (vJASS):
    call AddUnitAcceleration(GetTriggerUnit())


    As for the on init trigger just create a unit group variable which has all the units the playable map area and then pick every unit in the group, then paste this
    Code (vJASS):
    call AddUnitAcceleration(GetEnumUnit())


    Make a trigger for a unit that leaves playable map area and paste this
    Code (vJASS):
    call RemoveUnitAcceleration(GetTriggerUnit())


    Now make a trigger in which if a unit dies, you will remove its corpse after 2.5 (or any higher number, max would probably be 5) seconds (so they can play their death animation). Now create a new unit group variable and make sure all the heroes or even units that you want to still have acceleration after they die will be in that group (because maybe you want to revive the hero or do something wierd with the unit). Now just do the check if the dying unit is in that group or not, if not then proceed to removing the unit out of the game.

    This part might seem confusing so here is the trigger:
    • Removing unit corpse
      • Events
        • Unit - A unit Dies
      • Conditions
        • ((Triggering unit) is in UnitsWithAcceleration) Equal to False
      • Actions
        • Wait 2.50 seconds
        • Unit - Remove (Triggering unit) from the game


    *Copy paste the line codes in seperate custom script actions.

    ~ Happy Mapping!
     
  12. Zealon

    Zealon

    Joined:
    Mar 13, 2010
    Messages:
    1,142
    Resources:
    0
    Resources:
    0
    Thank you for the complement, this is a great system 5/5 +rep
     
  13. Diehard@Azeroth

    Diehard@Azeroth

    Joined:
    Sep 21, 2007
    Messages:
    483
    Resources:
    1
    Spells:
    1
    Resources:
    1
    @Zealon

    Appreciate it bro, if you need any requests for systems just tell me ^^
     
  14. .OmG.

    .OmG.

    Joined:
    May 9, 2010
    Messages:
    256
    Resources:
    2
    Spells:
    2
    Resources:
    2
    May be usefull.
     
  15. MiniMage

    MiniMage

    Joined:
    Jun 5, 2008
    Messages:
    1,752
    Resources:
    22
    Models:
    21
    Skins:
    1
    Resources:
    22
    Is there any better way to add the effects to units other than individually adding them one by one to the system? :O
     
  16. aider

    aider

    Joined:
    Jul 14, 2010
    Messages:
    248
    Resources:
    2
    Maps:
    2
    Resources:
    2
    This is so cool, but this wont work for a herodefense map with a lot of units right? I need to add units already in the game and it will only work for that unit(?)