Polled waits causing the thread to break?

Homer

New Member
Reaction score
2
Here are my functions

Spawns heroes to select from and initiates at timer.
JASS:
function Selection_time takes nothing returns nothing
local integer i = 1
local unit u = null
set i = 1
    loop
        exitwhen i > udg_numberofplayers
        if (CheckPlayer(i-1)) then
            if (g_selected<i>==false) then
                set u = GroupPickRandomUnit(g_group)
                call GroupRemoveUnit(g_group,u)
                set udg_selection_hero<i>=u
                call DisplayTimedTextToForce(GetPlayersAll(),4.0,g_playercolor<i>+GetPlayerName(Player(i-1))+&quot;|r has picked &quot;+EVENT+GetUnitName(u)+&quot;|r.&quot;)
                
            endif
        endif
        set i = i + 1
    endloop
    call BJDebugMsg(&quot;TEST&quot;)
    call EndHeroSelection()
    call BJDebugMsg(&quot;TEST2&quot;) 
endfunction

selects heroes, and ends the selection when everyone has pick a hero.

function Trig_set_up_heroes_Actions takes nothing returns nothing
local integer i = 1
local integer index = 0
local integer imax=4
local integer a= 1
local location point = GetRectCenter(gg_rct_HS_start_point)
local location point2
local unit u = null
local string fx=&quot;Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl&quot;
set g_timer= CreateTimer()
set g_group = CreateGroup()


call DisplayTextToForce(GetPlayersAll(),EVENT+&quot;Select a Hero:|r Click on a hero you wish to play as.&quot;)
call DisplayTextToForce(GetPlayersAll(),HINT+&quot;You may only pick a hero not selected by another player.|r&quot;)
call TriggerExecute(gg_trg_vision)
call Reveal(true)
    loop
    exitwhen i&gt;udg_numberofplayers
    set g_selected<i>=false
    set i = i+1
    endloop
    set i = 1
    loop
        exitwhen i &gt; imax
        set a = 1
        loop
        exitwhen a &gt; 4
        set point2  = OffsetLocation(point, I2R( ModuloInteger(a-1, 4) * 200 ), I2R( i * -200 ))
        
        call CreateNUnitsAtLoc( 1, udg_heroes[((i-1)*4)+a-1], Player(PLAYER_NEUTRAL_PASSIVE), point2, 270.00 )
        call GroupAddUnit(g_group,GetLastCreatedUnit())
        call UnitRemoveAbility(GetLastCreatedUnit(),&#039;Amov&#039;)
        call UnitRemoveAbility(GetLastCreatedUnit(),&#039;Aatk&#039;)
        call UnitAddAbility(GetLastCreatedUnit(),&#039;A999&#039;)        
        call special_effect(fx,point2)
        set a = a + 1
        endloop
        call TriggerSleepAction(1.0)
        set i = i + 1
    endloop
    set udg_selection_ready = true
    call TimerStart(g_timer,30.00,false,function Selection_time)
    set g_timerdialog=CreateTimerDialog(g_timer)
    call TimerDialogDisplay(g_timerdialog,true)
    
    call RemoveLocation(point)   
endfunction</i></i></i></i>


JASS:
function Trig_selection_method_Func001Func001C takes integer i, unit u returns boolean
    if ( not ( udg_selection_hero<i> == u ) ) then
        return false
    endif
    return true
endfunction

function Trig_selection_method_Actions takes nothing returns nothing
    local boolean bool = false
    local unit u = GetTriggerUnit()
    local player p = GetTriggerPlayer()
    local integer i = 1
    local integer imax = udg_numberofplayers
    
    if (udg_selection_ready == true) then
    if (IsUnitType(u, UNIT_TYPE_HERO)) then
    loop
        exitwhen i &gt; imax
        if ( Trig_selection_method_Func001Func001C(i, u) ) then
        set bool = true
        endif
        set i = i + 1
    endloop
    if (g_selected[GetConvertedPlayerId(p)]==false) then
    if (bool == false) then
    call SetUnitOwner( udg_selection_hero[GetConvertedPlayerId(p)], Player(PLAYER_NEUTRAL_PASSIVE), true )
    call SelectUnitForPlayerSingle( u, p )
    call SetUnitOwner( u, p, true )
    set udg_selection_hero[GetConvertedPlayerId(p)] = u
    endif
    endif
    endif
    endif
endfunction

function PickHero takes nothing returns nothing
local player p = GetOwningPlayer(GetSpellAbilityUnit())
local unit u = GetSpellAbilityUnit()
local integer i = 0
local boolean bool = true
local string fx=&quot;Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl&quot;
local location point
local group g = CreateGroup()
if (g_selected[GetConvertedPlayerId(p)]==false) then
if (GetSpellAbilityId()==PICKHERO) then
set g_selected[GetConvertedPlayerId(p)]=true
call UnitRemoveAbility(u,PICKHERO)
call DisplayTimedTextToForce(GetPlayersAll(),99999,g_playercolor[GetConvertedPlayerId(p)]+GetPlayerName(Player(GetConvertedPlayerId(p)-1))+&quot;|r has picked &quot;+EVENT+GetUnitName(udg_selection_hero[GetConvertedPlayerId(p)])+&quot;|r.&quot;)


loop
    exitwhen i&gt;udg_numberofplayers
    if (GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING) then
         if (GetPlayerController(Player(i)) == MAP_CONTROL_USER) then
            if (g_selected[i+1]==false) then
                set bool = false
                
            endif
         endif
    endif    
    set i = i + 1
endloop
    //change into a seperate function
if (bool==true) then
call EndHeroSelection()
endif
endif
endif
endfunction

//===========================================================================
function InitTrig_selection_method takes nothing returns nothing
    local trigger selection_method = CreateTrigger(  )
    local trigger changeoption = CreateTrigger(  )
    call TriggerRegisterPlayerSelectionEventBJ( selection_method, Player(0), true )
    call TriggerRegisterPlayerSelectionEventBJ( selection_method, Player(1), true )
    call TriggerRegisterPlayerSelectionEventBJ( selection_method, Player(2), true )
    call TriggerRegisterPlayerSelectionEventBJ( selection_method, Player(3), true )
    call TriggerRegisterPlayerSelectionEventBJ( selection_method, Player(4), true )
    call TriggerRegisterPlayerSelectionEventBJ( selection_method, Player(5), true )
    call TriggerAddAction( selection_method, function Trig_selection_method_Actions )
    call TriggerRegisterPlayerUnitEventSimple( changeoption, Player(0), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( changeoption, Player(1), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( changeoption, Player(2), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( changeoption, Player(3), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( changeoption, Player(4), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerRegisterPlayerUnitEventSimple( changeoption, Player(5), EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddAction( changeoption, function PickHero )
endfunction

</i>


EndHeroSelection function
JASS:
function EndHeroSelection takes nothing returns nothing
    local integer i = 1
    local location point 
    local string fx=&quot;Abilities\\Spells\\Human\\MassTeleport\\MassTeleportTarget.mdl&quot;
    
    call PolledWait(2.0)
    set i = 1
    loop
    exitwhen i&gt;udg_numberofplayers
    if (GetPlayerSlotState(Player(i-1)) == PLAYER_SLOT_STATE_PLAYING) then
        if (GetPlayerController(Player(i-1)) == MAP_CONTROL_USER) then
            
                set point = GetUnitLoc(udg_selection_hero<i>)
                call special_effect(fx,point)
                set g_selected<i>= true
                call SetUnitOwner(udg_selection_hero<i>,Player(PLAYER_NEUTRAL_PASSIVE), true )
                call SetUnitPositionLoc(udg_selection_hero<i>,GetRectCenter(gg_rct_hideheroes))
                
        endif
    endif
    set i = i + 1
    endloop
    call DestroyTimer(g_timer)
    call DestroyTimerDialog(g_timerdialog)
    set g_timer=null
    set g_timerdialog=null
        
    call PolledWait(2.0)    
    
    call CinematicFilterGenericBJ( 1.00, BLEND_MODE_BLEND, &quot;ReplaceableTextures\\CameraMasks\\Black_mask.blp&quot;, 100, 100, 100, 100.00, 0, 0, 0, 0 )
    call PolledWait(1.1)
    call Reveal(false)
    set g_setting = 999
    call UpdateSelector()

    //return
endfunction</i></i></i></i>


the waits break the thread when called from the timer function. However, it works fine when triggered via all heroes select.
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
You can't use TriggerSleepAction in any callback (timer,ForGroup,GroupEnum, and so one) and also not in a condition.
PolledWait is an "enhanced" TriggerSleepAction, open the blizzard.j to see how the function is made, basically it is just a loop with a TriggerSleepAction and a timer used.

So you must use a timer and maybe an attachment method/system like TimerUtils (didn't read your code).
 

Homer

New Member
Reaction score
2
thanks, Thats a bummer :) although i coulda swore it was working before... If i use the event timer expires will it work?
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
In the function Selection_time use this :

JASS:
call EndHeroSelection.execute() (vJass)
. or
JASS:
call ExecuteFunc(&quot;EndHeroSelection&quot;)
.
For many reasons the vJass is the best solution :

- easier to debug : when you do an error in an ExecuteFunc (invalid string) war3 crash and you don't know why.
- can take arguments, ExecuteFunc can't.
- it's faster than ExecuteFunc
- can use a function as an object (read the jasshelper documentation)
- the result code is more nice.
- and maybe some other features i've forgotten

Then, you should be able to use TriggerSleepAction in the function EndHeroSelection.
 

Homer

New Member
Reaction score
2
Thank you so much +rep. If u can, give me a hand at my other topic aswell.
 

T.s.e

Wish I was old and a little sentimental
Reaction score
133
> PolledWait is an "enhanced" TriggerSleepAction, open the blizzard.j to see how the function is made, basically it is just a loop with a TriggerSleepAction and a timer used.
And it also leaks a timer handle.
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
> PolledWait is an "enhanced" TriggerSleepAction, open the blizzard.j to see how the function is made, basically it is just a loop with a TriggerSleepAction and a timer used.
And it also leaks a timer handle.
That's why i used "", and it's still inaccurate, more than TriggerSleepAction alone (ofc if the game is not paused).
Btw i've heard that the wc3mapoptimizer replace PolledWait with PolledWait2 (better function made by Vexorian without the handle leak)
 

SFilip

Gone but not forgotten
Reaction score
634
> and it's still inaccurate, more than TriggerSleepAction alone
Regardless, PolledWait should always be used instead of TriggerSleepAction. The inaccuracy doesn't matter that much as you generally shouldn't use it for waits shorter than 10 seconds anyway. Actually, it is recommended to use timers whenever possible.
 

Troll-Brain

You can change this now in User CP.
Reaction score
85
I know that, next time i will write all the facts and all people will be happy.
PolledWait is a better option, because a timer is paused when the game is paused, but a TriggerSleepAction isn't. (You know it but you didn't said why he shoud use PolledWait instead of TriggerSleepAction)
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top