(Keeps Hive Alive)
Go Back   The Hive Workshop - A Warcraft III Modding Site > Warcraft III Resources > JASS Functions

JASS Functions Approved JASS functions will be located here.
Remember to submit your own resources to the submission forum.

Reply
 
LinkBack Thread Tools Display Modes
Old 06-17-2007, 08:49 PM   #1 (permalink)
 
Silvenon's Avatar

BBoy Silv
 
Join Date: Nov 2006
Posts: 866

Silvenon is on a distinguished road (81)Silvenon is on a distinguished road (81)


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'
endglobals

private 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
endglobals

private constant function Interval takes nothing returns real
    return 0.04
endfunction

private function KillTree takes nothing returns nothing
    if BoolAr[0] then
        call KillDestructable(GetEnumDestructable())
    else
        set BoolAr[1] = true
    endif
endfunction

public 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
    endmethod
endstruct

function 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)
endfunction

function Knockback takes unit u, real d, real a, real w returns nothing
    call Data.create(u, R2I(w / Interval()), d, a, 0, 0, "", "")
endfunction

private 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
endfunction

endlibrary


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 = null
endfunction


GUI:
Test
Events
Unit - A unit starts the effect of an ability
Conditions
(Ability being cast) Equal to <Some Spell>
Actions
Set Caster = (Triggering unit)
Set Target = (Target unit of ability being cast)
Set Distance = (400 + (100 x (Ability level of <Some Spell> for Caster)))
Set Angle = (Facing angle of Caster)
Set Duration = 2
Custom script: call Knockback(udg_Target, udg_Distance, udg_Angle * bj_DEGTORAD, udg_Duration)



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
Silvenon is offline   Reply With Quote
Old 06-17-2007, 08:56 PM   #2 (permalink)
 
Diablo-dk's Avatar

Shifting voidwalker!
 
Join Date: Nov 2004
Posts: 396

Diablo-dk has a spectacular aura about (129)Diablo-dk has a spectacular aura about (129)Diablo-dk has a spectacular aura about (129)Diablo-dk has a spectacular aura about (129)


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.
__________________
Need an easy Recipe System for your map?
Wonder what is inside the Spellbook?
Check my Cinematic!

Vote for the hive, the most friendly wc3 website.
Diablo-dk is offline   Reply With Quote
Old 06-17-2007, 10:41 PM   #3 (permalink)
 
Silvenon's Avatar

BBoy Silv
 
Join Date: Nov 2006
Posts: 866

Silvenon is on a distinguished road (81)Silvenon is on a distinguished road (81)


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.
Silvenon is offline   Reply With Quote
Old 06-18-2007, 03:29 AM   #4 (permalink)

iRawr
 
Join Date: Dec 2005
Posts: 8,349

PurplePoot is a splendid one to behold (807)PurplePoot is a splendid one to behold (807)PurplePoot is a splendid one to behold (807)

Paired Mapping Contest #4 Winner: Fallen Angel - Lucifer's Keep Respected User: This user has been given the respected user award. Map Development Mini-Contest #1 Winner: Stand of the Elements 

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
endfunction

function 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)
PurplePoot is offline   Reply With Quote
Old 06-18-2007, 09:55 AM   #5 (permalink)
 
Silvenon's Avatar

BBoy Silv
 
Join Date: Nov 2006
Posts: 866

Silvenon is on a distinguished road (81)Silvenon is on a distinguished road (81)


*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.
Silvenon is offline   Reply With Quote
Old 06-18-2007, 12:52 PM   #6 (permalink)
 
Diablo-dk's Avatar

Shifting voidwalker!
 
Join Date: Nov 2004
Posts: 396

Diablo-dk has a spectacular aura about (129)Diablo-dk has a spectacular aura about (129)Diablo-dk has a spectacular aura about (129)Diablo-dk has a spectacular aura about (129)


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.
__________________
Need an easy Recipe System for your map?
Wonder what is inside the Spellbook?
Check my Cinematic!

Vote for the hive, the most friendly wc3 website.
Diablo-dk is offline   Reply With Quote
Old 06-18-2007, 12:54 PM   #7 (permalink)

iRawr
 
Join Date: Dec 2005
Posts: 8,349

PurplePoot is a splendid one to behold (807)PurplePoot is a splendid one to behold (807)PurplePoot is a splendid one to behold (807)

Paired Mapping Contest #4 Winner: Fallen Angel - Lucifer's Keep Respected User: This user has been given the respected user award. Map Development Mini-Contest #1 Winner: Stand of the Elements 

~approved, now let's see if I can find out how~
PurplePoot is offline   Reply With Quote
Old 06-18-2007, 06:14 PM   #8 (permalink)
 
Silvenon's Avatar

BBoy Silv
 
Join Date: Nov 2006
Posts: 866

Silvenon is on a distinguished road (81)Silvenon is on a distinguished road (81)


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?
Silvenon is offline   Reply With Quote
Old 06-18-2007, 06:34 PM   #9 (permalink)

iRawr
 
Join Date: Dec 2005
Posts: 8,349

PurplePoot is a splendid one to behold (807)PurplePoot is a splendid one to behold (807)PurplePoot is a splendid one to behold (807)

Paired Mapping Contest #4 Winner: Fallen Angel - Lucifer's Keep Respected User: This user has been given the respected user award. Map Development Mini-Contest #1 Winner: Stand of the Elements 

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.
PurplePoot is offline   Reply With Quote
Old 06-19-2007, 10:58 PM   #10 (permalink)
 
Silvenon's Avatar

BBoy Silv
 
Join Date: Nov 2006
Posts: 866

Silvenon is on a distinguished road (81)Silvenon is on a distinguished road (81)


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..
Silvenon is offline   Reply With Quote
Old 06-29-2007, 12:50 AM   #11 (permalink)
 
PurgeandFire111's Avatar

User Title
 
Join Date: Nov 2006
Posts: 1,029

PurgeandFire111 is a jewel in the rough (155)


Well, Griffen recently said using handles for units or using GetHandleHandle (or something such of the sort) isn't all that great.

Instead, I think you should use JASS NewGen then use structs instead.
vJass For Spell Makers (Moving From Handle Vars to Structs)
__________________
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.
PurgeandFire111 is offline   Reply With Quote
Old 06-29-2007, 10:51 AM   #12 (permalink)
 
Silvenon's Avatar

BBoy Silv
 
Join Date: Nov 2006
Posts: 866

Silvenon is on a distinguished road (81)Silvenon is on a distinguished road (81)


Yeah, I have vJass version too, sry :P *fixed

EDIT: Added UnitKnockbackWithLightning for knockbacking with a lightning bolt (I use that quite often)
Silvenon is offline   Reply With Quote
Old 06-29-2007, 01:11 PM   #13 (permalink)
 
HappyTauren's Avatar

Banned
 
Join Date: Nov 2006
Posts: 6,459

HappyTauren has much of which to be proud (1015)HappyTauren has much of which to be proud (1015)HappyTauren has much of which to be proud (1015)HappyTauren has much of which to be proud (1015)HappyTauren has much of which to be proud (1015)HappyTauren has much of which to be proud (1015)


om6 h4x tis l33t, sir my use it in my map plz? AWsUM THX

+REP
HappyTauren is offline   Reply With Quote
Old 06-29-2007, 09:37 PM   #14 (permalink)
 
Diablo-dk's Avatar

Shifting voidwalker!
 
Join Date: Nov 2004
Posts: 396

Diablo-dk has a spectacular aura about (129)Diablo-dk has a spectacular aura about (129)Diablo-dk has a spectacular aura about (129)Diablo-dk has a spectacular aura about (129)


Isn't flushing one thing manually with SetHandleInt(t,"kd", 0) faster than flushing it all with FlushHandleLocals()?
__________________
Need an easy Recipe System for your map?
Wonder what is inside the Spellbook?
Check my Cinematic!

Vote for the hive, the most friendly wc3 website.

Last edited by Diablo-dk; 06-30-2007 at 08:54 AM..
Diablo-dk is offline   Reply With Quote
Old 06-30-2007, 05:28 PM   #15 (permalink)
 
Silvenon's Avatar

BBoy Silv
 
Join Date: Nov 2006
Posts: 866

Silvenon is on a distinguished road (81)Silvenon is on a distinguished road (81)


If you say so..... *fixed

http://www.wc3campaigns.net/showthread.php?t=91491 Vex used FlushHandleLocals()

EDIT: Minor fixes

Last edited by Silvenon; 07-01-2007 at 11:56 AM..
Silvenon is offline   Reply With Quote
Reply

Bookmarks