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.

MoveSpeedX for GUI v1.1.0.0

Submitted by PurgeandFire
This bundle is marked as approved. It works and satisfies the submission rules.
Requires JassNewGenPack v5d and JassHelper 0.A.2.B!

This library allows you to set unit move speeds beyond the 522 limit. Special thanks to Jesus4Lyf for the base code. It has been modified from the normal MoveSpeedX to be compatible with GUI. While the system is in vJASS, you can simply use the GUI function to modify the speed and it will do the rest for you. To retrieve speed properly, you can use the global array named "UnitSpeedX". To retrieve it for a specific unit, it would be UnitSpeedX[Custom value of <unit>]. Note that you need a unit indexer for that to work properly.

It has some quirks with very high speeds (beyond ~1000) but otherwise it works perfectly.

*Note*: Please read the documentation.

System:
Code (vJASS):
library MoveSpeedXGUI /* v1.1.0.0
*************************************************************************************
*
*   This library allows you to set unit movement speeds beyond 522 without bugs.
*   This is an extension of the library MoveSpeedX, but is formatted for GUI use.
*   Credits to Jesus4Lyf for the original system.
*
************************************************************************************
*
*   SETTINGS
*/

globals
    private constant real PERIOD = 0.03125
        //  This is the period on which all units will be run.
        // If you lower this value, movement bonuses will be smoother,
        // but will require more processing power (lag more).
        //  Also, the lower this is, the higher the move speed can be
        // before it starts bugging on waypoints. The lowest valid
        // period is 0.00125. A period of 0.00625 is very robust.
    private constant real MARGIN = 0.01
        // This is the margin of approximation when comparing reals.
        // You will most likely not need to change this.
endglobals
/*
************************************************************************************
*
*    Functions
*
*        function GetUnitMoveSpeedX takes unit whichUnit returns real
*           - Returns a unit movement speed. The GUI function will
*           - not return the correct value. This function will always
*           - return the correct value regardless of whether the unit
*           - has a movement speed beyond 522.
*
************************************************************************************
*
*   REQUIREMENTS
*
*       1.  JassNewGen Pack v5d
*       2.  JassHelper 0.A.2.B
*       3.  Any unit indexer
*
*   HOW TO IMPLEMENT
*  
*       1.  Copy the 'folder' MoveSpeedX.
*       2.  Paste it into your map.
*       3.  Open "Advanced -> Gameplay Constants".
*       4.  Checkmark "Use Custom Gameplay Constants".
*       5.  Find the field, "Movement - Unit Speed - Maximum", change
*           that to 522.
*       6.  Find the field, "Movement - Unit Speed - Minimum", hold
*           shift and click, and change it to 0.
*       7.  Read HOW TO USE.
*
************************************************************************************
*
*   HOW TO USE
*
*       This system will automatically work by itself. You can use the
*       normal GUI function for modifying unit movement speeds. Simply
*       use "Unit - Set Movement Speed", input whatever value you want,
*       and you are good to go! It will handle values beyond 522 by itself.
*
*       HOWEVER, the GUI function will not return correct values if a unit
*       has a movement speed greater than 522. To fix this, use the function
*       GetUnitMoveSpeedX to return the correct value. A sample is given in
*       the trigger "Speed Change" in the test map.
*
************************************************************************************
*
*   NOTES
*
*       Units that were issued orders as groups might not *always* end up in the proper
*       "order". (they might not end up in an organized formation) They do sometimes though.
*       This is only for units with speeds above 522.
*
*       This also will not factor in bonuses and probably not slows either.
*
*       Units may waddle around the point for a little bit. Reduce PERIOD to fix
*       it a little bit. I recommend about 0.02 if you have really high speeds.
*
************************************************************************************/


    private function ApproxEqual takes real A, real B returns boolean
        return (A >= (B - MARGIN)) and (A <= (B + MARGIN))
    endfunction
   
    private module M
        private static trigger issued = CreateTrigger()
       
        thistype next
        thistype prev
       
        boolean enabled
        unit curr
        real speed
        real x
        real y
        real ox
        real oy
       
        method destroy takes nothing returns nothing
            set this.next.prev = this.prev
            set this.prev.next = this.next
            set this.enabled = false
        endmethod
           
        private static method periodic takes nothing returns nothing
            local thistype this = thistype(0).next // first instance in list
            local real nx // the x-coordinate after tick
            local real ny // the y-coordinate after tick
            local real dx // distance between new-x and old-x
            local real dy // distance between new-y and old-y
            local real d  // distance between new point and old point
            local integer order // the unit's current order
            local unit u // unit being affected
            loop
                exitwhen this == 0
                set u  = .curr
                set nx = GetUnitX(u)
                set ny = GetUnitY(u)
                if IsUnitType(u, UNIT_TYPE_DEAD) then
                    call this.destroy()
                elseif not ApproxEqual(nx, .x) or not ApproxEqual(ny, .y) then
                    if (not IsUnitPaused(u)) and GetUnitAbilityLevel(u, 'BSTN') == 0 and GetUnitAbilityLevel(u, 'BPSE') == 0 then
                        set order = GetUnitCurrentOrder(u)
                        set dx = nx - .x
                        set dy = ny - .y
                        set d  = SquareRoot(dx * dx + dy * dy)
                        set dx = dx / d * .speed // move the unit offset-x by this
                        set dy = dy / d * .speed // move the unit offset-y by this
                       
                        if (order == 851986 or order == 851971) and /*
                        */
(this.ox - nx)*(this.ox - nx) < (dx*dx) and /*
                        */
(this.oy - ny)*(this.oy - ny) < (dy*dy) then
                            // if the unit is issued a move or smart order and they are near their destination
                            // then move them there instantly (removes a bit of glitchyness towards the end)
                            call SetUnitX(u, .ox)
                            call SetUnitY(u, .oy)
                            set .x = .ox
                            set .y = .oy
                            call IssueImmediateOrderById(u, 851972) // order them to stop
                        else
                            set .x = nx + dx
                            set .y = ny + dy
                            call SetUnitX(u, .x)
                            call SetUnitY(u, .y)
                        endif
                    endif
                endif
                set this = this.next
            endloop
            set u = null
        endmethod
       
        static method create takes unit whichUnit, real newSpeed returns thistype
            local thistype this = GetUnitUserData(whichUnit)
            set this.next = thistype(0).next
            set thistype(0).next.prev = this
            set thistype(0).next = this
            set this.prev  = 0
            set this.curr  = whichUnit
            set this.speed = (newSpeed - 522) * PERIOD
            set this.x     = GetUnitX(whichUnit)
            set this.y     = GetUnitY(whichUnit)
            set this.enabled = true
            return this
        endmethod
       
        static method update takes unit whichUnit, real newSpeed returns nothing
            local thistype this = GetUnitUserData(whichUnit)
            if this.enabled then
                if newSpeed > 522 then
                    set this.speed = (newSpeed - 522) * PERIOD
                else
                    call this.destroy()
                endif
            elseif newSpeed > 522 then
                call thistype.create(whichUnit, newSpeed)
            endif
        endmethod
       
        private static method storeOrderPoint takes nothing returns boolean
            local thistype this = GetUnitUserData(GetTriggerUnit())
            set this.ox = GetOrderPointX()
            set this.oy = GetOrderPointY()
            return false
        endmethod
   
        private static method onInit takes nothing returns nothing
            call TimerStart(CreateTimer(), PERIOD, true, function thistype.periodic)
            call TriggerRegisterAnyUnitEventBJ(issued, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
            call TriggerAddCondition(issued, Condition(function thistype.storeOrderPoint))
        endmethod
    endmodule
   
    private struct MoveSpeedStruct extends array
        implement M
    endstruct
   
    function GetUnitMoveSpeedX takes unit whichUnit returns real
        if MoveSpeedStruct(GetUnitUserData(whichUnit)).enabled then
            return udg_UnitSpeedX[GetUnitUserData(whichUnit)]
        endif
        return GetUnitMoveSpeed(whichUnit)
    endfunction
   
    function SetUnitMoveSpeedX takes unit whichUnit, real newSpeed returns nothing
        call MoveSpeedStruct.update(whichUnit, newSpeed)
        set udg_UnitSpeedX[GetUnitUserData(whichUnit)] = newSpeed
    endfunction

    hook SetUnitMoveSpeed SetUnitMoveSpeedX
endlibrary


Please report any bugs.

Changelog:
1.0.0.0 - Initial release
1.0.0.1 - Minor changes to constants.
1.1.0.0 - No longer requires JASS for retrieving speeds. Updated to use a unit indexer for faster speeds. Also is less prone to glitchy movement towards the end.

Keywords:
move, speed, nitro, boost, movespeed, movespeedx, sprint, dash
Contents

MoveSpeedX GUI (Map)

Reviews
Moderator
24th Nov 2011 Bribe: Approved and highly recommended.
  1. 24th Nov 2011
    Bribe: Approved and highly recommended.
     
  2. makai

    makai

    Joined:
    Apr 30, 2010
    Messages:
    320
    Resources:
    2
    Models:
    2
    Resources:
    2
    interesting, lemme check...
     
  3. Ironside

    Ironside

    Joined:
    Feb 3, 2009
    Messages:
    2,723
    Resources:
    4
    Maps:
    3
    Tutorials:
    1
    Resources:
    4
    I'll test it today as well.
     
  4. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,036
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Instead of ".rn" use the ".prev" member.

    Make a local unit to store ".curr" so you don't spam array referencing.

    It doesn't matter but "set thistype(0).next.prev = 0" is faster than "set this.next.prev = 0".

    You can initialize "hash" from the globals block and use a library initializer for the timer. This prevents the need of the struct altogether.
     
  5. Chaosy

    Chaosy

    Joined:
    Jun 9, 2011
    Messages:
    10,611
    Resources:
    18
    Maps:
    1
    Spells:
    11
    Tutorials:
    6
    Resources:
    18
    downloading it and i will edit this post after

    EDIT dont work for me since i got the WE sad i expected it to work when title sais GUI :p
     
  6. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,427
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    kk I'll update it soon.

    Sorry, it needs Jass NewGen Pack v5d. You can download it here:
    http://www.wc3c.net/showthread.php?t=90999

    It is GUI-friendly in the sense that you don't need to use any JASS functions to modify the unit's movement speed. You can just use the normal function as shown in the test map. ;)

    Thanks everyone else for the comments.

    EDIT: Updated for Bribe's comments.
     
    Last edited: Nov 25, 2011
  7. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,006
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    Looks pretty good :)
    5/5:

    - Efficient
    - Readable
    - Useful
    - Bugless
     
  8. nerovesper

    nerovesper

    Joined:
    Sep 29, 2008
    Messages:
    614
    Resources:
    2
    Maps:
    1
    Spells:
    1
    Resources:
    2
    just a question, when checking for the movement speed through triggers for example the Unit - (current movespeed) will it show the over 522 movespeed or 522 or something?
     
  9. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,427
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    When you check it through triggers, it will show 522 speed. Sadly, JassNewGen didn't expand its features much on hooking so I can only detect when functions occur; I can't override them. =(

    That's why the JASS function has to be used.
    GetUnitMoveSpeedX(unit)


    Here are some examples:
    • Custom script: set udg_TempReal = GetUnitMoveSpeedX(udg_MyUnit)
    • // Retrieves the movement speed of the unit of "MyUnit" and assigns it to "TempReal"
    • Custom script: set udg_TempReal = GetUnitMoveSpeedX(GetTriggerUnit())
    • // Retrieves the movement speed of the triggering unit and assigns it to "TempReal"


    However, you can set the movement speed however you want as normal.
    • Unit - Set <Unit> movement speed to 1043

    That would work just fine; my system would detect it and do everything accordingly.
     
  10. Mr_Bean

    Mr_Bean

    Joined:
    Feb 11, 2011
    Messages:
    1,823
    Resources:
    6
    Maps:
    2
    Spells:
    4
    Resources:
    6
    Awesome system. Using it in my map!

    5/5
     
  11. kStiyl

    kStiyl

    Joined:
    Oct 23, 2011
    Messages:
    180
    Resources:
    1
    JASS:
    1
    Resources:
    1
    Would this bug if I use SetUnitX/Y/Position? since it would probably think the unit moved

    If so, should i hook those functions
    and do something like this?

    set MoveSpeedStruct[unit].x = new x
     
  12. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,427
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    Now that I think about it, it may have a slight chance to accelerate the movement if you have something that moves the unit, such as a knockback.

    Although, if you pause the unit before moving them, it will not cause any problems.

    I'll run tests eventually and update this system if I find any problems. Thanks for bringing that to my attention. :) I could either add an option to disable the system for a unit (in case you need to move the unit), or I suppose i could also check if the unit is issued an order or not.

    I based this off of MoveSpeedX by Jesus4Lyf so I didn't do too much bug testing aside from the actual system.
     
  13. kStiyl

    kStiyl

    Joined:
    Oct 23, 2011
    Messages:
    180
    Resources:
    1
    JASS:
    1
    Resources:
    1
    the system also bugs when you order a group of units to move (they will try to allign in movement)
     
  14. .OmG.

    .OmG.

    Joined:
    May 9, 2010
    Messages:
    256
    Resources:
    2
    Spells:
    2
    Resources:
    2
    A flying units are stopping on every unit o decoration...
     
  15. SDM

    SDM

    Joined:
    May 7, 2012
    Messages:
    2
    Resources:
    0
    Resources:
    0
    hey an author i have a little question.Why does hero moves after he reach the target point.The model moves right and left some times and then stops.How can we skip that?
     
  16. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,427
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    Oh yeah it happens when he moves too fast. Sometimes he'll skip over the spot he wants to walk on, and that causes him to end up cycling back and forth until he gets to the right spot.

    This thing hasn't been completely bug fixed. If I get back on my other computer, I'll try to fix or reduce it.

    One fix:
    Code (vJASS):
    private constant real PERIOD = 0.03125
            //  This is the period on which all units will be run.
            // If you lower this value, movement bonuses will be smoother,
            // but will require more processing power (lag more).
            //  Also, the lower this is, the higher the move speed can be
            // before it starts bugging on waypoints. The lowest valid
            // period is 0.00125. A period of 0.00625 is very robust.

    You can change the period to be a bit lower and it may fix that problem or at least reduce the amount of occurrences.
     
    Last edited: Jun 21, 2012
  17. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,006
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    The fix for this is a bit ugly and slow.
    After hitting a certain threshold for speed, you would reduce the timer period.
    This way, users wouldn't have problems with this and they wouldn't post here, because the problem would never occur.
    (Unless they make crazy movement speeds like 40000 or something.)
     
  18. SDM

    SDM

    Joined:
    May 7, 2012
    Messages:
    2
    Resources:
    0
    Resources:
    0
    i've just used 1500 or 1000 movement speed and he skips from point to point. I'll wait your fix,thanks
     
  19. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,427
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    Sorry for the long wait. I've updated the system to fix some of the glitchiness. It may skip around a bit on the way to the path, but that would require reworking the whole thing to completely remove. Just reduce the PERIOD constant to try to make it less glitchy.

    Maybe I'll do mag's method eventually, but for now it should work pretty well. It takes up a bit more performance math-wise, but it is nothing noticeable ingame even on my crappy computer. If a unit is close enough to the point they've been issued to, then it will just put them there so they don't waddle around like a headless chicken trying to get on the right spot.

    This new version also has a global to track speeds so you don't need to use custom script anymore. However, it now requires a unit indexer. (Bribe's is the one used in my test map)

    Hopefully people will have fewer problems!