Warcraft III resources & community, 2003–2006 · archived

Cinematic Fade For Player

not rated
Submitted by Joey.Conversion0 downloads
Cinematic Fade For Player

This is a conversion of the cinematic fade triggers in "Blizzard.j" to fade
the screen only for a single player, even when there are multiple players in the game.

There is no problem executing the fade effect only for a single player using GetLocalPlayer()
The problem comes from the timers used for cleanly ending the fade
(and the timer for the middle of "fade out and back in"). If you put the standard fade call
inside an asynchronous block, the game will desync because of the timers.

The solution here is for every player to know about every timer.
The timers will be registered and fired for everyone, and only the actual fading will be asynchronous.

I mimic the functions in "Blizzard.j" as closely as possible, CinematicFadeCommonBJ
is used asynchronously to do the actual fading. If you use both "For Player" fades and standard fades
at the same time, you will have slight problems, because the fades will not cancel each other properly.
For example if you do a "fade out and back in" locally, then immediately do a fast global fade,
the global fade will happen, then the "middle" of the local fade will happen for that player.

Source

//===========================================================================
function CinematicFadeCommonForPlayer takes player fadePlayer, real red, real green, real blue, real duration, string tex, real startTrans, real endTrans returns nothing
    if (GetLocalPlayer() == fadePlayer) then
        call CinematicFadeCommonBJ(red, green, blue, duration, tex, startTrans, endTrans)
    endif
endfunction

//===========================================================================
function FinishCinematicFadeForPlayer takes nothing returns nothing
    local integer fadePlayerId = 1

    // We don't know which player the expired timer belongs to,
    // so we check each player's timer to see if it matches the one that just expired.
    loop
        exitwhen udg_cineFadeFinishTimer[fadePlayerId] ==  GetExpiredTimer()
        set fadePlayerId = fadePlayerId + 1
    endloop

    call DestroyTimer(udg_cineFadeFinishTimer[fadePlayerId])
    set udg_cineFadeFinishTimer[fadePlayerId] = null

    if (GetConvertedPlayerId(GetLocalPlayer()) == fadePlayerId) then
        call DisplayCineFilter(false)
        call EnableUserUI(true)
    endif
endfunction

//===========================================================================
function FinishCinematicFadeAfterForPlayer takes player fadePlayer, real duration returns nothing
    local integer fadePlayerId = GetConvertedPlayerId(fadePlayer)

    // Create a timer to end the cinematic fade.
    set udg_cineFadeFinishTimer[fadePlayerId] = CreateTimer()
    call TimerStart(udg_cineFadeFinishTimer[fadePlayerId], duration, false, function FinishCinematicFadeForPlayer)
endfunction

//===========================================================================
function ContinueCinematicFadeForPlayer takes nothing returns nothing
    local integer fadePlayerId = 1

    // We don't know which player the expired timer belongs to,
    // so we check each player's timer to see if it matches the one that just expired.
    loop
        exitwhen udg_cineFadeContinueTimer[fadePlayerId] ==  GetExpiredTimer()
        set fadePlayerId = fadePlayerId + 1
    endloop

    call DestroyTimer(udg_cineFadeContinueTimer[fadePlayerId])
    set udg_cineFadeContinueTimer[fadePlayerId] = null
    call CinematicFadeCommonForPlayer(ConvertedPlayer(fadePlayerId), udg_cineFadeContinueRed, udg_cineFadeContinueGreen, udg_cineFadeContinueBlue, udg_cineFadeContinueDuration, udg_cineFadeContinueTex, udg_cineFadeContinueTrans, 100)
endfunction

//===========================================================================
function ContinueCinematicFadeAfterForPlayer takes player fadePlayer, real duration, real red, real green, real blue, real trans, string tex returns nothing
    local integer fadePlayerId = GetConvertedPlayerId(fadePlayer)

    if (GetLocalPlayer() == fadePlayer) then
        set udg_cineFadeContinueRed = red
        set udg_cineFadeContinueGreen = green
        set udg_cineFadeContinueBlue = blue
        set udg_cineFadeContinueTrans = trans
        set udg_cineFadeContinueDuration = duration
        set udg_cineFadeContinueTex = tex
    endif

    // Create a timer to continue the cinematic fade.
    set udg_cineFadeContinueTimer[fadePlayerId] = CreateTimer()
    call TimerStart(udg_cineFadeContinueTimer[fadePlayerId], duration, false, function ContinueCinematicFadeForPlayer)
endfunction

//===========================================================================
function AbortCinematicFadeForPlayer takes player fadePlayer returns nothing
    local integer fadePlayerId = GetConvertedPlayerId(fadePlayer)
    if (udg_cineFadeContinueTimer[fadePlayerId] != null) then
        call DestroyTimer(udg_cineFadeContinueTimer[fadePlayerId])
    endif

    if (udg_cineFadeFinishTimer[fadePlayerId] != null) then
        call DestroyTimer(udg_cineFadeFinishTimer[fadePlayerId])
    endif
endfunction

function CinematicFadeForPlayer takes player fadePlayer, 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 AbortCinematicFadeForPlayer(fadePlayer)
        call CinematicFadeCommonForPlayer(fadePlayer, red, green, blue, duration, tex, 100, trans)
    elseif (fadetype == bj_CINEFADETYPE_FADEIN) then
        // Fade in from the requested color.
        call AbortCinematicFadeForPlayer(fadePlayer)
        call CinematicFadeCommonForPlayer(fadePlayer, red, green, blue, duration, tex, trans, 100)
        call FinishCinematicFadeAfterForPlayer(fadePlayer, 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 AbortCinematicFadeForPlayer(fadePlayer)
            call CinematicFadeCommonForPlayer(fadePlayer, red, green, blue, duration * 0.5, tex, 100, trans)
            call ContinueCinematicFadeAfterForPlayer(fadePlayer, duration * 0.5, red, green, blue, trans, tex)
            call FinishCinematicFadeAfterForPlayer(fadePlayer, duration)
        endif
    else
        // Unrecognized fadetype - ignore the request.
    endif
endfunction

Comments

3
Well, you could import it from top to bottum in the Map Header, (the blue map icon on the top of the trigger editor) and then when you want the fade to occur, just
--
Custom script:           call CinematicFadeForPlayer(GetOwningPlayer(GetEnumUnit()), bj_CINEFADETYPE_FADEOUT, 0.0, "ReplaceableTextures\\CameraMasks\\White_mask.blp", 255, 255, 255, 0 )

--
or something like that, I assume you'll know when to call whichever functions you find tedious.
//Also, I'm aware that this is also possible in WEU's advanced triggering, however I doubt anyone would want to add 400kb into their map just to use it, when you have a free source to gather from.

You could also gain some knowledge on my Spell Map, look me up :)
http://www.wc3sear.ch/index.php?p=Spells&ID=869
Usefull yes. I've been dying to add night vision and predator vision effects, but could never single out a player. Where could I find out how to implement this code exactly. I keep getting compile errors.
Very useful...

Good job 5/5 :D