MoveSpeedX for GUI v1.1.0.0 (Lua)

This bundle is marked as pending. It has not been reviewed by a staff member yet.
  • Like
Reactions: deepstrasz
Hey guys this is Lua solution for MoveSpeedX by PurgeandFire. He inveted really smart way of overhauling hardcoded maximum move speed, by changing X,Y coordinates.

Core of the system is just the same, i've implemented only few changes for optimizing purposes and to simplify GUI usage of this system.

There are no requirements for this system, unit indexing is now handled by natives, so there is no need for anything like unitindexer anymore.

I am using trigger instead of timer, thats just personal preference. Trigger is now enabled only when there are some units which have ms above 522, so only when it needs to be, in original version of this mod, it ran all the time for some reason.

There are 2 native functions hooked, SetUnitMoveSpeed and GetUnitMoveSpeed as well which is even better for GUI creators. So real value of Current Unit MoveSpeed in GUI should return correct values now.

There are no GUI global variables included everything necessary is handled by script itself.

Make sure your map is Lua scripted, which u can change in Map Properties (under Script Language).


Lua:
----------------------------------------------------
---------------MOVESPEED SYSTEM SETUP---------------
----------------------------------------------------
do
    local function tableLength(t)
        local count = 0
        if t then
            for _ in pairs(t) do count = count + 1 end
        end
        return count
    end

    local MSX_PERIOD = 0.00625
    local MSX_MARGIN = 0.01

    local function ApproxEqual (A,B)
        return (A >= (B - MSX_MARGIN)) and (A <= (B + MSX_MARGIN))
    end

    local MOVESPEED_X_TABLE = {}
    local MOVESPEED_X_ISSUED_TRIGGER = CreateTrigger()
    local MOVESPEED_X_TRIGGER = CreateTrigger()
    local oldGetUnitMS = GetUnitMoveSpeed
    local oldSetUnitMS = SetUnitMoveSpeed

    local function MSX_Periodic()
        local u,order,d,dy,dx,ny,nx = nil,nil,nil,nil,nil,nil,nil
        for i,t in pairs(MOVESPEED_X_TABLE) do
            u = t.unit
            nx = GetUnitX(u)
            ny = GetUnitY(u)
            if not(IsUnitAliveBJ(u)) or GetUnitTypeId(u) == 0 then
                MOVESPEED_X_TABLE[i] = nil
            elseif not(ApproxEqual(nx, t.x)) or not(ApproxEqual(ny, t.y)) then
                if not(IsUnitPaused(u)) then
                    order = GetUnitCurrentOrder(u)
                    dx = nx - t.x
                    dy = ny - t.y
                    d  = SquareRoot(dx * dx + dy * dy)
                    dx = dx / d * t.speed
                    dy = dy / d * t.speed
                    if (order == 851986 or order == 851971) and (t.ox - nx)*(t.ox - nx) < (dx*dx) and (t.oy - ny)*(t.oy - ny) < (dy*dy) then
                        SetUnitX(u, t.ox)
                        SetUnitY(u, t.oy)
                        t.x = t.ox
                        t.y = t.oy
                        IssueImmediateOrderById(u, 851972)
                    else
                        t.x = nx + dx
                        t.y = ny + dy
                        SetUnitX(u, t.x)
                        SetUnitY(u, t.y)
                    end
                end
            end
        end
        if tableLength(MOVESPEED_X_TABLE) == 0 then
            DisableTrigger(MOVESPEED_X_TRIGGER)
        end
    end

    local function MSX_storeOrderPoint()
        local u_id = GetHandleIdBJ(GetTriggerUnit())
        if MOVESPEED_X_TABLE[u_id] then
            MOVESPEED_X_TABLE[u_id].ox = GetOrderPointX()
            MOVESPEED_X_TABLE[u_id].oy = GetOrderPointY()
        end
    end

    local function MSX_Create (whichUnit,newSpeed)
        local u_id = GetHandleIdBJ(whichUnit)
        MOVESPEED_X_TABLE[u_id] = MOVESPEED_X_TABLE[u_id] or {
            unit = whichUnit
            ,x = GetUnitX(whichUnit)
            ,y = GetUnitY(whichUnit)
        }
        MOVESPEED_X_TABLE[u_id].speed = (newSpeed - 522) * MSX_PERIOD
        if not(IsTriggerEnabled(MOVESPEED_X_TRIGGER)) then
            EnableTrigger(MOVESPEED_X_TRIGGER)
        end
    end

    local function MSX_Update (whichUnit,newSpeed)
        local u_id = GetHandleIdBJ(whichUnit)
        if newSpeed > 522 then
            MSX_Create(whichUnit,newSpeed)
        else
            MOVESPEED_X_TABLE[u_id] = nil
        end
    end

    function GetUnitMoveSpeed(whichUnit)
        local u_id = GetHandleIdBJ(whichUnit)
        if MOVESPEED_X_TABLE[u_id] then
            return (MOVESPEED_X_TABLE[u_id].speed / MSX_PERIOD) + 522
        end
        return oldGetUnitMS(whichUnit)
    end

    function SetUnitMoveSpeed(whichUnit,newSpeed)
        oldSetUnitMS(whichUnit, newSpeed)
        MSX_Update(whichUnit, newSpeed)
    end

    local oldInit = InitBlizzard
    function InitBlizzard()
        oldInit()

        TriggerRegisterTimerEventPeriodic(MOVESPEED_X_TRIGGER, MSX_PERIOD)
        TriggerAddAction(MOVESPEED_X_TRIGGER, MSX_Periodic)
        TriggerRegisterAnyUnitEventBJ(MOVESPEED_X_ISSUED_TRIGGER, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
        TriggerAddAction(MOVESPEED_X_ISSUED_TRIGGER, MSX_storeOrderPoint)
    end
end
Contents

MoveSpeedX GUI (Map)

AGD

AGD

Level 13
Joined
Mar 29, 2016
Messages
677
You need to observe proper encapsulation for some of your functions (make them local). It's also better to automate the running of the initialization function. You can use [Lua] Global Initialization, or if you want no extra requirements you can simply change MSX_Initialize() into:
Lua:
do
    ... -- rest of your code

    local oldInit = InitBlizzard
    function InitBlizzard()
        oldInit()

        TriggerRegisterTimerEventPeriodic(MOVESPEED_X_TRIGGER, MSX_PERIOD)
        TriggerAddAction(MOVESPEED_X_TRIGGER, MSX_Periodic)
        TriggerRegisterAnyUnitEventBJ(MOVESPEED_X_ISSUED_TRIGGER, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
        TriggerAddAction(MOVESPEED_X_ISSUED_TRIGGER, MSX_storeOrderPoint)
    end
end
 
Last edited:
Level 5
Joined
Dec 29, 2019
Messages
61
You need to observe proper encapsulation for some of your functions (make them local). It's also better to automate the running of the initialization function. You can use [Lua] Global Initialization, or if you want no extra requirements you can simply change MSX_Initialize() into:
Lua:
...

local oldInit = InitBlizzard
function InitBlizzard()
    oldInit()

    TriggerRegisterTimerEventPeriodic(MOVESPEED_X_TRIGGER, MSX_PERIOD)
    TriggerAddAction(MOVESPEED_X_TRIGGER, MSX_Periodic)
    TriggerRegisterAnyUnitEventBJ(MOVESPEED_X_ISSUED_TRIGGER, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)
    TriggerAddAction(MOVESPEED_X_ISSUED_TRIGGER, MSX_storeOrderPoint)
end
What is the point of making them local if i may ask ?
 
Level 5
Joined
Dec 29, 2019
Messages
61
To make functions not meant to be used by users totally out of their reach, such as those with MSX_ prefix (and others, only expose the functions meant to be really used, in this case the Set/GetUnitMoveSpeed).

Oh i am steal learning lua properly, wasn't sure about some scoping essentials. So when i include the code into "do end" scope and mark "private" functions (not accesible outside of the scope) with "local" keyword it means they wont be usable in other scripts right ? Is this only for access purposes or does it even make memory more optimized ? Like making functions local means memory dont have to keep them stored in global vars ? Not sure how debugger works in here exactly.
 
Level 5
Joined
Dec 29, 2019
Messages
61
Yeah it is only for access purposes. I'm not very familiar with the internal workings of the lua interpreter either, but in this case I'm pretty sure it doesn't affect memory usage in a significant sense (if it even does).

Thanks for explanation, i've edited code in the map + description and hooked native Init function as well (nice advice +rep :))
 
Top