- Joined
- Oct 18, 2007
- Messages
- 930
Ok i decided to make a small, fast and efficient knockback :3
The reason im doing this is because the one used mostely here in hive is Silvenon's knockback. It needed some optimization and improvements, so i took the idea with the call and started making the code( from scratch ).
The end result was this, enjoy.
I dont need credits for making this, i did this only for the purpose of having a good knockback sys.
The reason im doing this is because the one used mostely here in hive is Silvenon's knockback. It needed some optimization and improvements, so i took the idea with the call and started making the code( from scratch ).
The end result was this, enjoy.
JASS:
// ||-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-||
// || ||
// || Knockback System v1.2b ||
// || By Dynasti ||
// || ||
// ||-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-||
// || Members of the Struct Data ||
// ||-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-||
// || ||
// || u - The unit that is being draged. ||
// || v - The Velocity the unit is traveling in ||
// || vd - The Velocity decreasement ||
// || cos - The Cos value for the angle. ||
// || sin - The Sin value for the angle. ||
// || r - A real value used to kill destructables within a desired range ||
// || s - A String used to call an effect. ||
// || e - Effect that is used for a trail effect. ||
// || i - Integer used for counting the effect spawning. ||
// || er - Integer used to tell the system when to create the effect, read below to understand more of it.||
// || p - A boolean used to determine if you want the unit to be paused or not while beign knocked ||
// || nX - A Static value used for handling the unit ' u 's X. ||
// || nY - A Static value used for handling the unit ' u 's Y. ||
// || R - A Static rect used to kill nearby destructables ||
// || ||
// ||-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-||
// || Global Memebers ||
// ||-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-||
// || ||
// || Interval(0.035) - A constant value used for the looping function, lower intervals = Higher FPS. ||
// || EffectRandom(4) - A constant value used for creating the trail effects. Higher numbers will result in ||
// || higher randomness of effects.(This does only apply if you want a random effectspawn ||
// || Index - An integer array used for an indexing system. ||
// || Total - An integer used for an indexing system. ||
// || Tim - A Timer used for the looping action. ||
// || MAX_X - A Real used for checking if the knocked unit gets off bounds. ||
// || MAX_Y - A Real used for checking if the knocked unit gets off bounds. ||
// || MIN_X - A Real used for checking if the knocked unit gets off bounds. ||
// || MIN_Y - A Real used for checking if the knocked unit gets off bounds. ||
// || ||
// ||-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-||
// || Tips'n tricks ||
// ||-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-||
// || ||
// || 1. - If you dont want any trees/destructables to be destroyed in it's path then call the radius with 0 ||
// || ||
// || 2. - On the call you need one integer called EffectInt and 2 strings called Effect and EffectAttach, If ||
// || want a looping effect( an effect that is spawned at each interval ) then you do the call with the ||
// || EffectInt being '1' and the Effect being "YourEffect" and dont forget to set the EffectAttach to "".||
// || If you want a constant effect that stays on the unit untill the end of the knockback, do the call ||
// || with the EffectInt being '2' and the Effect being "YourEffect" and for the EffectAttach being ||
// || "YourEffectAttach". ||
// || If you want both at the same time you call with EffectInt being '3'. ||
// || ||
// || 3. - As i have experienced there are times when you need to pause the unit while knocking it and ||
// || -sometimes not. That is why i have added a boolean to the call, called Pause. ||
// || It is really simple, just set it to false if you dont want the knocked unit to be paused and false ||
// || for not. ||
// || ||
// ||-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-||
// || The Call ||
// ||-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-||
// || ||
// || KnockbackEx function: ||
// || - unit Unit : The unit being knocked. ||
// || - real Distance : The distance the knoced unit is going to travlel. ||
// || - real RadAngle : The angle the knocked unit is being knocked( In Radians ). ||
// || - real Time : The time it takes to knock the unit. ||
// || - real Radius : The radius to kill nearby destructables( for example trees ) on collision. ||
// || - boolean Pause : If you want the knocked unit to be paused while knocked then call it with true. ||
// || - integer EffectSpawn : This determines if you want the effect spawning to be random or not. ||
// || Set it to ' 0 ' for random spawning of effect. Else if it is greater than ||
// || ' 0 ' then the effect will be created every "EffectSpawn" interval. ||
// || Lets say it is set to ' 3 ', then the effect will be created every 3rd move. ||
// || - integer EffectInt : The effect integer( read above for more info ). ||
// || - string Effect : The path of the effect( read above for more info ). ||
// || - string EffectAttach : The path for the attaching of the Effect( read above for more info ). ||
// || ||
// || Knockback function( Good for less complicated knockbacks): ||
// || - unit Unit : The unit being knocked. ||
// || - real Distance : The distance the knoced unit is going to travlel. ||
// || - real RadAngle : The angle the knocked unit is being knocked( In Radians ). ||
// || - real Time : The time it takes to knock the unit. ||
// || - boolean Pause : If you want the knocked unit to be paused while knocked then call it with true. ||
// ||-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-||
library Knockback initializer Init
globals
private constant real Interval = 0.035
private constant integer EffectRandom = 4 // 4 is 25% chance of the effect spawning( Looping effect )
private integer array Index
private integer Total = 0
private timer Tim = CreateTimer()
private real MAX_X
private real MAX_Y
private real MIN_X
private real MIN_Y
private boolexpr FilterDestructables
endglobals
private function DestructableFilter takes nothing returns boolean
local destructable d = GetFilterDestructable()
if GetWidgetLife(d) > .405 and not IsDestructableInvulnerable(d) then
call KillDestructable(d)
endif
set d = null
return false
endfunction
private keyword Data // If not here then the loop cannot be put over the struct( Why is because the struct needs the function for the timer )
private function Loop takes nothing returns nothing
local Data dat
local integer i=0
loop
exitwhen i >= Total
set dat = Index[i]
if dat.v <= 0 then
if dat.s != "" and dat.s != null then
if dat.e != null then
call DestroyEffect(dat.e)
set dat.e = null
endif
set dat.s = null
elseif dat.e != null then
call DestroyEffect(dat.e)
set dat.e = null
endif
if dat.p then
call PauseUnit(dat.u, false)
set dat.p = false
endif
set dat.u = null
call dat.destroy()
set Total = Total - 1
set Index[i] = Index[Total]
set i = i - 1
else
set dat.nX = GetUnitX(dat.u) + dat.v * dat.cos
set dat.nY = GetUnitY(dat.u) + dat.v * dat.sin
if dat.nX < MAX_X and dat.nY < MAX_Y and dat.nX > MIN_X and dat.nY > MIN_Y and GetWidgetLife(dat.u) > .405 then
call SetUnitX(dat.u, dat.nX)
call SetUnitY(dat.u, dat.nY)
if dat.r > 0 then // If the member ' r ' is greater than 0 it will destroy destructables in a desired range
set dat.R = Rect(dat.nX - dat.r, dat.nY - dat.r, dat.nX + dat.r, dat.nY + dat.r)
call EnumDestructablesInRect(dat.R, FilterDestructables, null)
endif
if dat.s != "" and dat.s != null then
if dat.er == 0 then
if GetRandomInt(1, EffectRandom) == EffectRandom then // Here is where the global random integer is used
call DestroyEffect(AddSpecialEffect(dat.s, dat.nX, dat.nY))
endif
elseif dat.i >= dat.er then
call DestroyEffect(AddSpecialEffect(dat.s, dat.nX, dat.nY))
set dat.i = 1
else
set dat.i = dat.i + 1
endif
endif
set dat.v = dat.v - dat.vd
else
set dat.v = 0
endif
endif
set i = i + 1
endloop
if Total == 0 then
call PauseTimer(Tim)
endif
endfunction
private struct Data
unit u
real v = 0
real vd
real cos
real sin
real r = 0
string s
effect e
integer i = 1
integer er = 0
boolean p
static real nX
static real nY
static rect R = Rect(0,0,0,0)
static method Start takes unit u, real d, real a, integer t, real r, boolean p, integer er, integer i, string s, string s2 returns nothing
local Data dat = Data.allocate()
set dat.u = u
set dat.er = er
set dat.v = 2*d/(t+1)
set dat.vd = dat.v/t
set dat.cos = Cos(a)
set dat.sin = Sin(a)
if s != "" and s != null then
if i == 1 then
set dat.s = s
elseif i == 2 then
set dat.e = AddSpecialEffectTarget(s, u, s2)
elseif i == 3 then
set dat.s = s
set dat.e = AddSpecialEffectTarget(s, u, s2)
endif
endif
if p then
call PauseUnit(u, true)
set dat.p = p
endif
if r > 0 then
set dat.r = r
endif
if Total == 0 then
call TimerStart(Tim, Interval, true, function Loop)
endif
set Index[Total] = dat
set Total = Total + 1
endmethod
endstruct
function KnockbackEx takes unit Unit, real Distance, real RadAngle, real Time, real Radius, boolean Pause, integer EffectSpawn, integer EffectInt, string Effect, string EffectAttach returns nothing
call Data.Start(Unit, Distance, RadAngle, R2I(Time/Interval), Radius, Pause, EffectSpawn, EffectInt, Effect, EffectAttach)
endfunction
function Knockback takes unit Unit, real Distance, real RadAngle, real Time, boolean Pause returns nothing
call Data.Start(Unit, Distance, RadAngle, R2I(Time/Interval), 0, Pause, 0, 0, "", "")
endfunction
private function Init takes nothing returns nothing
set MAX_X = GetRectMaxX(bj_mapInitialPlayableArea)
set MAX_Y = GetRectMaxY(bj_mapInitialPlayableArea)
set MIN_X = GetRectMinX(bj_mapInitialPlayableArea)
set MIN_Y = GetRectMinY(bj_mapInitialPlayableArea)
set FilterDestructables = Condition(function DestructableFilter)
endfunction
endlibrary
I dont need credits for making this, i did this only for the purpose of having a good knockback sys.
Last edited: