• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Small Code Snippets

Level 40
Joined
Dec 14, 2005
Messages
10,532
To keep out a potential deluge of threads with very small functions, this thread is for you to post short functions you wish to share.

Normal or long-length snippets still go the same place as always.

So, if you have something worth sharing, post it here!


Functions







JASS:
//By Silvenon
function PreloadSoundPath takes string path returns nothing
    local sound snd = CreateSound(path, false, false, false, 10, 10, "")
    call SetSoundVolume(snd, 0)
    call StartSound(snd)
    call KillSoundWhenDone(snd)
    set snd = null
endfunction
JASS:
//By DiscipleOfLife and Troll-Brain
library QuickTimer
    //=======================================================================
    // Attaches an integer to a timer and makes it expire after 0 seconds.
    // The integer passed must be a positive value.
    //
    function TimerExpireQuick takes timer t, integer data, code func returns nothing
        call TimerStart(t, -data, false, func)
    endfunction
   
    //=======================================================================
    // Returns the integer attached to a quick timer.
    //
    function QuickTimerGetData takes timer t returns integer
        return -R2I(TimerGetTimeout(t))
    endfunction
endlibrary

 
Last edited by a moderator:
Level 13
Joined
Nov 22, 2006
Messages
1,260
JASS:
function GetClosestUnit takes real x, real y, boolexpr e returns unit
    local real md = 100000
    local real d
    local group g = CreateGroup()
    local unit u
    local real dx
    local real dy
    call GroupEnumUnitsInRect(g, bj_mapInitialPlayableArea, e)
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        call GroupRemoveUnit(g, u)
        set dx = GetUnitX(u) - x
        set dy = GetUnitY(u) - y
        if (dx * dx + dy * dy) / 100000 < md then
            set udg_ClosestUnit = u
            set md = (dx * dx + dy * dy) / 100000
        endif
    endloop
    call DestroyGroup(g)
    call DestroyBoolExpr(e)
    set g = null
    return udg_ClosestUnit
endfunction


Instructions:

Before using anything, you must create a global variable named ClosestUnit of type unit.

Parameters:
  • real x - x coordinate of the point from where the function searches for the closest unit
  • real y - y coordinate of the point from where the function searches for the closest unit
  • boolexpr e - used for filtering (enemy, illusion, hero...), you can put null if you don't want any filter

You can use the function in two ways:

JASS:
function FirstWay takes nothing returns nothing
    local unit u = SomeUnit()
    local unit c
    set c = GetClosestUnit(GetUnitX(u), GetUnitY(u))
    call DoSomethingWithUnit(c)
    set u = null
    set c = null
endfunction


Or:

JASS:
function SecondWay takes nothing returns nothing
    local unit u = SomeUnit()
    call GetClosestUnit(GetUnitX(u), GetUnitY(u))
    call DoSomethingWithUnit(udg_ClosestUnit)
    set u = null
endfunction
 
Last edited:
Level 12
Joined
Aug 3, 2005
Messages
745
Stun a Unit, for X seconds:
You could add an SFX extension as well.

(I tried using jass tags but it screws up, becoming 1 gigantic line).

Uses a Timer Stack

JASS:
globals
    integer array StunArray
    integer StunTotal=0
endglobals

struct stundata
    unit u=null
    real d=0
    boolean destroyplease=false
endstruct

function StunUnit_KeepStunned takes nothing returns nothing
    local integer i = 0
    local stundata dat
    loop
        exitwhen i==Stun_Total
        set dat=StunArray[i]
        if dat.destroyplease then
            set Stun_Total=Stun_Total-1
            set StunArray[i]=StunArray[Stun_Total]
            call dat.destroy()
            set i=i-1
        else
            set dat.d=dat.d-0.01
            call SetUnitPosition(dat.u,GetUnitX(dat.u),GetUnitY(dat.u))
            set dat.destroyplease=(dat.d<=0)
        endif
        set i=i+1
    endloop
    if Stun_Total==0 then
        call ReleaseTimer(GetExpiredTimer())
    endif
endfunction

function StunUnit takes unit u,real d returns nothing
    local stundata dat=stundata.create()
    set dat.d=d
    set dat.u=u
    if (Stun_Total==0) then
        call TimerStart(NewTimer(),.01,true,function StunUnit_KeepStunned)
    endif
    set Stun_Total=Stun_Total+1
    set StunArray[Stun_Total-1]=dat
endfunction
 
Last edited by a moderator:
Level 3
Joined
Sep 4, 2007
Messages
49
You should probably mention there is a global integer array StunArray and also that the function requires JassNewGen, also I don't see any actual stunning going on (just moving a unit).

It also uses a timer stack (release timer) which you havent specified, other then that the function looks good and efficient
 
Level 12
Joined
Aug 3, 2005
Messages
745
Aha yea thx, updated.

Yea its an alternative way of stunning without using A Stormbolt spell with 100 levels.

On my map the function also takes an effect + attachment point so you can customise the overhead buff. I'd recommend the same.
(Id need to included the whole AddTimedSfx for that).
 
Level 3
Joined
Sep 4, 2007
Messages
49
Yeah what I was saying is that you dont have IssueTargetOrder order for the spell or whatever you need to do to stun. Someone will put this in their map and say WTF this doesnt do anything. I know how custom stun systems work, they stun forever and then a timer removes the buff. There is however none of that in what you posted
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
Yeah, that's what I meant.

And Fulla, I edited your post to use
JASS:
 tags.

Also, it'd be easier to just store the struct to a cache on a timer with the duration of the stun, and then remove the stun after the end of the duration. (However you need to Pause them this way)

Or cast a dummy ability that stuns forever then remove the buff after long enough, thus also adding a buff.
 
Level 1
Joined
Dec 6, 2006
Messages
72
Regrow Trees

This is a script I made that will revive trees that die for some reason. Whether it be a peasant picking at it or a spell that destroys trees like flame strike.

JASS:
function RegrowTrees takes nothing returns nothing
    local destructable tree=GetDyingDestructable()
    call TriggerSleepAction(10)
    call DestructableRestoreLife( tree, GetDestructableMaxLife(tree), true )
    set tree=null
endfunction

function Trig_Int_Tree_Revival takes nothing returns nothing
    local integer d=GetDestructableTypeId(GetEnumDestructable())
    if d=='ATtr' or d=='BTtw' or d=='KTtw' or d=='YTft' or d=='YTct' or d=='YTwt' or d=='JTwt' or d=='DTsh' or d=='FTtw' or d=='CTtr' or d=='ITtw' or d=='NTtw' or d=='OTtw' or d=='ZTtw' or d=='WTst' or d=='LTlt' or d=='GTsh' or d=='Xtlt' or d=='WTtw' or d=='ATtc' or d=='BTtc' or d=='CTtc' or d=='ITtc' or d=='ZTtc' then
    call TriggerRegisterDeathEvent( gg_trg_Regrow_Trees, GetEnumDestructable() )
    call TriggerAddAction(gg_trg_Regrow_Trees,function RegrowTrees)
endif
endfunction

function Int_Tree_Revive takes nothing returns nothing
    call EnumDestructablesInRect(GetPlayableMapRect(), null, function Trig_Int_Tree_Revival)
endfunction

___________

I will add a test map later
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
GetPlayableMapRect() == bj_mapInitialPlayableArea

Also, better use timer instead of TriggerSleepAction.......hehe I can't remember the last time I used that crappy function :)

Anyways, it's a nice idea. Maybe you should put the time-to-regrow in a global so it can be easily changeable.

EDIT: Maybe add a GetAbilityOrderString function Pooty? I don't know how to do that efficiently.
 
Last edited:
Level 6
Joined
Nov 4, 2004
Messages
125
When stunning a unit for x seconds, I suggest using Aerial Shackles with infinite duration and then adding an expiration timer, or any timer after casting the spell. As far as I know, aerial shackles cannot be dispelled, but the only way to cancel it is to stun/silence the caster which won't work with a locust unit. So that way you get the same effect like stormbolt, with a duration of x.xx seconds if you like, and you only need one spell level :)
(I have tried it this way in my map "BEER BEER", and so far it worked flawless)

//Edit: Just saw that purplepoot posted something similiar already. Well, I suggest aerial shackles as dummy!
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
JASS:
function PreloadSoundPath takes string path returns nothing
    local sound snd = CreateSound(path, false, false, false, 10, 10, "")
    call SetSoundVolume(snd, 0)
    call StartSound(snd)
    call KillSoundWhenDone(snd)
    set snd = null
endfunction


Just a retarded function that preloads a sound in the given path. If someone doesn't know, first time you play a sound nothing happens, because the sound is loaded first, so this function does that loading part.

Maybe we should do something about these snippets Pooty? For example do something about this:

PurplePoot said:
Functions

(none yet)
 
Level 17
Joined
Jun 17, 2007
Messages
1,433
JASS:
function Trig_Single_Player_Defeat_Actions takes nothing returns nothing
    //do whatever//
endfunction

//===========================================================================
function Trig_Single_Player_Defeat_Conditions takes nothing returns boolean
    return bj_isSinglePlayer == true
endfunction

function InitTrig_Single_Player_Defeat takes nothing returns nothing
    set gg_trg_Single_Player_Defeat = CreateTrigger(  )
    call TriggerRegisterTimerEventSingle( gg_trg_Single_Player_Defeat, 15.00 )
    call TriggerAddCondition( gg_trg_Single_Player_Defeat, Condition( function Trig_Single_Player_Defeat_Conditions ) )
    call TriggerAddAction( gg_trg_Single_Player_Defeat, function Trig_Single_Player_Defeat_Actions )
endfunction

That will detect if the game is single player at 15 seconds.
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
JASS:
function IsDestTree takes destructable dest returns boolean
    local integer d = GetDestructableTypeId(dest)
    return d == 'ATtr' or d == 'BTtw' or d == 'KTtw' or d == 'YTft' or d == 'JTct' or d == 'YTst' or d == 'YTct' or d == 'YTwt' or d == 'JTwt' or d == 'JTwt' or d == 'FTtw' or d == 'CTtr' or d == 'ITtw' or d == 'NTtw' or d == 'OTtw' or d == 'ZTtw' or d == 'WTst' or d == 'LTlt' or d == 'GTsh' or d == 'Xtlt' or d == 'WTtw' or d == 'Attc' or d == 'BTtc' or d == 'CTtc' or d == 'ITtc' or d == 'NTtc' or d == 'ZTtc'
endfunction


Just a function that checks if the given destructable is a tree.
 
Last edited:
Level 1
Joined
Dec 6, 2006
Messages
72
JASS:
function IsDestTree takes destructable dest returns boolean
    local integer d = GetDestructableTypeId(dest)
    return d == 'ATtr' or d == 'BTtw' or d == 'KTtw' or d == 'YTft' or d == 'JTct' or d == 'YTst' or d == 'YTct' or d == 'YTwt' or d == 'JTwt' or d == 'JTwt' or d == 'FTtw' or d == 'CTtr' or d == 'ITtw' or d == 'NTtw' or d == 'OTtw' or d == 'ZTtw' or d == 'WTst' or d == 'LTlt' or d == 'GTsh' or d == 'Xtlt' or d == 'WTtw' or d == 'Attc' or d == 'BTtc' or d == 'CTtc' or d == 'ITtc' or d == 'NTtc' or d == 'ZTtc'
endfunction


Just a function that checks if the given destructable is a tree.

That looks like you just too out a piece of my code and called it your own code..
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
I never said I made it, but yes, that was a bitchy thing to do, sorry.

This is what I said when I was using the function in the Coding an efficient knockback tutorial if it makes you feel better:

Silvenon said:
This is a function I wrote (actually copied from Hero12341234's Tree Revival tutorial, hehe, sorry Hero....)

You can see for yourself if you don't believe me. I just modified it a bit.

Now I'm going in my room to cry........give me neg rep Purple! (not a joke, I deserve it)

Again, sorry Hero, I forgot to mention it was yours (like I did in the tutorial).
 
Level 9
Joined
Mar 25, 2005
Messages
252
Hello friends. Here is my gift of the month to you:
EDIT: moved here
JASS:
Not here anymore

I have tested all of these except for the __InGroup versions, but I think its safe to assume that all of them work because of their similarity.

Im also quite sure (lets say 100%) that this is faster than the FirstOfGroup(...) looping alternative.

117 lines of code... I guess this might be better off with a thread of its own but meh. If thats the case Im sure you'll tell me.
 
Last edited:
Level 13
Joined
Nov 22, 2006
Messages
1,260
That looks awesome, but:

To keep out a potential deluge of threads with very small functions, I've created this thread for you to post relatively short functions you wish to share.

I would rather post that in the JASS functions, not small code snippets.

Crap, this totally beats up my GetClosestUnit function, thanks Disciple <sarcasm> :p
 
Level 17
Joined
Jun 17, 2007
Messages
1,433
This is really small, and probably already made, but it's worth a shot.

JASS:
function AddWeatherEffectForPlayer takes rect where, integer effectID, player whichplayer returns nothing
    if GetLocalPlayer() == whichplayer then
        call AddWeatherEffect(where, effectID)
    endif
endfunction
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
We can make 5 000 000 of those, but it's ok, I guess.

Better to make stuff like:

JASS:
function CreateUnitForPlayer takes player owner, integer unitID, real x, real y, real facing, player whichPlayer returns unit
    local integer i
        if GetLocalPlayer() == whichPlayer then
            set i = unitID
        endif
    return CreateUnit(owner, i, x, y, facing)
endfunction


I don't know how this function works exactly, I don't understand how can you create a unit that exists only for one player, but I've seen it on TheHelper.

Or maybe:

JASS:
function AddSpecialEffectForPlayer takes string path, real x, real y, player whichPlayer returns effect
    local string s
        if GetLocalPlayer() == whichPlayer then
            set s = path
        endif
    return AddSpecialEffect(s, x, y)
endfunction
 
Level 12
Joined
Aug 20, 2007
Messages
866
GetClosestUnitFunction

I'm assuming that the function works, but could you explain it to me a bit better, kind of step by step

Mostly, I'm curious as to why (dx^2 + dy^2)/100000 > 100000 is the closest unit (I suppose that 100000 is the max size of all maps?)
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
No.

You see, I was trying to avoid SquareRoot function (as you can see, there isn't one in it). In the beginning, md variable represents a great distance (probably bigger than the map) which is compared to the location from which it is searching the closest unit. If distance from a picked unit and that location is lower than that distance (which it is), md becomes the distance between the picked unit and the location. Then it compares to the other units, if the distance from a certain unit to that location is lower than the current md, that md becomes that distance.

But, since I'm not using SquareRoot, the system compares each distance squared (since I'm not square rooting it), so md has to represent a distance greater than any other, but it has to be squared (since maybe some distance squared will be greater than that one), so with a little help from Disciple, I used this simple equation:

Code:
x = y
x/1000 = y/1000

I had to lower each number because there is a number limit in wc3 from which every next number becomes the negative value of that number (then I would be calculating with negative distances........yeah).

Get it?
 
Level 12
Joined
Aug 20, 2007
Messages
866
Hmmm

Ohhhhh now I got it

Your just getting the x and the y, then using pythagorean thereom

There isn't a ^ (1/2) function so it had to be a number that is much larger than any two squares could be (100000*100000)

But at the same time, x^2 and y^2 would get so big they would flip to negative(odd), so you just divided x^2 + y^2 by 100000

So, does it keep looping over and over, even after you got the unit??? (maybe you should add something so it doesn't loop with over 300 units or something)

_________________________________________________
EDIT

Finally, I'm starting to really understand JASS thanks to these little code snippets, thank you so much for this
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
Yeah, it loops through all units that satisfy the boolexpr condition. I can't make it run through less units because........because I just can't, I need to check every single one. This is supposed to be fast, so it shouldn't lag.

That flipping-to-negative is a stupid bug and people should be careful with it.
 
Level 12
Joined
Aug 20, 2007
Messages
866
Question

Do you think it would lag awfully in a timed trigger (.05) on a massive risk map??? (each unit has bout 100hp each, cost 1, and each player receives +100 gold per round)
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
First of all, this is getting offtopic, you should open a new thread or PM me, second of all, you really gave me little information, try to explain the details more (for example, I already lost you at the "massive risk map" part, since I don't know what that is).
 
Level 12
Joined
Aug 20, 2007
Messages
866
Eh nvm

I'm not gonna be making any risk maps any time soon, so it doesn't really matter just a bit curious


Btw, How come you wanted to avoid the SquareRoot function?
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
Arghhhh try to put all your questions in the fewest number of posts possible!

SquareRoot is a slow function, many good jassers are avoiding it. There are also other slow functions that should be avoided: Sin(), Cos(), Tan(), Pow()......
 
Level 12
Joined
Aug 20, 2007
Messages
866
Sorry bout that

Yeah the questions kind of just keep popping into my mind

Damn sin, cos, tan, pow, all are no good

That makes me sad :cry:

I suppose you would only use those if they were absolutely necessary, like a polar coordinate (I think uses one of those)
 
Level 13
Joined
Nov 22, 2006
Messages
1,260
Yeah, sometimes you have to use those, but I think Pow() isn't necessary in any situation (since Pow(x, 3) = x * x * x).

But with the power of vJass sin, cos and tan won't make problems anymore (since every good vJass code is freakin fast).

If you got any more questions, PM me, that would be better.
 
Level 12
Joined
Aug 20, 2007
Messages
866
Ok sure

Something about the unit for one player, I suppose you could use it as a dummy unit, and create special effects for players who should see it, and not for players who couldn't see it

I'm not really sure when the situation would call for it, but I suppose it would be for an RPG or something

(Maybe a flare behind a wall???)
 
Top