Jesus4Lyf
Good Idea™
- Reaction score
- 397
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'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 'Edit -> Convert to
// Custom Text', and replace everything that'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
// call MS_AddSpeedFactor(u, 0.1).
// - This stacks incrementally. So +10% +10% = +20%.
// - This factor does not increase pure speed, only the unit's
// speed outside of this system (so it does include buffs).
//
// function MSX_GetMoveSpeed takes unit whichUnit returns real
// - Returns the unit'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,'Aloc')==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,'BSTN')==0 and GetUnitAbilityLevel(Unit,'BPSE')==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
call KT_Add(function thistype.periodic,this,PERIOD)
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>
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
call MSX_AddSpeedPure(GetFilterUnit(),1.0)
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
Updates:
- Version 1.0.1: Found a potential efficiency gain in moving the periodic function.
- Version 1.0.0: Release.
Attachments
-
41.1 KB Views: 877