|
 |   |  |  |
JASS Functions Approved JASS functions will be located here.
Remember to submit your own resources to the submission forum. |
 |
|
06-17-2007, 08:49 PM
|
#1 (permalink)
|
BBoy Silv
Join Date: Nov 2006
Posts: 866
|
Knockback Unit
Knockback(Ex)
Credits to:
Fixes:- renamed UnitKnockback/UnitKnockback_Execute into Knockback/Knockback_Execute (actually made Execute public)
- removed UnitKnockbackWithLightning, found out it's useless
- optimized the performance, it only uses Jass NewGen Pack now
- added KnockbackEx function
- changed the parameters a bit, added new feature(s)
- uses initializer Init_Knockback, so no map initialization trigger is required anymore
More fixes:- this version actually works
- doesn't use the stupid CheckPathability function anymore
- has a different system instead
- added instructions for GUI users
- removed the CSSafety requirement
- renamed Knockback_Init function
- added a new radius feature (look in the parameter explanation)
- removed the Data returnage, PP was right, it can only screw things up
- modified the code, so now it uses create and onDestroy methods, I hope it's more readable now
library Knockback initializer Init // **************************************************************************// ** **// ** Knockback(Ex) **// ** ————————————— **// ** **// ** A function made for efficient knockbacking **// ** **// ** By: Silvenon **// ** **// **************************************************************************//=======================================////Credits to PitzerMike for this function////=======================================//globals private constant integer DUMMY_ID = 'h000'endglobalsprivate function TreeFilter takes nothing returns boolean local destructable d = GetFilterDestructable () local boolean i = IsDestructableInvulnerable (d ) local unit u = CreateUnit (Player (PLAYER_NEUTRAL_PASSIVE ), DUMMY_ID, GetWidgetX (d ), GetWidgetY (d ), 0 ) local boolean result = false call UnitAddAbility (u, 'Ahrl') if i then call SetDestructableInvulnerable (d, false) endif set result = IssueTargetOrder (u, "harvest", d ) call RemoveUnit (u ) if i then call SetDestructableInvulnerable (d, true) endif set u = null set d = null return result endfunction//===========================================================================globals private timer Tim = CreateTimer () private integer Total = 0 private boolexpr Cond = null private integer array Ar private boolean array BoolAr private real MAX_X private real MAX_Y private real MIN_X private real MIN_Y endglobalsprivate constant function Interval takes nothing returns real return 0.04 endfunctionprivate function KillTree takes nothing returns nothing if BoolAr [0 ] then call KillDestructable (GetEnumDestructable ()) else set BoolAr [1 ] = true endifendfunctionpublic struct Data unit u real d1 real d2 real sin real cos real r string s = "" effect e = null static method create takes unit u, integer q, real d, real a, real r, integer t, string s, string p returns Data local Data dat = Data.allocate () set dat.u = u set dat.d1 = 2 * d / (q + 1 ) set dat.d2 = dat.d1 / q set dat.sin = Sin (a ) set dat.cos = Cos (a ) set dat.r = r if s != "" and s != null then if t == 2 then if p != "" and p != null then set dat.e = AddSpecialEffectTarget (s, u, p ) else set dat.e = AddSpecialEffectTarget (s, u, "chest") endif elseif t == 1 then set dat.s = s endif endif call SetUnitPosition (u, GetUnitX (u ), GetUnitY (u )) call PauseUnit (u, true) if Total == 0 then call TimerStart (Tim, Interval (), true, function Data.Execute ) endif set Total = Total + 1 set Ar [Total - 1 ] = dat return dat endmethod static method Execute takes nothing returns nothing local Data dat local integer i = 0 local real x local real y local rect r local real rad loop exitwhen i >= Total set dat = Ar [i ] if dat.s != "" and dat.s != null then set x = GetUnitX (dat.u ) set y = GetUnitY (dat.u ) call DestroyEffect (AddSpecialEffect (dat.s, x, y )) set x = x + dat.d1 * dat.cos set y = y + dat.d1 * dat.sin else set x = GetUnitX (dat.u ) + dat.d1 * dat.cos set y = GetUnitY (dat.u ) + dat.d1 * dat.sin endif if dat.r != 0 then set BoolAr [0 ] = dat.r > 0 set rad = dat.r if not BoolAr [0 ] then set rad = rad * (-1 ) endif set r = Rect (x - rad, y - rad, x + rad, y + rad ) call EnumDestructablesInRect (r, Cond, function KillTree ) call RemoveRect (r ) set r = null endif if (x < MAX_X and y < MAX_Y and x > MIN_X and y > MIN_Y ) and not BoolAr [1 ] then call SetUnitX (dat.u, x ) call SetUnitY (dat.u, y ) endif set dat.d1 = dat.d1 - dat.d2 if dat.d1 <= 0 or (x > MAX_X or y > MAX_Y or x < MIN_X or y < MIN_Y ) or BoolAr [1 ] then set Ar [i ] = Ar [Total - 1 ] set Total = Total - 1 call dat.destroy () endif set i = i + 1 endloop if Total == 0 then call PauseTimer (Tim ) endif endmethod method onDestroy takes nothing returns nothing if .e != null then call DestroyEffect (.e ) endif call PauseUnit (.u, false) set BoolAr [0 ] = false set BoolAr [1 ] = false endmethodendstructfunction KnockbackEx takes unit u, real d, real a, real w, real r, integer t, string s, string p returns nothing call Data.create (u, R2I (w / Interval ()), d, a, r, t, s, p )endfunctionfunction Knockback takes unit u, real d, real a, real w returns nothing call Data.create (u, R2I (w / Interval ()), d, a, 0, 0, "", "")endfunctionprivate function Init takes nothing returns nothing set Cond = Filter (function TreeFilter ) set BoolAr [0 ] = false set BoolAr [1 ] = false set MAX_X = GetRectMaxX (bj_mapInitialPlayableArea ) - 64 set MAX_Y = GetRectMaxY (bj_mapInitialPlayableArea ) - 64 set MIN_X = GetRectMinX (bj_mapInitialPlayableArea ) + 64 set MIN_Y = GetRectMinY (bj_mapInitialPlayableArea ) + 64 endfunctionendlibrary
Are you getting tired of writing a knockback code every single time when you want to knockback something? If the answer is yes, then this is what you need. This function knockbacks a unit according to the parameters below: - unit u = the unit being knockbacked
- real d = the distance the unit is knockbacked to
- real a = the angle (direction of the knockback) in RADIANS
- real w = the duration of the knockback
- real r = the radius of tree destroying, but there's a new trick: if you put a negative number as the radius, the unit will stop knockbacking when it gets in that range of a tree and if you put a positive value, the unit will destroy trees when it gets in that range of a tree (if you don't want any of those, just put 0)
- integer t = type 0 means no effect (both s and p should be ""), type 1 means periodic effect (meaning you should put "" as the attachment point, parameter p), type 2 means a special effect attached on the unit and destroyed when the knockback is finished (this is where you use parameter p)
- string s = the path to the special effect you want to use (periodic), that effect will be destroyed immediatelly (you can put "" if you don't want a special effect)
- string p = used for type 2, it's the attachment point of the effect, "chest" is default (so if you put "", it will be "chest")
Instructions:
Create a dummy unit according to one of these two tutorials: 1, 2 (I suggest the second one). You MUST change the DUMMY_ID constant integer to that unit's id.
You can deprivate any function from the library you want to use, I just made it like that so it doesn't interfere with other stuff. If you don't want any special effects and tree destroying, you can use Knockback function that takes only the first 4 parameters.
If you by any chance have angle in degrees and want to use it for this function, when calling the function just multiply that angle with bj_DEGTORAD, example:
call Knockback(u, d, a * bj_DEGTORAD, w)
You can change the interval of execution in the Knockback_Interval constant (default is 0.035).
Example of usage:
JASS: function Test takes nothing returns nothing local unit c = GetTriggerUnit () local unit t = GetSpellTargetUnit () local real x1 = GetUnitX (c ) local real y1 = GetUnitY (c ) local real x2 = GetUnitX (t ) local real y2 = GetUnitY (t ) local real dist = 500 local real angle = Atan2 (y2 - y1, x2 - x1 ) local real dur = 2 call Knockback (t, dist, angle, dur ) set c = null set t = nullendfunction
GUI:  Test  Events   Unit - A unit starts the effect of an ability  Conditions   (Ability being cast) Equal to <Some Spell>  Actions
On the same principle you use the KnockbackEx function
Requires: Jass NewGen Pack
Find more about the function in my Knockback tutorial
Please report any errors.
Last edited by Silvenon; 07-28-2008 at 10:22 AM..
Reason: Fixed a typo in the readme that led to confusion
|
|
|
06-17-2007, 08:56 PM
|
#2 (permalink)
|
Shifting voidwalker!
Join Date: Nov 2004
Posts: 396
|
If you are using CSCache, how come that you don't use tables instead? they are faster, and else i don't really see any reason not to use handle vars, as people here are more familiar with them.
I suggest you to use constant functions, as it is faster than attaching stuff and much easier to change.
|
|
|
06-17-2007, 10:41 PM
|
#3 (permalink)
|
BBoy Silv
Join Date: Nov 2006
Posts: 866
|
Please explain what do you mean by using constants. I changed it into handle vars. Btw I never learned using tables because I switched to structs after handle vars.
|
|
|
06-18-2007, 03:29 AM
|
#4 (permalink)
|
iRawr
Join Date: Dec 2005
Posts: 8,349
|
What he means by using Constants is instead of doing something like this
function myFunc takes paramArgs returns type local integer imaconstant = 5 call DoSomething ( imaconstant )endfunction
do something like
constant function imaconstant takes nothing returns integer return 5 endfunctionfunction myFunc takes paramArgs returns type call DoSomething ( imaconstant () )endfunction
Tools like Vexorian's Map Optimizer inline the call anyways, and it makes the function more readable+easier to change, as you know by looking at the top what alot of the things do (if you name the functions well)
Anyways, you should probably also remove the damage option from the function. It's clogging up the parameters with stuff that will often be left unused, and is much less flexible than UnitDamageTarget.
It's probably better to either
A) rename that UnitKnockbackEx and have a copy without the damage feature
B) remove it altogether
In other news, I'll approve this if those're fixed. (well, the second one, the first one doesn't matter that much)
|
|
|
06-18-2007, 09:55 AM
|
#5 (permalink)
|
BBoy Silv
Join Date: Nov 2006
Posts: 866
|
*Removed damage options. Heh my original function didn't have damage options, but I thought people would want that, but now I realize it was a mistake (I thought damage over time was better).
I know what are constants and how to use them, but can you please explain how would i use constants in my knockback functions?? What values would constants return? How would it then allow different knocbacks? Please give more details, as I would love to improve it.
|
|
|
06-18-2007, 12:52 PM
|
#6 (permalink)
|
Shifting voidwalker!
Join Date: Nov 2004
Posts: 396
|
constant function Knockback_Interval takes nothing returns real return 0.035 endfunction//Instead of attaching the stuff just do like this: call TimerStart (t, Knockback_Interval (), true, function UnitKnockback_Execute )
Interval is VERY important to be changeable as a constant.
|
|
|
06-18-2007, 12:54 PM
|
#7 (permalink)
|
iRawr
Join Date: Dec 2005
Posts: 8,349
|
~approved, now let's see if I can find out how~
|
|
|
06-18-2007, 06:14 PM
|
#8 (permalink)
|
BBoy Silv
Join Date: Nov 2006
Posts: 866
|
Then you mean constant only for the interval then? Why is it so important to be able to change it? Btw I already told how to do it, but ok......*fixed, that better?
|
|
|
06-18-2007, 06:34 PM
|
#9 (permalink)
|
iRawr
Join Date: Dec 2005
Posts: 8,349
|
Yeah, better.
The reason it's better to make the interval changeable is that an interval of .04 or so is more practical for speed, so this alows the user to balance the efficiency they want with the smoothness they want.
|
|
|
06-19-2007, 10:58 PM
|
#10 (permalink)
|
BBoy Silv
Join Date: Nov 2006
Posts: 866
|
Ok. No feedback people? No one wants to comment this brilliant function?? :(:(
EDIT: Is it ok if I add IsTerrainPathable? Because it can get annoying if the unit gets knocked outside the playable map area.
Last edited by Silvenon; 06-20-2007 at 07:22 PM..
|
|
|
06-29-2007, 12:50 AM
|
#11 (permalink)
|
User Title
Join Date: Nov 2006
Posts: 1,029
|
__________________
Vote For The Hive Workshop!
Funny but the TRUTH! :
Quote:
|
Originally Posted by Sopho
Unprotecting maps is not right its like crime and YOU GO MAKE YOUR OWN MAP AND BE HAPPY! Don't be gay n00b!
1. You can if it is yours but you should not if it is not. It is like stealing information and using it as if it is your own. It si gay stuff and people who unprotect maps are gay themselves.
|
|
|
|
06-29-2007, 10:51 AM
|
#12 (permalink)
|
BBoy Silv
Join Date: Nov 2006
Posts: 866
|
Yeah, I have vJass version too, sry :P *fixed
EDIT: Added UnitKnockbackWithLightning for knockbacking with a lightning bolt (I use that quite often)
|
|
|
06-29-2007, 01:11 PM
|
#13 (permalink)
|
Banned
Join Date: Nov 2006
Posts: 6,459
|
om6 h4x tis l33t, sir my use it in my map plz? AWsUM THX
+REP
|
|
|
06-29-2007, 09:37 PM
|
#14 (permalink)
|
Shifting voidwalker!
Join Date: Nov 2004
Posts: 396
|
Isn't flushing one thing manually with SetHandleInt(t,"kd", 0) faster than flushing it all with FlushHandleLocals()?
Last edited by Diablo-dk; 06-30-2007 at 08:54 AM..
|
|
|
06-30-2007, 05:28 PM
|
#15 (permalink)
|
BBoy Silv
Join Date: Nov 2006
Posts: 866
|
Last edited by Silvenon; 07-01-2007 at 11:56 AM..
|
|
|
|
|
|