• Check out the results of the Techtree Contest #19!
  • Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

Is GetUnitsSelectedAll(<player>) asynchronous ?

Status
Not open for further replies.
Hello,

I made the following trigger (I use damage engine, the final purpose is to use healing potion automatically to save the hero under some conditions).

  • AutoPotionOfGreaterHealing
    • Events
      • Game - DamageEvent becomes Equal to 1.00
    • Conditions
      • ((Owner of DamageEventTarget) is in ConnectedPlayers.) Equal to True
      • (DamageEventTarget is A Hero) Equal to True
      • (DamageEventTarget is paused) Equal to False
      • (DamageEventTarget has an item of type Potion of Greater Healing) Equal to True
      • DamageEventAmount Greater than or equal to (Life of DamageEventTarget)
    • Actions
      • Custom script: local unit udg_LocalTempUnit = udg_DamageEventTarget
      • Custom script: local player udg_LocalTempPlayer = GetOwningPlayer(udg_LocalTempUnit)
      • Custom script: local group udg_LocalTempGroup
      • -------- Check if player selection is shop(s) --------
      • // Set VariableSet LocalTempGroup = (Units currently selected by LocalTempPlayer) // Would execute right and save from death
      • Set VariableSet LocalTempGroup = (Units currently selected by LocalTempPlayer)
      • Hero - Order LocalTempUnit to use (Item carried by LocalTempUnit of type Potion of Greater Healing) // Would not save the unit from death ???
      • [...] // Other unrelevant code for this post
      • Custom script: call DestroyGroup(udg_LocalTempGroup)
      • Custom script: set udg_LocalTempGroup = null
      • Custom script: set udg_LocalTempPlayer = null
      • Custom script: set udg_LocalTempUnit = null
What is akward is that:
- "Hero - Order Hero <> to use item <>" works fine and saves the unit from dying if I place it before the line "Set VariableSet LocalTempGroup = (Units currently selected by LocalTempPlayer)".
- In the opposite, if I place it after this line, the unit dies.

WTF ???
Is GetUnitsSelectedAll primitive actually asynchronous, with a hidden wait somewhere in its code ??
 
(Units currently selected by X) is slow af and, IIRC, hangs the thread until it synchronizes selection among players. You'd better off creating a constant unit group for each possible player and add/remove units with the selection events.

Oh it is the "syncselections()" thing ?
It pauses the thread, synchronize over network, then resume the thread ?

If I listen select/unselect events & register 1 unit-group per player for selected units, theoretically I won't have desync issues in multi-player games ?


Tracking myself selected/unselected units would be a bit bothersome, since I've to track all those events: player X selects a unit, player X unselects a unit, unit is removed (deindexed) ?

And maybe (if they don't fire a unselect event): unit dies, unit acquires ability Aloc, unit is hidden..
 
Last edited:
Oh it is the "syncselections()" thing ?
It pauses the thread, synchronize over network, then resume the thread ?
Yes.

If I listen select/unselect events & register 1 unit-group per player for selected units, theoretically I won't have desync issues in multi-player games ?
Correct, as those events are already synchronized.

Tracking myself selected/unselected units would be a bit bothersome, since I've to track all those events: player X selects a unit, player X unselects a unit, unit is removed (deindexed) ?
I don't think this part is difficult at all because once a unit is removed/dies/hides, the events fire as they should.
 
Mhh with Bribe's "Unit Event" system (including "Unit in Action") I can do this vjass system then:

JASS:
library UnitSelection

    globals
        private trigger playerSelectUnitTrigger
        private trigger playerDeselectUnitTrigger
        private trigger unitInactionTrigger
    endglobals

    function onPlayerSelectUnit takes nothing returns boolean
        local player p = GetTriggerPlayer()
        local integer pIndex = GetConvertedPlayerId(p)
        local unit u = GetTriggerUnit()
        local boolean b = IsUnitInGroup(u, udg_Selections[pIndex])
        if (not b) then
            call GroupAddUnitSimple(u, udg_Selections[pIndex])

            // Fire a unit selection event
            set udg_UnitSelectionPlayerId = pIndex
            set udg_UnitSelectionEvent = 0.00
            set udg_UnitSelectionEvent = 1.00
            set udg_UnitSelectionEvent = 0.00
            set udg_UnitSelectionPlayerId = 0
        endif
        set u = null
        set p = null
        return false
    endfunction

    function onPlayerDeselectUnit takes nothing returns boolean
        local player p = GetTriggerPlayer()
        local integer pIndex = GetConvertedPlayerId(p)
        local unit u = GetTriggerUnit()
        local boolean b = IsUnitInGroup(u, udg_Selections[pIndex])
        if (b) then
            call GroupRemoveUnitSimple(u, udg_Selections[pIndex])

            // Fire a unit deselection event
            set udg_UnitSelectionPlayerId = pIndex
            set udg_UnitSelectionEvent = 0.00
            set udg_UnitSelectionEvent = 2.00
            set udg_UnitSelectionEvent = 0.00
            set udg_UnitSelectionPlayerId = 0
        endif
        set u = null
        set p = null
        return false
    endfunction

    function onUnitInaction takes nothing returns boolean
        local integer pIndex
        local integer pCount = GetPlayers()
        local unit u = udg_UDexUnits[udg_UDex]
        local boolean b
        set pIndex = 1
        loop
            set b = IsUnitInGroup(u, udg_Selections[pIndex])
            if (b) then
                call GroupRemoveUnitSimple(u, udg_Selections[pIndex])
                // Fire a unit deselection event
                set udg_UnitSelectionPlayerId = pIndex
                set udg_UnitSelectionEvent = 0.00
                set udg_UnitSelectionEvent = 2.00
                set udg_UnitSelectionEvent = 0.00
                set udg_UnitSelectionPlayerId = 0
            endif
            set pIndex = pIndex + 1
            exitwhen pIndex > pCount
        endloop
        set u = null
        return false
    endfunction

    // ----------------------------------------------------------------------------
    // onInit: system initializer
    // ----------------------------------------------------------------------------
    private module M
        private static method onInit takes nothing returns nothing
            local integer index
            local integer playerCount = GetPlayers()
            set playerSelectUnitTrigger = CreateTrigger()
            set playerDeselectUnitTrigger = CreateTrigger()
            set unitInactionTrigger = CreateTrigger()

            set index = 1
            loop
                set udg_Selections[index] = CreateGroup()
                call TriggerRegisterPlayerSelectionEventBJ( playerSelectUnitTrigger, ConvertedPlayer(index), true )
                call TriggerRegisterPlayerSelectionEventBJ( playerDeselectUnitTrigger, ConvertedPlayer(index), false )
                set index = index + 1
                exitwhen index > playerCount
            endloop
            call TriggerRegisterVariableEvent( unitInactionTrigger, "udg_UnitInActionEvent", EQUAL, 2.00 )

            call TriggerAddCondition(playerSelectUnitTrigger, Condition(function onPlayerSelectUnit))
            call TriggerAddCondition(playerDeselectUnitTrigger, Condition(function onPlayerDeselectUnit))
            call TriggerAddCondition(unitInactionTrigger, Condition(function onUnitInaction))
        endmethod
    endmodule
    private struct S extends array
        implement M
    endstruct

endlibrary
 
Status
Not open for further replies.
Back
Top