• 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.

Selection/Deselection/Selection

Status
Not open for further replies.
Level 15
Joined
Nov 30, 2007
Messages
1,202
How to carry over the following boolean.

Player selects unit of type A (1). Set b = true,

player selection unit of type A (2) b should still be true.

the proble is that between every selection and new selection there is a deselection event that "cleans up everything" and I want it to not do that when a player selects from a unit of type A to another

The reason is that I want to reuse some information that was created at the first selection.

Or actually never mind - I don't need to clean up the information between selections (deselection), only clean up the bad information when re-selected.
 
Level 12
Joined
Nov 3, 2013
Messages
989
I don't really get what you're trying to do besides saving some boolean.

the generic event - unit is selected give both trigger unit and trigger player

with unit group you can take a player and have a unit group of all units currently selected by player.

Even if it didn't answered your question this can maybe help you.
 
Level 12
Joined
Nov 3, 2013
Messages
989
I think you can make a unit group for each player, every time they select their city remove all units in the unit group and then make new ones and add them to the unit group

something like this i guess

  • Untitled Trigger 002
    • Events
      • Player - Player 1 (Red) Selects a unit
      • Player - Player 2 (Blue) Selects a unit
      • ETC
    • Conditions
    • Actions
      • set player = (triggering player)
      • set unit = (triggering unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of unit) Equal to City
          • (Owner of unit) Equal to player
        • Then - Actions
          • Unit Group - Pick every unit in unitgroup[player number]) and do (Actions)
            • Loop - Actions
              • Unit - Remove (Picked unit) from the game
          • Unit - Create 1 Footman for player at (Center of (Playable map area)) facing Default building facing degrees
          • Unit Group - add (Last Created unit) to unitgroup[player number]
        • Else - Actions
if a player can have more than one city you just make MUI unit groups instead of MPI unit groups
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
I think you can make a unit group for each player, every time they select their city remove all units in the unit group and then make new ones and add them to the unit group

something like this i guess

  • Untitled Trigger 002
    • Events
      • Player - Player 1 (Red) Selects a unit
      • Player - Player 2 (Blue) Selects a unit
      • ETC
    • Conditions
    • Actions
      • set player = (triggering player)
      • set unit = (triggering unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of unit) Equal to City
          • (Owner of unit) Equal to player
        • Then - Actions
          • Unit Group - Pick every unit in unitgroup[player number]) and do (Actions)
            • Loop - Actions
              • Unit - Remove (Picked unit) from the game
          • Unit - Create 1 Footman for player at (Center of (Playable map area)) facing Default building facing degrees
          • Unit Group - add (Last Created unit) to unitgroup[player number]
        • Else - Actions
if a player can have more than one city you just make MUI unit groups instead of MPI unit groups

Yes, I had that solution in mind - but it would seem to be extensive, to add say max 20 units remove 20 units add 20 units. When instead you could add 20, next city remove 5, etc. But if it isn't too bad to create/remove this amount of units on selection i guess it's fine?
 

Deleted member 219079

D

Deleted member 219079

If you wanna avoid using 12 unit groups you can use Table and PUI so use Custom Script - set myTable [GetPlayerId(GetTriggerPlayer())].boolean [GetUnitIndex(GetTriggerUnit())] = true

Alternatively you can use normal hashtable and filthy GUI unit indexer by bribe, in which case you can do:
  • myTrigger
    • Events
      • Player - Player 1 (Red) Selects a unit
    • Conditions
    • Actions
      • Hashtable - Save True as ((Player number of (Triggering player)) - 1) of (Custom value of (Triggering unit)) in myTable
  • myTrigger De
    • Events
      • Player - Player 1 (Red) Deselects a unit
    • Conditions
    • Actions
      • Hashtable - Save False as ((Player number of (Triggering player)) - 1) of (Custom value of (Triggering unit)) in myTable
 

Deleted member 219079

D

Deleted member 219079

@chobibo It indexes everything. Before I discovered PUI I thought Bribe's unit indexer was AWESOME, like, there'd be no better thing as that. I could now create my filthy GUI triggers with ease.

But then I discovered PUI, it indexes only the units I need it to index, it's much more efficient in my opinion.

I think OP is GUI user so I gave him a solution using GUI's unit indexer, it might be easier for him.

Edit: And no I'm not trying to insult the creator nor the GUI indexer, it was a joke D: I'd never have brains to create unit indexer myself!!


@Pinzu What about my solution? Link to GUI Unit Indexer: http://www.hiveworkshop.com/forums/spells-569/gui-unit-indexer-1-2-0-2-a-197329/
 
Level 15
Joined
Nov 30, 2007
Messages
1,202

I'm using that indexing system.

I was thinking of having a unit variable and then adding/removing based on the first boolean.

TechType[0] = 'A000'
TechType[1] = A001'

altought i think my formula is wrong. xD


JASS:
loop 
    exitwhen TechType[i] == null
    if (SOME TECH CONDITON == true and TechUnit[i + pID*12] == null) then
         set TechUnit[i + pID*12] = CreateUnit(Player(pID), TechType[i], 0,0,0)
    elseif (SOME TECH CONDITION == false and  TechUnit[i + pID*12] != null) then
        call UnitApplyTimedLife(u, xxxx, 0.1)
        set TechUnit[i + pID*12] = null    
    endif
    set i = i + 1
endloop
 

Deleted member 219079

D

Deleted member 219079

You don't declare pID anywhere.

Edit: or maybe you do, can you post the whole function?
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
You don't declare pID anywhere.

Edit: or maybe you do, can you post the whole function?

Obviously the constants should be replaced with TechType ands the ifs must be changed to match the types somehow...

Well it looks like this atm (haven't incorporated the last part):

JASS:
library Selection initializer init

globals
    unit array CurrentSelection
    unit array      TechUnit 
    integer array   TechType
endglobals 

private function Selection takes nothing returns boolean
    local boolean CityWasSelected = false
    local unit u = GetTriggerUnit()
    local player owner = GetOwningPlayer(u) 
    local player clicker = GetTriggerPlayer()
    local integer pID = GetPlayerId(clicker) 
    local integer i = 0 
    local real x
    local real y
    local integer array b_count
    
    loop
        exitwhen CityType[i] == null
        if (GetUnitTypeId(u) == CityType[i]) then
            set CityWasSelected = true
        endif
        set i = i + 1
    endloop
    
    if (CityWasSelected == true) then
        if (owner == clicker) then
            set x = GetUnitX(u)
            set y = GetUnitY(u) 
            set CurrentSelection[pID] = u
            call SetUnitPosition(CityController[pID],x,y)
            call ShowUnit(CityController[pID], true) 
            if (GetLocalPlayer() == clicker) then 
                call ClearSelection()
                call SelectUnit(CityController[pID], true) 
            endif
            call SetUnitPosition(CityController[pID],x,y)
            call ShowUnit(CityController[pID], true)
            set i = 0
            loop
                exitwhen Building_order[i] == null 
                set b_count[i] = CountBuildings(GetUnitUserData(u), i)
                set i = i + 1
            endloop
            
            // TECH-TREE // OLD 
            // instead of (u) use TechUnit[formula]
            if (b_count[6] > 0 and u == null) then
                set u = CreateUnit(clicker, HOUSE_1_TECH, 0,0,0) 
            elseif (b_count[6] = 0 and u != null) then
                call UnitApplyTimedLife(u,'BTLF', 0.1)
                set u = null 
            endif
            if (b_count[4] > 1) then
                set u = CreateUnit(clicker, HOUSE_2_TECH, 0,0,0) 
            endif
            if (b_count[4] > 2) then
                set u = CreateUnit(clicker, HOUSE_3_TECH, 0,0,0) 
            endif
            if (b_count[4] > 3) then
                set u = CreateUnit(clicker, HOUSE_4_TECH, 0,0,0) 
            endif
            if (b_count[6] > 0) then
                set u = CreateUnit(clicker, WELL_TECH, 0,0,0) 
            endif
            if (b_count[7] > 0) then
                set u = CreateUnit(clicker, GRANARY_TECH, 0,0,0)
            endif
    
    // House      
    // Granary 6
    // Well 7
            
            
            
        endif
    endif 
    

    
    return false 
endfunction

//===========================================================================
private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterPlayerSelectionEventBJ( t, Player(0), true )
    call TriggerRegisterPlayerSelectionEventBJ( t, Player(1), true )
    call TriggerRegisterPlayerSelectionEventBJ( t, Player(2), true )
    call TriggerRegisterPlayerSelectionEventBJ( t, Player(3), true )
    call TriggerRegisterPlayerSelectionEventBJ( t, Player(4), true )
    call TriggerRegisterPlayerSelectionEventBJ( t, Player(5), true )
    call TriggerRegisterPlayerSelectionEventBJ( t, Player(6), true )
    call TriggerRegisterPlayerSelectionEventBJ( t, Player(7), true )
    call TriggerRegisterPlayerSelectionEventBJ( t, Player(8), true )
    call TriggerRegisterPlayerSelectionEventBJ( t, Player(9), true )
    call TriggerRegisterPlayerSelectionEventBJ( t, Player(10), true )
    call TriggerRegisterPlayerSelectionEventBJ( t, Player(11), true )
    call TriggerAddCondition( t, Condition( function Selection) )
    set t = null
    
    set TechType[0]     = 'n002'    // WELL_TECH
    set TechType[1]     = 'n003'    // GRANARY_TECH
    set TechType[2]     = 'n004'    // HOUSE_1_TECH
    set TechType[3]     = 'n005'    // HOUSE_2_TECH
    set TechType[4]     = 'n006'    // HOUSE_3_TECH
    set TechType[5]     = 'n00D'    // HOUSE_4_TECH
    set TechType[6]     = 'n008'    // AGORA_TECH
    set TechType[7]     = 'n00C'    // BARRACK_TECH
    set TechType[8]     = 'n001'    // ARCHERY_RANGE_TECH
    set TechType[9]     = 'n00A'    // STABLE_TECH
    set TechType[9]     = 'n009'    // BLACKSMITH_TECH
    set TechType[10]    = 'n007'    // TEMPLE TECH
endfunction

endlibrary

The formula would be: TechUnit[TechInt + (TechIntMax+1)*pID]
 
Last edited:

Deleted member 219079

D

Deleted member 219079

Change your init to this:
JASS:
private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer p = 0
    loop
        call TriggerRegisterPlayerUnitEvent(t, Player(p), EVENT_PLAYER_UNIT_SELECTED, null /*Filter(function InCaseYouWantFilter)*/)
        exitwhen p == 11
        set p = p + 1
    endloop
    call TriggerAddCondition( t, Condition( function Selection) )
    set t = null
endfunction
You could filter out unwanted selections in the event declaration with a filter.

Also here:
set b_count[i] = CountBuildings(GetUnitUserData(u), i) , are you sure you didn't mean GetUnitTypeId(u) instead of UserData?


And since your problem was deselection cleaning up everything, why don't you just use PUI and Table, add private TableArray SELECTED to your globals, add set SELECTED = TableArray [12] to your init, and declare whether unit was selected via:
set SELECTED [pID].boolean [GetUnitIndex(whichUnit)] = selectedOrNot

This way you can check if your selection was already done with this:
if (owner == clicker) and not SELECTED[GetPlayerId(owner)].boolean [GetUnitIndex(u)] then

Then in the block declare it to be true afterwards?
 

Deleted member 219079

D

Deleted member 219079

Use GetFilterUnit()

Edit: And it must return boolean
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
I changed the code to its bare bones. Basically I want to not display "DESELECTED" when you select of same type, or select same unit. Do I need a 0.1 timer for that?

JASS:
library Selection initializer init

globals
    unit array curSelected
    unit array lastSelected
endglobals

private function s_filter takes nothing returns boolean
    local unit u = GetFilterUnit() 
    if (IsUnitCityType(u) == true) then
        set u = null
        return true
    endif
    set u = null
    return false
endfunction

private function d_filter takes nothing returns boolean
    return true 
endfunction 

private function main takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local integer pID = GetPlayerId(GetTriggerPlayer())
    local integer owner = GetPlayerId(GetOwningPlayer(u)) 
    local integer i
    local real x
    local real y
    
    
    if (GetTriggerEventId() == EVENT_PLAYER_UNIT_SELECTED) then
        call BJDebugMsg("Selected")
        set curSelected[pID] = u 
        if (curSelected[pID] == lastSelected[pID]) then
            call BJDebugMsg("DONT RUN DESELCT! Cur = Last")
        elseif (IsUnitCityType(curSelected[pID]) == true and IsUnitCityType(lastSelected[pID]) == true) then
            call BJDebugMsg("DONT RUN DESELCT! You clicked same type!")
            set lastSelected[pID] = curSelected[pID]
        else
            set lastSelected[pID] = curSelected[pID]
        endif
    
    else // EVENT_PLAYER_UNIT_DESELECTED 
        set lastSelected[pID] = curSelected[pID]
        set curSelected[pID] = null
        call BJDebugMsg("Deselected")
    
    
    endif

    return false
endfunction

//===========================================================================
private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer p = 0
    loop
        exitwhen p > 11
        call TriggerRegisterPlayerUnitEvent(t, Player(p), EVENT_PLAYER_UNIT_SELECTED, Filter(function s_filter))
        call TriggerRegisterPlayerUnitEvent(t, Player(p), EVENT_PLAYER_UNIT_DESELECTED, Filter(function d_filter))
        set p = p + 1
    endloop
    call TriggerAddCondition( t, Condition( function main) )
    set t = null
endfunction

endlibrary
 

Deleted member 219079

D

Deleted member 219079

So basically what part of it is not working atm? What you want to fix?
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
Just comment them out...
JASS:
library Selection initializer init

globals
    unit array curSelected
    unit array lastSelected
endglobals

private function s_filter takes nothing returns boolean
    local unit u = GetFilterUnit()
    if (IsUnitCityType(u) == true) then
        set u = null
        return true
    endif
    set u = null
    return false
endfunction

private function d_filter takes nothing returns boolean
    return true
endfunction

private function main takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local integer pID = GetPlayerId(GetTriggerPlayer())
    local integer owner = GetPlayerId(GetOwningPlayer(u))
    local integer i
    local real x
    local real y
   
   
    if (GetTriggerEventId() == EVENT_PLAYER_UNIT_SELECTED) then
       // call BJDebugMsg("Selected")
        set curSelected[pID] = u
        if (curSelected[pID] == lastSelected[pID]) then
            //call BJDebugMsg("DONT RUN DESELCT! Cur = Last")
        elseif (IsUnitCityType(curSelected[pID]) == true and IsUnitCityType(lastSelected[pID]) == true) then
            //call BJDebugMsg("DONT RUN DESELCT! You clicked same type!")
            set lastSelected[pID] = curSelected[pID]
        else
            set lastSelected[pID] = curSelected[pID]
        endif
   
    else // EVENT_PLAYER_UNIT_DESELECTED
        set lastSelected[pID] = curSelected[pID]
        set curSelected[pID] = null
        //call BJDebugMsg("Deselected")
   
   
    endif

    return false
endfunction
 

Deleted member 219079

D

Deleted member 219079

do
JASS:
if curSelected[pID] != lastSelected[pID] then
    call BJDebugMsg("Deselected")
endif[/icode]

Edit: yeah do as chobibo said, then it won't print it anymore
 
Level 15
Joined
Nov 30, 2007
Messages
1,202
No technically I need to do this, the messages are in fact unimportant. But, later it will carry significance.

i need to hide that message behind a if statement and some sort of timer to check if any of the two selection options happend or not.

The part that doesn't work even though anything else runs is the part after SleepAction.

JASS:
library Selection initializer init

globals
    unit array curSelected
    private unit array lastSelected
endglobals

private function s_filter takes nothing returns boolean
    local unit u = GetFilterUnit() 
    if (IsUnitCityType(u) == true) then
        return true
    endif
    return false 
endfunction

private function d_filter takes nothing returns boolean
    local unit u = GetFilterUnit()
    local integer i = 0
    loop
        exitwhen i>11
        if (CityController[i] == u) then
            return true
        endif
        set i = i + 1
    endloop
    return false 
endfunction 

private function main takes nothing returns boolean
    local unit u = GetTriggerUnit()
    local integer pID = GetPlayerId(GetTriggerPlayer())
    local integer owner = GetPlayerId(GetOwningPlayer(u)) 
    local integer i = 0 
    local real x
    local real y
    
    
    if (GetTriggerEventId() == EVENT_PLAYER_UNIT_SELECTED) then
        set x = GetUnitX(u)
        set y = GetUnitY(u)
        set curSelected[pID] = u 
        call BJDebugMsg("IS THIS RUNNING?")
        set curSelected[pID] = u 
        if (curSelected[pID] == lastSelected[pID]) then
            call BJDebugMsg("Cur = Last")
        elseif (IsUnitCityType(curSelected[pID]) == true and IsUnitCityType(lastSelected[pID]) == true) then
            call BJDebugMsg("You clicked same type!")
            set lastSelected[pID] = curSelected[pID]
            call SetUnitPosition(CityController[pID],x,y)
        else
            set lastSelected[pID] = curSelected[pID]
            call BJDebugMsg(GetUnitName(u) + " first selection")
            call SetUnitPosition(CityController[pID],x,y)
            call ShowUnit(CityController[pID], true) 
            if (GetLocalPlayer() == Player(pID)) then 
                call ClearSelection()
                call SelectUnit(CityController[pID], true) 
            endif
        endif
    
    else // EVENT_PLAYER_UNIT_DESELECTED 
        
        set lastSelected[pID] = curSelected[pID]
        set curSelected[pID] = null
        call BJDebugMsg("okey.. you deselected all above units..")
        call TriggerSleepAction(0.1) 
        if (curSelected[pID] == null) then // <<--- THIS IS NOT RUNNING
            set lastSelected[pID] = null
            call BJDebugMsg(GetUnitName(u) + " was deselected...")
            call ShowUnit(CityController[pID], false) 
        endif
    
    endif

    return false
endfunction

//===========================================================================
private function init takes nothing returns nothing
    local trigger t = CreateTrigger()
    local integer p = 0
    loop
        exitwhen p > 11
        call TriggerRegisterPlayerUnitEvent(t, Player(p), EVENT_PLAYER_UNIT_SELECTED, Filter(function s_filter))
        call TriggerRegisterPlayerUnitEvent(t, Player(p), EVENT_PLAYER_UNIT_DESELECTED, Filter(function d_filter))
        set p = p + 1
    endloop
    call TriggerAddCondition( t, Condition( function main) )
    set t = null
endfunction

endlibrary
 
Last edited:
Level 15
Joined
Nov 30, 2007
Messages
1,202
JASS:
    call TriggerSleepAction(0.1)
set lastSelected[pID] = curSelected[pID]
        set curSelected[pID] = null
        call BJDebugMsg("okey.. you deselected all above units..")
        call TriggerSleepAction(0.1) 
        if (curSelected[pID] == null) then // <<--- THIS IS NOT RUNNING
            set lastSelected[pID] = null
            call BJDebugMsg(GetUnitName(u) + " was deselected...")
            call ShowUnit(CityController[pID], false) 
        endif
 
Level 22
Joined
Sep 24, 2005
Messages
4,821
That's because TriggerSleepActions don't work inside triggerconditions; If you need waits, use triggeractions instead.

JASS:
//return false
...
//call TriggerAddCondition( t, Condition( function main) )
call TriggerAddAction( t, Condition( function main) )
 
Status
Not open for further replies.
Top