1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still haven't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. Rubbed the right way, the genie is out of its lamp! The 12th Concept Art Contest Results have been announced.
    Dismiss Notice
  4. Race against the odds and Reforge, Don't Refund. The 14th Techtree Contest has begun!
    Dismiss Notice
  5. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[JASS] BJ Functions

Discussion in 'Triggers & Scripts' started by Hashjie, May 28, 2009.

  1. Lord_BoNes

    Lord_BoNes

    Joined:
    Sep 5, 2007
    Messages:
    264
    Resources:
    0
    Resources:
    0
    Well I can tell you, at a glance, why that doesn't work...
    Code (vJASS):

        call TriggerSleepAction(1)
        call SetDestructableAnimation(GetDyingDestructable(),"Birth")//GetDyingDestructable

    The GetDyingDestructable() function checks for the last dying destructable, and after a wait.... well, things aren't always what you think. You'd just have to use a local variable:
    Code (vJASS):

        local destructable tree = GetDyingDestructable()
        call TriggerSleepAction(1)
        call SetDestructableAnimation(tree, "Birth")//GetDyingDestructable

    Now THAT would work. :thumbs_up:
     
  2. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,926
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    BJs were fail functions made by blizzard for their GUI engine. They basically were redirectors allowing them to change how they were used in GUI. Blizzard never meant triggers to be heavily used and have to actually need speed, so them being so slow was no problem. However complex spells and systems can be quite demanding, thus as much optimization as possiable is required for maps to be playable.

    Just like leaks, WC3 was not made to support so many of them occuring.
     
  3. Cokemonkey11

    Cokemonkey11

    Wurst Reviewer

    Joined:
    May 9, 2006
    Messages:
    3,237
    Resources:
    18
    Tools:
    1
    Maps:
    5
    Spells:
    3
    Tutorials:
    2
    JASS:
    7
    Resources:
    18
    Can't believe I didn't notice the non instanceability there. But regardless I was talking about the fact that Dying Destructable is a BJ function which simply calls Trigger Widget, but if you simplify it to that native it stops working.
     
  4. Hashjie

    Hashjie

    Joined:
    Apr 20, 2009
    Messages:
    1,515
    Resources:
    0
    Resources:
    0
    and why is that? You don't want gui users to become as powerfull as jass users some day? I'm just trying to improve my gui to make it more efficient... If you dissagree with that then I don't care... As long as it improves my experiences AND my triggers I don't care what you think about the differences between them :)
     
  5. Deaod

    Deaod

    Joined:
    Nov 18, 2007
    Messages:
    805
    Resources:
    12
    Maps:
    1
    Spells:
    11
    Resources:
    12
    GUI uses triggers for every fucking thing you can find (heck, even dynamic triggers, which are considered really bad practice among vJass coders). JASS uses triggers as well, but not as extensively. Understanding where to apply what solution is crucial to writing safe and efficient code. You will never write good JASS code by converting and optimizing GUI generated code (unless you actually rewrite everything, in which case you dont need to write anything in GUI anymore).
     
    Last edited: Jun 3, 2009
  6. Cokemonkey11

    Cokemonkey11

    Wurst Reviewer

    Joined:
    May 9, 2006
    Messages:
    3,237
    Resources:
    18
    Tools:
    1
    Maps:
    5
    Spells:
    3
    Tutorials:
    2
    JASS:
    7
    Resources:
    18
    What's a dynamic trigger?
     
  7. Deaod

    Deaod

    Joined:
    Nov 18, 2007
    Messages:
    805
    Resources:
    12
    Maps:
    1
    Spells:
    11
    Resources:
    12
    A trigger being modified after the map has been initialized (such as adding events, or adding and removing actions/conditions).
     
  8. Cokemonkey11

    Cokemonkey11

    Wurst Reviewer

    Joined:
    May 9, 2006
    Messages:
    3,237
    Resources:
    18
    Tools:
    1
    Maps:
    5
    Spells:
    3
    Tutorials:
    2
    JASS:
    7
    Resources:
    18
    I see. Poorly made damage detection without recycling fits here?
     
  9. Deaod

    Deaod

    Joined:
    Nov 18, 2007
    Messages:
    805
    Resources:
    12
    Maps:
    1
    Spells:
    11
    Resources:
    12
    damage detection is an exception, since blizzard forgot adding EVENT_PLAYER_UNIT_DAMAGED (then again, there are exceptions to this exception, in cases like conditional damage detection, where you only add those units you want to detect damage for; either you detect damage for all units or none). I believe the unit state events also fall in this category.
     
  10. SerraAvenger

    SerraAvenger

    Joined:
    Apr 16, 2007
    Messages:
    149
    Resources:
    4
    Maps:
    4
    Resources:
    4
    hum, last time I checked Dynamic Triggers were Triggers that are Created and Destroyed at runtime...
    Or did I misunderstand something there?
     
  11. Silvenon

    Silvenon

    Joined:
    Nov 22, 2006
    Messages:
    1,233
    Resources:
    1
    Tutorials:
    1
    Resources:
    1
    I don't think anyone mentioned that BJs don't always have to end with "BJ", they can end with Swapped or they don't even have to have a characteristic suffix at all. Just to note one really stupid BJ:

    Code (vJASS):
    function IsUnitAliveBJ takes unit whichUnit returns boolean

        return not IsUnitDeadBJ(whichUnit)

    endfunction


    Code (vJASS):
    function IsUnitDeadBJ takes unit whichUnit returns boolean

        return GetUnitState(whichUnit, UNIT_STATE_LIFE) <= 0

    endfunction


    Well, ain't that dumb... This checks if the unit is alive by checking if unit is not dead, which then checks if the unit's health is less than or equal to 0.

    Also, here's an example of a useful BJ:

    CinematicFadeBJ
    Code (vJASS):
    function CinematicFadeBJ takes integer fadetype, real duration, string tex, real red, real green, real blue, real trans returns nothing

        if (fadetype == bj_CINEFADETYPE_FADEOUT) then

            // Fade out to the requested color.

            call AbortCinematicFadeBJ()

            call CinematicFadeCommonBJ(red, green, blue, duration, tex, 100, trans)

        elseif (fadetype == bj_CINEFADETYPE_FADEIN) then

            // Fade in from the requested color.

            call AbortCinematicFadeBJ()

            call CinematicFadeCommonBJ(red, green, blue, duration, tex, trans, 100)

            call FinishCinematicFadeAfterBJ(duration)

        elseif (fadetype == bj_CINEFADETYPE_FADEOUTIN) then

            // Fade out to the requested color, and then fade back in from it.

            if (duration > 0) then

                call AbortCinematicFadeBJ()

                call CinematicFadeCommonBJ(red, green, blue, duration * 0.5, tex, 100, trans)

                call ContinueCinematicFadeAfterBJ(duration * 0.5, red, green, blue, trans, tex)

                call FinishCinematicFadeAfterBJ(duration)

            endif

        else

            // Unrecognized fadetype - ignore the request.

        endif

    endfunction


    Look what list of BJs it uses:

    holy shit
    Code (vJASS):
    function AbortCinematicFadeBJ takes nothing returns nothing

        if (bj_cineFadeContinueTimer != null) then

            call DestroyTimer(bj_cineFadeContinueTimer)

        endif



        if (bj_cineFadeFinishTimer != null) then

            call DestroyTimer(bj_cineFadeFinishTimer)

        endif

    endfunction


    Code (vJASS):
    function CinematicFadeCommonBJ takes real red, real green, real blue, real duration, string tex, real startTrans, real endTrans returns nothing

        if (duration == 0) then

            // If the fade is instant, use the same starting and ending values,

            // so that we effectively do a set rather than a fade.

            set startTrans = endTrans

        endif

        call EnableUserUI(false)

        call SetCineFilterTexture(tex)

        call SetCineFilterBlendMode(BLEND_MODE_BLEND)

        call SetCineFilterTexMapFlags(TEXMAP_FLAG_NONE)

        call SetCineFilterStartUV(0, 0, 1, 1)

        call SetCineFilterEndUV(0, 0, 1, 1)

        call SetCineFilterStartColor(PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100-startTrans))

        call SetCineFilterEndColor(PercentTo255(red), PercentTo255(green), PercentTo255(blue), PercentTo255(100-endTrans))

        call SetCineFilterDuration(duration)

        call DisplayCineFilter(true)

    endfunction


    Code (vJASS):
    function FinishCinematicFadeAfterBJ takes real duration returns nothing

        // Create a timer to end the cinematic fade.

        set bj_cineFadeFinishTimer = CreateTimer()

        call TimerStart(bj_cineFadeFinishTimer, duration, false, function FinishCinematicFadeBJ)

    endfunction


    Code (vJASS):
    function ContinueCinematicFadeAfterBJ takes real duration, real red, real green, real blue, real trans, string tex returns nothing

        set bj_cineFadeContinueRed = red

        set bj_cineFadeContinueGreen = green

        set bj_cineFadeContinueBlue = blue

        set bj_cineFadeContinueTrans = trans

        set bj_cineFadeContinueDuration = duration

        set bj_cineFadeContinueTex = tex



        // Create a timer to continue the cinematic fade.

        set bj_cineFadeContinueTimer = CreateTimer()

        call TimerStart(bj_cineFadeContinueTimer, duration, false, function ContinueCinematicFadeBJ)

    endfunction


    Code (vJASS):
    function PercentTo255 takes real percentage returns integer

        return PercentToInt(percentage, 255)

    endfunction


    Code (vJASS):
    function PercentToInt takes real percentage, integer max returns integer

        local integer result = R2I(percentage * I2R(max) * 0.01)



        if (result < 0) then

            set result = 0

        elseif (result > max) then

            set result = max

        endif



        return result

    endfunction


    Not to mention how much times those BJs are called. Note that these are only BJs that are used, there are also thousands of natives called too.

    I mean sweet jesus.