• 🏆 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!

"GetLocalPlayer" causes DeSync??

Status
Not open for further replies.
Level 5
Joined
Oct 2, 2013
Messages
95
I'm creating a flashbang spell - a grenade that causes players screen to go white ( making them blind ) if they are nearby. Using a map example found in this thread:
http://www.hiveworkshop.com/threads/flashbang-spell.129244/
posted by maskedpoptart, i've achieved the desired effect. However, it uses "GetLocalPlayer" funtion so that only the affected players are blinded ( and not all of them ).

I've seen people say that using this method ( the way the flashbang works ) causes desync, and I would like to know if its true.

Here's the code from the flashband spell by maskedpoptart:
JASS:
//======SETUP (STUFF YOU CAN CHANGE)========
function Trig_flashbang_Radius takes integer spellLevel returns real
    //this is the flash effect radius, depending on the ability level
    return 300.0 + 200*spellLevel
endfunction

function Trig_flashbang_Duration takes integer spellLevel returns real
    //this calculates the duration
    return 2.0*spellLevel
endfunction

function Trig_flashbang_AbilityId takes nothing returns integer
    //replace 'AHtb' with the raw code of your flashbang spell.
    //to find the raw code value, go to object editor, click the view tab, and click "display values as raw data."
    //you should now see the raw values next to the names of everything
    return 'AHtb'
endfunction

//=======CONDITIONS===========

function Trig_flashbang_Conditions takes nothing returns boolean
    return ( GetSpellAbilityId() == Trig_flashbang_AbilityId() )
endfunction

//========ACTIONS==============

//put this next function in your map header if you want to use it outside this trigger
function CinematicFadeForPlayer takes player whichPlayer, integer fadetype, real duration, string tex, real red, real green, real blue, real trans returns nothing
    if(GetLocalPlayer() == whichPlayer)then
        call CinematicFadeBJ(fadetype, duration, tex, red, green, blue, trans)
    endif
endfunction

function Trig_flashbang_filter takes nothing returns boolean
    return true//( IsPlayerEnemy( GetOwningPlayer(GetFilterUnit()), GetOwningPlayer(GetTriggerUnit()) ) )
endfunction

function Trig_flashbang_ForGroupActions takes nothing returns nothing
    local player owningPlayer = GetOwningPlayer(GetEnumUnit())
    call CinematicFadeForPlayer(owningPlayer, bj_CINEFADETYPE_FADEOUT, .1, "ReplaceableTextures\\CameraMasks\\White_mask.blp", 100, 100, 100, 0)
endfunction

function Trig_flashbang_ForGroupActions2 takes nothing returns nothing
    local player owningPlayer = GetOwningPlayer(GetEnumUnit())
    call CinematicFadeForPlayer(owningPlayer, bj_CINEFADETYPE_FADEIN, Trig_flashbang_Duration( GetUnitAbilityLevel(GetTriggerUnit(), Trig_flashbang_AbilityId()) )/2, "ReplaceableTextures\\CameraMasks\\White_mask.blp", 100, 100, 100, 0)
endfunction

function Trig_flashbang_Actions takes nothing returns nothing
    local integer skillLevel = GetUnitAbilityLevel(GetTriggerUnit(), Trig_flashbang_AbilityId())
    local unit target = GetSpellTargetUnit()
    local real targetX = GetUnitX(target)
    local real targetY = GetUnitY(target)
    local group affectedUnits = CreateGroup()
    call GroupEnumUnitsInRange(affectedUnits, targetX, targetY, Trig_flashbang_Radius(skillLevel), Condition(function Trig_flashbang_filter))
    call ForGroup(affectedUnits, function Trig_flashbang_ForGroupActions )
    //this next line is a bad function to use, but the alternative method is too much work without using JassNewGenPack (vJass)
    call TriggerSleepAction ( .1+Trig_flashbang_Duration(skillLevel)/2 )
    call ForGroup(affectedUnits, function Trig_flashbang_ForGroupActions2 )

    call DestroyGroup(affectedUnits)
    set affectedUnits = null
    set target = null
endfunction

//========EVENTS==============

function InitTrig_flashbang takes nothing returns nothing
    set gg_trg_flashbang = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_flashbang, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_flashbang, Condition( function Trig_flashbang_Conditions ) )
    call TriggerAddAction( gg_trg_flashbang, function Trig_flashbang_Actions )
endfunction
 
Last edited by a moderator:
You should use the script here by WaterKnight:
http://www.hiveworkshop.com/threads/fade-filter-for-triggering-player.175880/#post-1676883

For this particular spell, you can use a smaller version (below). Create this variable in the variable editor:

cineFadeFinishTimer -> timer array with size 11, preset value new timer

Then remove the CinematicFadeForPlayer function and put this instead:
JASS:
function CinematicFadeCommonForPlayer takes player p, real red, real green, real blue, real duration, string tex, real startTrans, real endTrans returns nothing
    if (duration == 0) then
        set startTrans = endTrans
    endif
    if (GetLocalPlayer() == p) then
        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)
    endif
endfunction

function FinishCinematicFadeForPlayer takes nothing returns nothing
    local integer playerid
    local integer index = 0
    loop
        exitwhen index > 11
        if (GetExpiredTimer() == udg_cineFadeFinishTimer[index]) then
            set playerid = index
        endif
        set index = index + 1
    endloop
    call DestroyTimer(udg_cineFadeFinishTimer[playerid])
    set udg_cineFadeFinishTimer[playerid] = null
    if (GetPlayerId(GetLocalPlayer()) == playerid) then
        call DisplayCineFilter(false)
        call EnableUserUI(true)
    endif
endfunction

function FinishCinematicFadeAfterForPlayer takes integer playerid, real duration returns nothing
    set udg_cineFadeFinishTimer[playerid] = CreateTimer()
    call TimerStart(udg_cineFadeFinishTimer[playerid], duration, false, function FinishCinematicFadeForPlayer)
endfunction

function AbortCinematicFadeForPlayer takes integer playerid returns nothing
    if (udg_cineFadeFinishTimer[playerid] != null) then
        call DestroyTimer(udg_cineFadeFinishTimer[playerid])
    endif
endfunction

function CinematicFadeForPlayer takes player p, integer fadetype, real duration, string tex, real red, real green, real blue, real trans returns nothing
    local integer playerid = GetPlayerId(p)
    if (fadetype == bj_CINEFADETYPE_FADEOUT) then
        call AbortCinematicFadeForPlayer(playerid)
        call CinematicFadeCommonForPlayer(p, red, green, blue, duration, tex, 100, trans)
    elseif (fadetype == bj_CINEFADETYPE_FADEIN) then
        call AbortCinematicFadeForPlayer(playerid)
        call CinematicFadeCommonForPlayer(p, red, green, blue, duration, tex, trans, 100)
        call FinishCinematicFadeAfterForPlayer(playerid, duration)
    endif
endfunction
 
Last edited:
Level 4
Joined
Sep 13, 2014
Messages
106
The problem is that the function "CinematicFadeBJ" is a BJ function that creates and destroys timers. You cannot create or destroy any type that extends agent locally without causing desync. You can use the cinematic natives, however.

It's probably best to test for yourself whether the code desyncs or not - programs can have bugs even if you don't notice them.

Look at the link for GetLocalPlayer() in PurgeAndFire's signature for more information.

WaterKnight's solution probably works. I think this solution is probably simpler and nicer though:

http://www.hiveworkshop.com/threads/getlocalplayer-faq.224876/


  • Test 1
    • Events
      • Player - Player 1 (Red) types a chat message containing test1 as An exact match
    • Conditions
    • Actions
      • Set TempForce = (All allies of Player 1 (Red))
      • Set AlphaReal = 100
      • Custom script: if IsPlayerInForce(GetLocalPlayer(),udg_TempForce) then
      • Set AlphaReal = 0
      • Custom script: endif
      • Cinematic - Fade out and back in over 2.00 seconds using texture Black Mask and color (0.00%, 0.00%, 0.00%) with AlphaReal transparency
 
Last edited:
Level 5
Joined
Oct 2, 2013
Messages
95
Thanks for the replies!

I've implemented PurgeandFire's code into the spell by maskedpoptart and it works very nicely. Am I safe to assume it won't cause desyncs then, even when flashing multiple units?

Also, another thing: my ideal flashbang duration would vary based on a number of factors. Even with different durations on the fade timers ( so that some players would be flashed for longer ) it wouldn't cause desync?
 
Status
Not open for further replies.
Top