# SystemMoveSpeedX

#### Jesus4Lyf

##### Good Idea™
MoveSpeedX​
Version 1.0.1​

Requirements:
- Jass NewGen
- AIDS
- Key Timers 2

JASS:
//
//                             _____          _____
//        __  __  ___ _    ____\_   \        /    /
//       /  |/  |/ _ \ \  / /  __|    \    /    /
//      / / | / | (_) | \/ /|  __| \    \/    /
//     /_/|__/|_|\___/_\__/_|____|_  \      /
//          / __\  _ \  __|  __|   \ /      \         By Jesus4Lyf
//          \__ \  __/  __|  __| |) |   /\    \
//          \___/_|  |____|____|___/  /    \    \          v 1.0.1
//                             /____/        \____\
//      What is MoveSpeedX?
//     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//          MoveSpeedX allows you to modify a unit&#039;s movement speed, either by a
//          factor of its current speed or by a pure amount. It is possible to disobey
//          the 522 movement speed limit in Warcraft III in this way.
//
//          Please note that setting the speed too high will bug waypoints.
//
//      How to implement?
//     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//          Create a new trigger object called MoveSpeedX, go to &#039;Edit -&gt; Convert to
//          Custom Text&#039;, and replace everything that&#039;s there with this script.
//
//      Functions:
//     ¯¯¯¯¯¯¯¯¯¯¯¯
//          function MSX_AddSpeedPure takes unit whichUnit, real speed returns nothing
//          function MSX_RemoveSpeedPure takes unit whichUnit, real speed returns nothing
//              - Adds or removes a pure amount of speed from the unit.
//
//          function MSX_AddSpeedFactor takes unit whichUnit, real factor returns nothing
//          function MSX_RemoveSpeedFactor takes unit whichUnit, real factor returns nothing
//              - Adds or removes a factor of speed from the unit.
//                For example, to add 10% movement speed to unit u, you would
//              - This stacks incrementally. So +10% +10% = +20%.
//              - This factor does not increase pure speed, only the unit&#039;s
//                speed outside of this system (so it does include buffs).
//
//          function MSX_GetMoveSpeed takes unit whichUnit returns real
//              - Returns the unit&#039;s move speed, inclusive of MoveSpeedX bonuses.
//
//      Thanks:
//     ¯¯¯¯¯¯¯¯¯
//          - Frozenhelfir for the idea.
//
library MSX uses AIDS, KT
globals
//=================================================================
//  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 PERIOD=0.03125
//=================================================================
endglobals
//=================================================================
//  This is a filter that determines whether or not a unit may have
// its move speed modified. Units that pass this filter will be
// indexed by AIDS if they have not already been.
private function VALID_UNITS_FILTER takes unit u returns boolean
return GetUnitAbilityLevel(u,&#039;Aloc&#039;)==0 and not IsUnitType(u,UNIT_TYPE_STRUCTURE)
endfunction
//=================================================================

globals//locals
private unit Unit
private real X
private real Y
private real Xinc
private real Yinc
private real Dist
endglobals
private struct SpeedData extends array
real pureBonus
real factorBonus
private boolean remove
private boolean onTimer
private real x
private real y
private static method AIDS_filter takes unit u returns boolean
return VALID_UNITS_FILTER(u)
endmethod
private method AIDS_onCreate takes nothing returns nothing
set this.pureBonus=0.0
set this.factorBonus=0.0
endmethod
private method AIDS_onDestroy takes nothing returns nothing
set this.remove=true
endmethod
//! runtextmacro AIDS()
private static method periodic takes nothing returns boolean
local thistype this=thistype(KT_GetData())
if this.remove then
set this.onTimer=false
return true
endif
set Unit=this.unit
set X=GetUnitX(Unit)
set Y=GetUnitY(Unit)
if (not IsUnitPaused(Unit)) and GetUnitAbilityLevel(Unit,&#039;BSTN&#039;)==0 and GetUnitAbilityLevel(Unit,&#039;BPSE&#039;)==0 then
if X!=this.x or Y!=this.y then
set Xinc=X-this.x
set Yinc=Y-this.y
if this.factorBonus!=0.0 then
set X=X+Xinc*this.factorBonus
set Y=Y+Yinc*this.factorBonus
endif
if this.pureBonus!=0.0 then
set Dist=SquareRoot(Xinc*Xinc+Yinc*Yinc)
set X=X+Xinc/Dist*this.pureBonus
set Y=Y+Yinc/Dist*this.pureBonus
endif
call SetUnitX(Unit,X)
call SetUnitY(Unit,Y)
endif
endif
set this.x=X
set this.y=Y
return false
endmethod
method checkTimer takes nothing returns nothing
if not this.onTimer then
set this.onTimer=true
set this.remove=false
set this.x=GetUnitX(this.unit)
set this.y=GetUnitY(this.unit)
endif
if this.pureBonus==0.0 and this.factorBonus==0.0 then
set this.remove=true
endif
endmethod
endstruct
public function AddSpeedPure takes unit u, real speed returns nothing
local SpeedData d=SpeedData<u>
set d.pureBonus=d.pureBonus+speed*PERIOD
call d.checkTimer()
endfunction
public function RemoveSpeedPure takes unit u, real speed returns nothing
local SpeedData d=SpeedData<u>
set d.pureBonus=d.pureBonus-speed*PERIOD
call d.checkTimer()
endfunction
public function AddSpeedFactor takes unit u, real factor returns nothing
local SpeedData d=SpeedData<u>
set d.factorBonus=d.factorBonus+factor
call d.checkTimer()
endfunction
public function RemoveSpeedFactor takes unit u, real factor returns nothing
local SpeedData d=SpeedData<u>
set d.factorBonus=d.factorBonus-factor
call d.checkTimer()
endfunction
public function GetMoveSpeed takes unit u returns real
local SpeedData d=SpeedData<u>
return GetUnitMoveSpeed(u)*(1.0+d.factorBonus)+d.pureBonus
endfunction
endlibrary
</u></u></u></u></u>
[/SPOILER]
This system is for modifying a unit's move speed, since the natives are fail and buffs are impractical, and the 522 sometimes just isn't what we want.

It's worth reading the comments about waypoints bugging and how to fix it. Refer to the "PERIOD" constant at the top of the code to see them (minor issue, easily solved). Basically, if you hack up a unit's movement speed too high it will miss its WC3 waypoints. You can reduce the PERIOD on the system to counter this.

Example use (20 times a second increases move speed for all units on map by 1):
JASS:
scope MoveSpeedXExample initializer OnInit
globals
private group GROUP=CreateGroup()
endglobals
private function ForAll takes nothing returns boolean
return false
endfunction
private function Periodic takes nothing returns nothing
call GroupEnumUnitsInRect(GROUP,bj_mapInitialPlayableArea,Filter(function ForAll))
endfunction
private function OnInit takes nothing returns nothing
call TimerStart(CreateTimer(),0.05,true,function Periodic)
endfunction
endscope

- Version 1.0.1: Found a potential efficiency gain in moving the periodic function.
- Version 1.0.0: Release.

#### Attachments

• MoveSpeedX.w3x
41.1 KB · Views: 926
Since i don't know JASS i will ask you just 1 question...
When you increase movespeed by this system and while my unit has increased movespeed a unit to cast Bloodlust on my unit that will increase my unit's ms. After X time will I be able to return the ms of my unit to normal be4 the increasement has been placed?

Demo map?

When you increase movespeed by this system and while my unit has increased movespeed a unit to cast Bloodlust on my unit that will increase my unit's ms. After X time will I be able to return the ms of my unit to normal be4 the increasement has been placed?
Yes. It works like this:

+/* buffs.
* MSX factor bonus.
+ MSX pure bonus.

So basically... this doesn't screw anything up. It doesn't directly modify move speed, it keeps itself independently. I know what you're saying, and this was basically made in part to solve that problem.

When both the MSX gain is revoked (pure or factor) and the bloodlust gain is removed, regardless the order of removal, the unit will return to the move speed it had before either was applied.

>Demo map?
Demo map up. It's just the example.

Well I won't use it because it requires NewGen which is very bugged. Thats why i don't use it. Just good job for that system. I haven't seen anything like it till now

UNFORTUNATE! :thup:

NewGen isn't bugged for me at all.

Because you use SetUnitX/Y instead of SetUnitPosition, the collision of the unit is ignored, the unit could be stucked beetween trees for example.
I don't think there is a good way to change the unit speed more than 512.
You can't be as good as war3 engine with simply jass2.

Watch me.

Really though, try the demo map. Units have a collision size, as long as you don't move more than it at once, can't get stuck. Or so I think. I dunno, the demo map works, doesn't it?

It's a guess based on my knowledge but i didn't read the code so far, so maybe i'm wrong, i will try it tomorrow.

If I remember correclty, the game indeed does some pathability checking when you use SetUnitX&Y for moving units that are currently walking.

My guess is that units walking triggers those pathability thingies, because sometimes when you move unit to some point where it should not be, it pops out when you give it a move order.

GOOD POINT!

Yeah, which means as long as you don't go TOO far in one skip, you're fine.

It's a case of lower the period if you want to use really fast move speeds...

Noticed that if you set the pheonix's move speed to something past 522, wait for it to die and revive, attempting to order it to move freezes wc3 for me.

Edit: Bleh, nevermind. I coded it wrong.

Christ, Jesus. This is brilliant. Saves me the hassle of coding a past-522 movement speed spell myself. <3

I think this is awesome.
I had great fun testing the demo map.

This system should be implemented on a larger map (perhaps one that is already completed), just to see how it works in a real situation.
-I reckon the footman would fly through any group of enemy units that would otherwise block him.

+rep
:thup:

I noticed some snags around 1500ms with a .00125 period. Unhappy with this I decided to boost KT2 from 800 executions per second up to 80000 executions per second so I could use a .0000125 period. Not really sure how stable it is, or if timers can even go that low, but it was fun . I tried using a movespeed of about 20,000-60,000 movespeed. However the unit just started doing the hokey pokey and it turned itself around. Went really fast when it wasn't doing that though.

I actually found I could fix it by making KT2 very unstable though /votes for J4L to ficks this so it doesn't have to require a hacked KT2 or let me try

JASS:
//      Thanks:
//     ¯¯¯¯¯¯¯¯¯
//          - Frozenhelfir stealing his system.

Fixed :|

Unhappy with this I decided to boost KT2 from 800 executions per second up to 80000 executions per second so I could use a .0000125 period. Not really sure how stable it is, or if timers can even go that low, but it was fun . I tried using a movespeed of about 20,000-60,000 movespeed. However the unit just started doing the hokey pokey and it turned itself around. Went really fast when it wasn't doing that though.
See, this is why we can't have nice things...

Sounds fun, but yea you did make KT2 unstable. Nice work all the same (now go back to using 800 execs/sec, or maybe 8,000 if you must as I originally instructed you ). By the way, that value should be called the Resolution, not executions per second, but I suppose it's much the same thing.

Question, did it lag?
And question #2, do you need that high a move speed?

See, this is why we can't have nice things...

Sounds fun, but yea you did make KT2 unstable. Nice work all the same (now go back to using 800 execs/sec, or maybe 8,000 if you must as I originally instructed you ). By the way, that value should be called the Resolution, not executions per second, but I suppose it's much the same thing.

Question, did it lag?
And question #2, do you need that high a move speed?

Question 1: Nope, but it would probably lag other people
Question 2: Yes, my endgame items don't fuck around.

I'll recode a version specially for stupidly high move speeds perhaps.

Will this still attempt to move units when they are under the effect of a movement-type spell, such as a dash or blink or something? If so then that may be a little bit of a problem. If this were in a map I was making I would just add an "invisible" ability to a unit every time it uses a spell like that, and just check if it had that ability before adding the extra movement. However I'm not sure if that is the best possible way to do things for a public system.

But besides that, I see this as a way of completely replacing the wc3 movement speed system, which is awesome, and in high demand recently. So nice work. :thup:

I can probably remove the speed bonus while a spell is casting. Currently, it doesn't apply while paused or stunned.

Edit: For Frozenhelfir...
JASS:
//
//                             _____          _____
//        __  __  ___ _    ____\_   \        /    /
//       /  |/  |/ _ \ \  / /  __|    \    /    /
//      / / | / | (_) | \/ /|  __| \    \/    /
//     /_/|__/|_|\___/_\__/_|____|_  \      /
//          / __\  _ \  __|  __|   \ /      \         By Jesus4Lyf
//          \__ \  __/  __|  __| |) |   /\    \
//          \___/_|  |____|____|___/  /    \    \          v 1.0.1 (UNOFFICIAL RELEASE)
//                             /____/        \____\
//      What is MoveSpeedX?
//     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//          MoveSpeedX allows you to modify a unit&#039;s movement speed, either by a
//          factor of its current speed or by a pure amount. It is possible to disobey
//          the 522 movement speed limit in Warcraft III in this way.
//
//          Please note that setting the speed too high will bug waypoints.
//
//      How to implement?
//     ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//          Create a new trigger object called MoveSpeedX, go to &#039;Edit -&gt; Convert to
//          Custom Text&#039;, and replace everything that&#039;s there with this script.
//
//      Functions:
//     ¯¯¯¯¯¯¯¯¯¯¯¯
//          function MSX_AddSpeedPure takes unit whichUnit, real speed returns nothing
//          function MSX_RemoveSpeedPure takes unit whichUnit, real speed returns nothing
//              - Adds or removes a pure amount of speed from the unit.
//
//          function MSX_AddSpeedFactor takes unit whichUnit, real factor returns nothing
//          function MSX_RemoveSpeedFactor takes unit whichUnit, real factor returns nothing
//              - Adds or removes a factor of speed from the unit.
//                For example, to add 10% movement speed to unit u, you would
//              - This stacks incrementally. So +10% +10% = +20%.
//              - This factor does not increase pure speed, only the unit&#039;s
//                speed outside of this system (so it does include buffs).
//
//          function MSX_GetMoveSpeed takes unit whichUnit returns real
//              - Returns the unit&#039;s move speed, inclusive of MoveSpeedX bonuses.
//
//      Thanks:
//     ¯¯¯¯¯¯¯¯¯
//          - Frozenhelfir for the idea.
//
library MSX uses AIDS, KT
globals
//=================================================================
//  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. There is no lowest period
// in this version.
private constant real PERIOD=0.001
//=================================================================
endglobals
//=================================================================
//  This is a filter that determines whether or not a unit may have
// its move speed modified. Units that pass this filter will be
// indexed by AIDS if they have not already been.
private function VALID_UNITS_FILTER takes unit u returns boolean
return GetUnitAbilityLevel(u,&#039;Aloc&#039;)==0 and not IsUnitType(u,UNIT_TYPE_STRUCTURE)
endfunction
//=================================================================

globals//locals
private unit Unit
private real X
private real Y
private real Xinc
private real Yinc
private real Dist
endglobals
private struct SpeedData extends array
real pureBonus
real factorBonus
private boolean remove
private boolean onTimer
private real x
private real y
private static method AIDS_filter takes unit u returns boolean
return VALID_UNITS_FILTER(u)
endmethod
private method AIDS_onCreate takes nothing returns nothing
set this.pureBonus=0.0
set this.factorBonus=0.0
endmethod
private method AIDS_onDestroy takes nothing returns nothing
set this.remove=true
endmethod
//! runtextmacro AIDS()
private method periodic takes nothing returns boolean
if this.remove then
set this.onTimer=false
return true
endif
set Unit=this.unit
set X=GetUnitX(Unit)
set Y=GetUnitY(Unit)
if (not IsUnitPaused(Unit)) and GetUnitAbilityLevel(Unit,&#039;BSTN&#039;)==0 and GetUnitAbilityLevel(Unit,&#039;BPSE&#039;)==0 then
if X!=this.x or Y!=this.y then
set Xinc=X-this.x
set Yinc=Y-this.y
if this.factorBonus!=0.0 then
set X=X+Xinc*this.factorBonus
set Y=Y+Yinc*this.factorBonus
endif
if this.pureBonus!=0.0 then
set Dist=SquareRoot(Xinc*Xinc+Yinc*Yinc)
set X=X+Xinc/Dist*this.pureBonus*PERIOD
set Y=Y+Yinc/Dist*this.pureBonus*PERIOD
endif
call SetUnitX(Unit,X)
call SetUnitY(Unit,Y)
endif
endif
set this.x=X
set this.y=Y
return false
endmethod
// T32 implementation.
private thistype next
private thistype prev
private static method PeriodicLoop takes nothing returns nothing
local thistype this=thistype(0).next
loop
exitwhen this==0
if this.periodic() then
// This is some real magic.
set this.prev.next=this.next
set this.next.prev=this.prev
// This will even work for the starting element.
endif
set this=this.next
endloop
endmethod
method startPeriodic takes nothing returns nothing
set thistype(0).next.prev=this
set this.next=thistype(0).next
set thistype(0).next=this
set this.prev=thistype(0)
endmethod
private static method AIDS_onInit takes nothing returns nothing
call TimerStart(CreateTimer(),PERIOD,true,function thistype.PeriodicLoop)
endmethod
// End T32 implementation.
method checkTimer takes nothing returns nothing
if not this.onTimer then
call this.startPeriodic()
set this.onTimer=true
set this.remove=false
set this.x=GetUnitX(this.unit)
set this.y=GetUnitY(this.unit)
endif
if this.pureBonus==0.0 and this.factorBonus==0.0 then
set this.remove=true
endif
endmethod
endstruct
public function AddSpeedPure takes unit u, real speed returns nothing
local SpeedData d=SpeedData<u>
set d.pureBonus=d.pureBonus+speed
call d.checkTimer()
endfunction
public function RemoveSpeedPure takes unit u, real speed returns nothing
local SpeedData d=SpeedData<u>
set d.pureBonus=d.pureBonus-speed
call d.checkTimer()
endfunction
public function AddSpeedFactor takes unit u, real factor returns nothing
local SpeedData d=SpeedData<u>
set d.factorBonus=d.factorBonus+factor
call d.checkTimer()
endfunction
public function RemoveSpeedFactor takes unit u, real factor returns nothing
local SpeedData d=SpeedData<u>
set d.factorBonus=d.factorBonus-factor
call d.checkTimer()
endfunction
public function GetMoveSpeed takes unit u returns real
local SpeedData d=SpeedData<u>
return GetUnitMoveSpeed(u)*(1.0+d.factorBonus)+d.pureBonus
endfunction
endlibrary
</u></u></u></u></u>

Try this. Just wrote it, unsure if it compiles.

General chit-chat
Help Users
• No one is chatting at the moment.
• The Helper:
News portal has been retired. Main page of site goes to Headline News forum now
• The Helper:
I am working on getting access to the old news portal under a different URL for those that would rather use that for news before we get a different news view.
• Ghan:
Easily done
+1
• The Helper:
https://www.thehelper.net/pages/news/ is a link to the old news portal - i will integrate it into the interface somewhere when i figure it out
• Ghan:
Need to try something
• Ghan:
Hopefully this won't cause problems.
• Ghan:
Hmm
• Ghan:
I have converted the Headline News forum to an Article type forum. It will now show the top 20 threads with more detail of each thread.
• Ghan:
See how we like that.
• The Helper:
I do not see a way to go past the 1st page of posts on the forum though
• The Helper:
It is OK though for the main page to open up on the forum in the view it was before. As long as the portal has its own URL so it can be viewed that way I do want to try it as a regular forum view for a while
• Ghan:
Yeah I'm not sure what the deal is with the pagination.
• Ghan:
It SHOULD be there so I think it might just be an artifact of having an older style.
• Ghan:
I switched it to a "Standard" article forum. This will show the thread list like normal, but the threads themselves will have the first post set up above the rest of the "comments"
• The Helper:
I don't really get that article forum but I think it is because I have never really seen it used on a multi post thread
• Ghan:
RpNation makes more use of it right now as an example: https://www.rpnation.com/news/
• The Helper:
• The Helper:
What do you think Tom?
• tom_mai78101:
I will have to get used to this.
• tom_mai78101:
The latest news feed looks good
• The Helper:
I would like to see it again like Ghan had it the first time with pagination though - without the pagination that view will not work but with pagination it just might...
• The Helper:
This drink recipe I have had more than a few times back in the day! Mind Eraser https://www.thehelper.net/threads/cocktail-mind-eraser.194720/

### Members online

No members online now.