• 🏆 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!

Hill movement speed

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
Slows units that go up the hill. accelerate the units that go downhill.

Fixed by:
WereElf;2794635 said:
Well, I took the liberty and fixed your system for you.
There ya go:
JASS:
function Trig_walk_speed_Actions takes nothing returns boolean
    local unit u
    local real def
    local location loc
    local location loc_tar
    local real z1
    local real z2
    call GroupEnumUnitsInRect( udg_MoveGroup, bj_mapInitialPlayableArea, null )
    loop
        set u = FirstOfGroup( udg_MoveGroup )
        exitwhen u == null
        if not IsUnitType( u , UNIT_TYPE_STRUCTURE ) and not IsUnitType( u , UNIT_TYPE_FLYING ) then
            set def = GetUnitDefaultMoveSpeed(u)
            set loc = GetUnitLoc(u)
            set loc_tar = PolarProjectionBJ( loc, 10.00, GetUnitFacing(u))
            set z1 = GetLocationZ(loc)
            set z2 = GetLocationZ(loc_tar)
            if z1 < z2 then
                call SetUnitMoveSpeed( u, def - (z2 - z1)*20 )
            elseif z1 > z2 then
                call SetUnitMoveSpeed( u, def + (z1 - z2)*10 )
            else
                call SetUnitMoveSpeed( u, def )
            endif
            call RemoveLocation(loc)
            call RemoveLocation(loc_tar)
        endif
        call GroupRemoveUnit( udg_MoveGroup, u )
    endloop
    set loc_tar = null
    set loc = null
    return false
endfunction

//===========================================================================
function InitTrig_walk_speed takes nothing returns nothing
    set gg_trg_walk_speed = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_walk_speed, 0.1 )
    call TriggerAddCondition( gg_trg_walk_speed, Condition(function Trig_walk_speed_Actions) )
endfunction

You can improve it further from here :)
The speed change is configured by changing the *20 and *10 to something else.
I could've made it configurable by a variable, but it would've required vJASS. And I saw that you've made it in WE, so I didn't convert it to vJASS.

What I did:
1) Made the trigger run every 0.1 seconds, instead of every 0.02 seconds
2) Changed the "action" to "condition"
3) Started assigning the values to variables, instead of calling functions to get the values every time you need them.
4) Using First of Group method to do the loop, instead of "For Group", and stopped leaking a unit group every 0.02 seconds (50 groups leaked every second) :D
5) Doing the speed change, based on the unit's default speed, instead of on its "current" speed, thus now it works well with items/abilities, and it doesn't increase/decrease the unit's speed to max/min allowed, instead - it sets it to some value, based on the steepness of the hill.
6) Stopped changing the movespeed of structures, and flying units.
7) Moved the 'if's inside the main function, instead of calling external functions to do the check.
8) Started clearing location leaks.

And that's about all I did :p

Keywords:
hill, walk, speed, movement
Contents

Další mapa pro Warcraft III (Map)

Reviews
10:37, 13th March 2016 Tank-Commander: V1.2 - improved but still lots of problems, here's my post on what's wrong 19:35, 27th Feb 2016 Tank-Commander: There's a lot wrong with the system programmatically, please look at my points here and...

Moderator

M

Moderator

10:37, 13th March 2016
Tank-Commander: V1.2 - improved but still lots of problems, here's my post on what's wrong


19:35, 27th Feb 2016
Tank-Commander: There's a lot wrong with the system programmatically, please look at my points here and update the system
 
The concept is exceptionally simple and the coding is very shoddy:
1) The code is a converted GUI trigger which was just converted to JASS
2) The code while being 10 lines which aren't function definition lines, returns or "endif" (of converted GUI) leaks roughly 12 times each iteration
3) There are else parts of the code which need not be there as there are no else actions
4) There's no configuration for the system (how far to check each side, periodic timer speed)
5) Periodic timer is set to 0.02 - should be 0.03 when this is performed on every unit
6) Move speed is a risky thing to control via triggers - it's better to use the slow ability as to avoid permanently affecting the movement speed of a unit when other abilities interact with the system
7) The entire system could be put into a single function (other than the init function)
8) There doesn't need to be three if statements on what to do based on the angle of the incline - if the incline is flat the default movement speed will automatically return

Please read This thread and have a look at some of our Tutorials on the site
 
Level 10
Joined
Aug 21, 2010
Messages
316
I tested this with the boots of speed ,rune of speed , cripple and bloodlust.There is a serious conflict with the above.Manipulation with speed involves a lot of factors and not just climbing the hill.You say you're a beginner.My suggestion is that you give up from this for now.
 
Last edited:
Level 12
Joined
Jan 2, 2016
Messages
973
Well, I took the liberty and fixed your system for you.
There ya go:
JASS:
function Trig_walk_speed_Actions takes nothing returns boolean
    local unit u
    local real def
    local location loc
    local location loc_tar
    local real z1
    local real z2
    call GroupEnumUnitsInRect( udg_MoveGroup, bj_mapInitialPlayableArea, null )
    loop
        set u = FirstOfGroup( udg_MoveGroup )
        exitwhen u == null
        if not IsUnitType( u , UNIT_TYPE_STRUCTURE ) and not IsUnitType( u , UNIT_TYPE_FLYING ) then
            set def = GetUnitDefaultMoveSpeed(u)
            set loc = GetUnitLoc(u)
            set loc_tar = PolarProjectionBJ( loc, 10.00, GetUnitFacing(u))
            set z1 = GetLocationZ(loc)
            set z2 = GetLocationZ(loc_tar)
            if z1 < z2 then
                call SetUnitMoveSpeed( u, def - (z2 - z1)*20 )
            elseif z1 > z2 then
                call SetUnitMoveSpeed( u, def + (z1 - z2)*10 )
            else
                call SetUnitMoveSpeed( u, def )
            endif
            call RemoveLocation(loc)
            call RemoveLocation(loc_tar)
        endif
        call GroupRemoveUnit( udg_MoveGroup, u )
    endloop
    set loc_tar = null
    set loc = null
    return false
endfunction

//===========================================================================
function InitTrig_walk_speed takes nothing returns nothing
    set gg_trg_walk_speed = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_walk_speed, 0.1 )
    call TriggerAddCondition( gg_trg_walk_speed, Condition(function Trig_walk_speed_Actions) )
endfunction

You can improve it further from here :)
The speed change is configured by changing the *20 and *10 to something else.
I could've made it configurable by a variable, but it would've required vJASS. And I saw that you've made it in WE, so I didn't convert it to vJASS.

What I did:
1) Made the trigger run every 0.1 seconds, instead of every 0.02 seconds
2) Changed the "action" to "condition"
3) Started assigning the values to variables, instead of calling functions to get the values every time you need them.
4) Using First of Group method to do the loop, instead of "For Group", and stopped leaking a unit group every 0.02 seconds (50 groups leaked every second) :D
5) Doing the speed change, based on the unit's default speed, instead of on its "current" speed, thus now it works well with items/abilities, and it doesn't increase/decrease the unit's speed to max/min allowed, instead - it sets it to some value, based on the steepness of the hill.
6) Stopped changing the movespeed of structures, and flying units.
7) Moved the 'if's inside the main function, instead of calling external functions to do the check.
8) Started clearing location leaks.

And that's about all I did :p
 
Last edited:
Level 10
Joined
Aug 21, 2010
Messages
316
Well, I took the liberty and fixed your system for you.
There ya go:
JASS:
function Trig_walk_speed_Actions takes nothing returns boolean
    local unit u
    local real def
    local location loc
    local location loc_tar
    local real z1
    local real z2
    call GroupEnumUnitsInRect( udg_MoveGroup, bj_mapInitialPlayableArea, null )
    loop
        set u = FirstOfGroup( udg_MoveGroup )
        exitwhen u == null
        if not IsUnitType( u , UNIT_TYPE_STRUCTURE ) and not IsUnitType( u , UNIT_TYPE_FLYING ) then
            set def = GetUnitDefaultMoveSpeed(u)
            set loc = GetUnitLoc(u)
            set loc_tar = PolarProjectionBJ( loc, 10.00, GetUnitFacing(u))
            set z1 = GetLocationZ(loc)
            set z2 = GetLocationZ(loc_tar)
            if z1 < z2 then
                call SetUnitMoveSpeed( u, def - (z2 - z1)*20 )
            elseif z1 > z2 then
                call SetUnitMoveSpeed( u, def + (z1 - z2)*10 )
            else
                call SetUnitMoveSpeed( u, def )
            endif
            call RemoveLocation(loc)
            call RemoveLocation(loc_tar)
        endif
        call GroupRemoveUnit( udg_MoveGroup, u )
    endloop
    set loc_tar = null
    set loc = null
    return false
endfunction

//===========================================================================
function InitTrig_walk_speed takes nothing returns nothing
    set gg_trg_walk_speed = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_walk_speed, 0.1 )
    call TriggerAddCondition( gg_trg_walk_speed, Condition(function Trig_walk_speed_Actions) )
endfunction

You can improve it further from here :)
The speed change is configured by changing the *20 and *10 to something else.
I could've made it configurable by a variable, but it would've required vJASS. And I saw that you've made it in WE, so I didn't convert it to vJASS.

What I did:
1) Made the trigger run every 0.1 seconds, instead of every 0.02 seconds
2) Changed the "action" to "condition"
3) Started assigning the values to variables, instead of calling functions to get the values every time you need them.
4) Using First of Group method to do the loop, instead of "For Group", and stopped leaking a unit group every 0.02 seconds (50 groups leaked every second) :D
5) Doing the speed change, based on the unit's default speed, instead of on its "current" speed, thus now it works well with items/abilities, and it doesn't increase/decrease the unit's speed to max/min allowed, instead - it sets it to some value, based on the steepness of the hill.
6) Stopped changing the movespeed of structures, and flying units.
7) Moved the 'if's inside the main function, instead of calling external functions to do the check.
8) Started clearing location leaks.

And that's about all I did :p

You could avoid polarprobj
 
Level 12
Joined
Jan 2, 2016
Messages
973
You could avoid polarprobj

Yes, I know I could, but I'd just end up writing the same code as PolarProjectionBJ. That BJ function is well made - nothing unneeded in it, so why not use it?

Instead of declaring 3 more variables, and wasting 4 more rows (7 in total) of code to get it done, why not just use the function, that's already doing it for me? :p
 
Level 10
Joined
Aug 21, 2010
Messages
316
Yes, I know I could, but I'd just end up writing the same code as PolarProjectionBJ. That BJ function is well made - nothing unneeded in it, so why not use it?

Instead of declaring 3 more variables, and wasting 4 more rows (7 in total) of code to get it done, why not just use the function, that's already doing it for me? :p

You do not need any variables for this,but it does not matter,forget it.
 
Level 2
Joined
Dec 17, 2014
Messages
5
Thanks

Thanks, I don't know how to fix it :D, I'm little bit noob with scripts :D
Well, I took the liberty and fixed your system for you.
There ya go:
JASS:
function Trig_walk_speed_Actions takes nothing returns boolean
    local unit u
    local real def
    local location loc
    local location loc_tar
    local real z1
    local real z2
    call GroupEnumUnitsInRect( udg_MoveGroup, bj_mapInitialPlayableArea, null )
    loop
        set u = FirstOfGroup( udg_MoveGroup )
        exitwhen u == null
        if not IsUnitType( u , UNIT_TYPE_STRUCTURE ) and not IsUnitType( u , UNIT_TYPE_FLYING ) then
            set def = GetUnitDefaultMoveSpeed(u)
            set loc = GetUnitLoc(u)
            set loc_tar = PolarProjectionBJ( loc, 10.00, GetUnitFacing(u))
            set z1 = GetLocationZ(loc)
            set z2 = GetLocationZ(loc_tar)
            if z1 < z2 then
                call SetUnitMoveSpeed( u, def - (z2 - z1)*20 )
            elseif z1 > z2 then
                call SetUnitMoveSpeed( u, def + (z1 - z2)*10 )
            else
                call SetUnitMoveSpeed( u, def )
            endif
            call RemoveLocation(loc)
            call RemoveLocation(loc_tar)
        endif
        call GroupRemoveUnit( udg_MoveGroup, u )
    endloop
    set loc_tar = null
    set loc = null
    return false
endfunction

//===========================================================================
function InitTrig_walk_speed takes nothing returns nothing
    set gg_trg_walk_speed = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_walk_speed, 0.1 )
    call TriggerAddCondition( gg_trg_walk_speed, Condition(function Trig_walk_speed_Actions) )
endfunction

You can improve it further from here :)
The speed change is configured by changing the *20 and *10 to something else.
I could've made it configurable by a variable, but it would've required vJASS. And I saw that you've made it in WE, so I didn't convert it to vJASS.

What I did:
1) Made the trigger run every 0.1 seconds, instead of every 0.02 seconds
2) Changed the "action" to "condition"
3) Started assigning the values to variables, instead of calling functions to get the values every time you need them.
4) Using First of Group method to do the loop, instead of "For Group", and stopped leaking a unit group every 0.02 seconds (50 groups leaked every second) :D
5) Doing the speed change, based on the unit's default speed, instead of on its "current" speed, thus now it works well with items/abilities, and it doesn't increase/decrease the unit's speed to max/min allowed, instead - it sets it to some value, based on the steepness of the hill.
6) Stopped changing the movespeed of structures, and flying units.
7) Moved the 'if's inside the main function, instead of calling external functions to do the check.
8) Started clearing location leaks.

And that's about all I did :p
 
The changed version still has some old problems along with some new ones:
1) Timer speed should be 0.03 (as I mentioned before)
2) the speed change should be configured via either constant functions or variables rather than hard-coded
3) locations don't need to be set to null since they are already removed
4) one location can be used to get all location heights (use a GetZ function)
5) the polar projection distance should be configurable (see point 2)
6) Add a version number to the thread
7) as from before: Move speed is a risky thing to control via triggers - it's better to use the slow ability as to avoid permanently affecting the movement speed of a unit when other abilities interact with the system (currently the system bugs if you slow a unit and it becomes unaffected by terrain changes)
 
Level 12
Joined
Jan 2, 2016
Messages
973
The changed version still has some old problems along with some new ones:
1) Timer speed should be 0.03 (as I mentioned before)
2) the speed change should be configured via either constant functions or variables rather than hard-coded
3) locations don't need to be set to null since they are already removed
4) one location can be used to get all location heights (use a GetZ function)
5) the polar projection distance should be configurable (see point 2)
6) Add a version number to the thread
7) as from before: Move speed is a risky thing to control via triggers - it's better to use the slow ability as to avoid permanently affecting the movement speed of a unit when other abilities interact with the system (currently the system bugs if you slow a unit and it becomes unaffected by terrain changes)

Since I'm the one who "fixed" his system, I'll be the one to answer that:
1) you may have not noticed, but the timer is set to 0.1, not 0.01 (it used to be 0.02). I don't see a reason for the event to run more often than 10 times per second. Even 5 times per second would be plenty, as this only changes the speed, instead of changing the position of the unit.
2) I could've added a configurations trigger, that's true, but why? It's just 2 values you need to set.
And I didn't want to make this in vJASS, cuz the original version was originally made in WE.
But yeah, I guess it would be easier to configure with variables, than changing 2 values in the trigger itself if you don't know JASS...
3) Okay, that's good to know :p
4) Okay
5) I don't see why should it be configurable, 10 is a reasonable value. What would you set it to?
6) ~This isn't for me~
7) Are you sure you checked the triggers? Now the speed change is done trought the unit's default speed, which is ALWAYS the same, and isn't affected by in-built slows/speed-ups.
Example:
Unit has 320 speed, it's on a hill, so its speed is reduced to 200.
Then a 50% slow is cast on the unit - 100 speed remaining.
Then the unit climbs the hill - its base speed is returned to 320, but since it still has the 50% slow - it will have 160 speed instead.
When the slow ends - the unit will have 320 speed.

I have a movespeed modifying library, and I had to "research" how do speed changes work, so I know what I'm talking about :p

Anyways.. since I only helped with this system, it's up to Dark Lord 25 if he's gonna do anything about it :p
(Tho I could help him again, if he asks me to)
 
Since I'm the one who "fixed" his system, I'll be the one to answer that:
1) you may have not noticed, but the timer is set to 0.1, not 0.01 (it used to be 0.02). I don't see a reason for the event to run more often than 10 times per second. Even 5 times per second would be plenty, as this only changes the speed, instead of changing the position of the unit.
That'd be up to them - though 0.03 remains the standard so I'd still recommend it even if not mandatorily
2) I could've added a configurations trigger, that's true, but why? It's just 2 values you need to set.
And I didn't want to make this in vJASS, cuz the original version was originally made in WE.
But yeah, I guess it would be easier to configure with variables, than changing 2 values in the trigger itself if you don't know JASS...
You can use a constant function and it remains JASS and doesn't use an additional variable - there's little reason to not do this, variable names also make purpose very clear while raw numbers do not
5) I don't see why should it be configurable, 10 is a reasonable value. What would you set it to?
Optional precision, while 10 is a reasonable value people may choose to have a different one, also again clear purpose
7) Are you sure you checked the triggers? Now the speed change is done trought the unit's default speed, which is ALWAYS the same, and isn't affected by in-built slows/speed-ups.
Yes I checked it and I tested it - it does bug as it stands right now, otherwise I wouldn't have mentioned it - it isn't permanently bugged but it is while the unit is slowed
 
Level 12
Joined
Jan 2, 2016
Messages
973
Well, I tested it, and it works fine.
I think the gameplay constants are getting in the way for you (I was getting the same results as you until I changed the min and max movespeeds allowed) :p
Set the minimum movespeed to 10, and the maximum to 500, and try it again.
 
Top