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

Hi guys , how can I check if entire map no player 2 unit , player 1 win

Status
Not open for further replies.
Level 6
Joined
Mar 9, 2009
Messages
175
Hi guys , how can I check if entire map no player 2 unit , player 1 and other play that same allied with player 1 win too.

Hey guy I need your help here

Thank you !
 
Level 6
Joined
Mar 9, 2009
Messages
175
i mean if the entire map there are no player 2 unit left then action player 1 victory . Not the one no "Town Hall" then lose . My one is no unit left doesn't need Town Hall .
 
Level 9
Joined
Nov 19, 2011
Messages
516
Just like you said.

  • Win
  • Events
    • Unit - A Unit owned by player(2) died.
  • Conditions
  • Actions
    • Unit Group - Pick evry unit that belongs to player(2) at Playable map area and do (acctions)
      • If picked unit is alive = true then
        • Actions
          • Skip remaining acctions.
        • else (actions)
          • Do Nothing
    • Game - Set Player 1 victory
    • Game - Set Player 2 deffeat
And of course remove win/loose conditions from melee initialization.
 
Last edited:
Level 14
Joined
Apr 20, 2009
Messages
1,543
Just like you said.

  • Win
    • Events
      • Unit - A Unit owned by player(2) died.
    • Conditions
    • Actions
      • Unit Group - Pick evry unit that belongs to player(2) at Playable map area and do (acctions)
      • If picked unit is alive = true then
      • Actions
      • Skip remaining acctions.
    • else (actions)
      • Do Nothing
    • Game - Set Player 1 victory
    • Game - Set Player 2 deffeat
And of course remove win/loose conditions from melee initialization.

I guess this is the GUI trigger your looking for:

  • Win
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Owner of (Triggering unit)) Equal to Player 2 (Blue)
    • Actions
      • Unit Group - Pick every unit in (Units in (Playable map area) owned by Player 2 (Blue)) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) is alive) Equal to True
            • Then - Actions
              • Skip remaining actions
            • Else - Actions
              • Do nothing
          • Game - Victory Player 1 (Red) (Show dialogs, Show scores)
          • Game - Defeat Player 2 (Blue) with the message: Defeat!
This trigger contains a LOT of BJ's...

Here is the converted Jass script:

JASS:
function Trig_Win_Conditions takes nothing returns boolean
    if ( not ( GetOwningPlayer(GetTriggerUnit()) == Player(1) ) ) then
        return false
    endif
    return true
endfunction

function Trig_Win_Func003Func001C takes nothing returns boolean
    if ( not ( IsUnitAliveBJ(GetEnumUnit()) == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_Win_Func003A takes nothing returns nothing
    if ( Trig_Win_Func003Func001C() ) then
        return
    else
        call DoNothing(  )
    endif
    call CustomVictoryBJ( Player(0), true, true )
    call CustomDefeatBJ( Player(1), "TRIGSTR_001" )
endfunction

function Trig_Win_Actions takes nothing returns nothing
    call ForGroupBJ( GetUnitsInRectOfPlayer(GetPlayableMapRect(), Player(1)), function Trig_Win_Func003A )
endfunction

//===========================================================================
function InitTrig_Win takes nothing returns nothing
    set gg_trg_Win = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Win, EVENT_PLAYER_UNIT_DEATH )
    call TriggerAddCondition( gg_trg_Win, Condition( function Trig_Win_Conditions ) )
    call TriggerAddAction( gg_trg_Win, function Trig_Win_Actions )
endfunction

Do nothing does nothing. Why execute a function that does nothing, better don't execute a function at all?

IsUnitAliveBJ calls IsUnitDeadBJ which calls GetUnitState, so why not call GetUnitState immediatly? That's the reason why I hate BJ's -,-

Ow well, I guess that's GUI... >.>

Here is a more optimized Jass version of it:

JASS:
function Trig_Win_Actions takes nothing returns nothing
    local unit u
    local group g
    local integer i
    set i = 0
    call GroupEnumUnitsOfPlayer(g, Player(1), null)
    loop
        set u = FirstOfGroup(g)
        exitwhen u == null
        if (GetUnitState(u, UNIT_STATE_LIFE) > 0)   then
            set i = i + 1
        endif
        call GroupRemoveUnit(g, u)
    endloop
    if i == 0 then
        call CustomVictoryBJ( Player(0), true, true )
        call CustomDefeatBJ( Player(1), "Defeat!" ) 
    endif
    call DestroyGroup(g)
    set g = null
    set u = null
endfunction

//===========================================================================
function InitTrig_Win takes nothing returns nothing
    local trigger T = CreateTrigger()
    call TriggerRegisterPlayerUnitEvent(T, Player(1), EVENT_PLAYER_UNIT_DEATH, null)
    call TriggerAddAction( T, function Trig_Win_Actions )
    set T = null
endfunction

I didn't optimize CustomVictoryBJ and CustomDefeatBJ, because I have no idea how to optimize this without adding TONS of script.

Isn't there an easier way then writing all this out:
JASS:
function CustomVictoryBJ takes player whichPlayer, boolean showDialog, boolean showScores returns nothing
    if AllowVictoryDefeat( PLAYER_GAME_RESULT_VICTORY ) then
        call RemovePlayer( whichPlayer, PLAYER_GAME_RESULT_VICTORY )

        if not bj_isSinglePlayer then
            call DisplayTimedTextFromPlayer(whichPlayer, 0, 0, 60, GetLocalizedString( "PLAYER_VICTORIOUS" ) )
        endif

        // UI only needs to be displayed to users.
        if (GetPlayerController(whichPlayer) == MAP_CONTROL_USER) then
            set bj_changeLevelShowScores = showScores
            if showDialog then
                call CustomVictoryDialogBJ( whichPlayer )
            else
                call CustomVictorySkipBJ( whichPlayer )
            endif
        endif
    endif
endfunction

function AllowVictoryDefeat takes playergameresult gameResult returns boolean
    if (gameResult == PLAYER_GAME_RESULT_VICTORY) then
        return not IsNoVictoryCheat()
    endif
    if (gameResult == PLAYER_GAME_RESULT_DEFEAT) then
        return not IsNoDefeatCheat()
    endif
    if (gameResult == PLAYER_GAME_RESULT_NEUTRAL) then
        return (not IsNoVictoryCheat()) and (not IsNoDefeatCheat())
    endif
    return true
endfunction

function CustomVictoryDialogBJ takes player whichPlayer returns nothing
    local trigger t = CreateTrigger()
    local dialog  d = DialogCreate()

    call DialogSetMessage( d, GetLocalizedString( "GAMEOVER_VICTORY_MSG" ) )

    set t = CreateTrigger()
    call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_CONTINUE" ), GetLocalizedHotkey("GAMEOVER_CONTINUE") ) )
    call TriggerAddAction( t, function CustomVictoryOkBJ )

    set t = CreateTrigger()
    call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_QUIT_MISSION" ), GetLocalizedHotkey("GAMEOVER_QUIT_MISSION") ) )
    call TriggerAddAction( t, function CustomVictoryQuitBJ )

    if (GetLocalPlayer() == whichPlayer) then
        call EnableUserControl( true )
        if bj_isSinglePlayer then
            call PauseGame( true )
        endif
        call EnableUserUI(false)
    endif

    call DialogDisplay( whichPlayer, d, true )
    call VolumeGroupSetVolumeForPlayerBJ( whichPlayer, SOUND_VOLUMEGROUP_UI, 1.0 )
    call StartSoundForPlayerBJ( whichPlayer, bj_victoryDialogSound )
endfunction

function CustomVictoryOkBJ takes nothing returns nothing
    if bj_isSinglePlayer then
        call PauseGame( false )
        // Bump the difficulty back up to the default.
        call SetGameDifficulty(GetDefaultDifficulty())
    endif

    if (bj_changeLevelMapName == null) then
        call EndGame( bj_changeLevelShowScores )
    else
        call ChangeLevel( bj_changeLevelMapName, bj_changeLevelShowScores )
    endif
endfunction

function CustomVictoryQuitBJ takes nothing returns nothing
    if bj_isSinglePlayer then
        call PauseGame( false )
        // Bump the difficulty back up to the default.
        call SetGameDifficulty(GetDefaultDifficulty())
    endif

    call EndGame( bj_changeLevelShowScores )
endfunction

function VolumeGroupSetVolumeForPlayerBJ takes player whichPlayer, volumegroup vgroup, real scale returns nothing
    if (GetLocalPlayer() == whichPlayer) then
        call VolumeGroupSetVolume(vgroup, scale)
    endif
endfunction

function StartSoundForPlayerBJ takes player whichPlayer, sound soundHandle returns nothing
    if (whichPlayer == GetLocalPlayer()) then
        call StartSound(soundHandle)
    endif
endfunction

function CustomVictorySkipBJ takes player whichPlayer returns nothing
    if (GetLocalPlayer() == whichPlayer) then
        if bj_isSinglePlayer then
            // Bump the difficulty back up to the default.
            call SetGameDifficulty(GetDefaultDifficulty())
        endif

        if (bj_changeLevelMapName == null) then
            call EndGame( bj_changeLevelShowScores )
        else
            call ChangeLevel( bj_changeLevelMapName, bj_changeLevelShowScores )
        endif
    endif
endfunction

Now that's a good example of what 1 BJ called CustomVictoryBJ does behind the scenes...
Look at that enormous list of function calls :p!
The same amount of code gets executed for CustomDefeatBJ...

For the GUI users out there:

This:
  • Game - Victory Player 1 (Red) (Show dialogs, Show scores)
Is the same as this:
JASS:
function CustomVictoryBJ takes player whichPlayer, boolean showDialog, boolean showScores returns nothing
    if AllowVictoryDefeat( PLAYER_GAME_RESULT_VICTORY ) then
        call RemovePlayer( whichPlayer, PLAYER_GAME_RESULT_VICTORY )

        if not bj_isSinglePlayer then
            call DisplayTimedTextFromPlayer(whichPlayer, 0, 0, 60, GetLocalizedString( "PLAYER_VICTORIOUS" ) )
        endif

        // UI only needs to be displayed to users.
        if (GetPlayerController(whichPlayer) == MAP_CONTROL_USER) then
            set bj_changeLevelShowScores = showScores
            if showDialog then
                call CustomVictoryDialogBJ( whichPlayer )
            else
                call CustomVictorySkipBJ( whichPlayer )
            endif
        endif
    endif
endfunction

function AllowVictoryDefeat takes playergameresult gameResult returns boolean
    if (gameResult == PLAYER_GAME_RESULT_VICTORY) then
        return not IsNoVictoryCheat()
    endif
    if (gameResult == PLAYER_GAME_RESULT_DEFEAT) then
        return not IsNoDefeatCheat()
    endif
    if (gameResult == PLAYER_GAME_RESULT_NEUTRAL) then
        return (not IsNoVictoryCheat()) and (not IsNoDefeatCheat())
    endif
    return true
endfunction

function CustomVictoryDialogBJ takes player whichPlayer returns nothing
    local trigger t = CreateTrigger()
    local dialog  d = DialogCreate()

    call DialogSetMessage( d, GetLocalizedString( "GAMEOVER_VICTORY_MSG" ) )

    set t = CreateTrigger()
    call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_CONTINUE" ), GetLocalizedHotkey("GAMEOVER_CONTINUE") ) )
    call TriggerAddAction( t, function CustomVictoryOkBJ )

    set t = CreateTrigger()
    call TriggerRegisterDialogButtonEvent( t, DialogAddButton( d, GetLocalizedString( "GAMEOVER_QUIT_MISSION" ), GetLocalizedHotkey("GAMEOVER_QUIT_MISSION") ) )
    call TriggerAddAction( t, function CustomVictoryQuitBJ )

    if (GetLocalPlayer() == whichPlayer) then
        call EnableUserControl( true )
        if bj_isSinglePlayer then
            call PauseGame( true )
        endif
        call EnableUserUI(false)
    endif

    call DialogDisplay( whichPlayer, d, true )
    call VolumeGroupSetVolumeForPlayerBJ( whichPlayer, SOUND_VOLUMEGROUP_UI, 1.0 )
    call StartSoundForPlayerBJ( whichPlayer, bj_victoryDialogSound )
endfunction

function CustomVictoryOkBJ takes nothing returns nothing
    if bj_isSinglePlayer then
        call PauseGame( false )
        // Bump the difficulty back up to the default.
        call SetGameDifficulty(GetDefaultDifficulty())
    endif

    if (bj_changeLevelMapName == null) then
        call EndGame( bj_changeLevelShowScores )
    else
        call ChangeLevel( bj_changeLevelMapName, bj_changeLevelShowScores )
    endif
endfunction

function CustomVictoryQuitBJ takes nothing returns nothing
    if bj_isSinglePlayer then
        call PauseGame( false )
        // Bump the difficulty back up to the default.
        call SetGameDifficulty(GetDefaultDifficulty())
    endif

    call EndGame( bj_changeLevelShowScores )
endfunction

function VolumeGroupSetVolumeForPlayerBJ takes player whichPlayer, volumegroup vgroup, real scale returns nothing
    if (GetLocalPlayer() == whichPlayer) then
        call VolumeGroupSetVolume(vgroup, scale)
    endif
endfunction

function StartSoundForPlayerBJ takes player whichPlayer, sound soundHandle returns nothing
    if (whichPlayer == GetLocalPlayer()) then
        call StartSound(soundHandle)
    endif
endfunction

function CustomVictorySkipBJ takes player whichPlayer returns nothing
    if (GetLocalPlayer() == whichPlayer) then
        if bj_isSinglePlayer then
            // Bump the difficulty back up to the default.
            call SetGameDifficulty(GetDefaultDifficulty())
        endif

        if (bj_changeLevelMapName == null) then
            call EndGame( bj_changeLevelShowScores )
        else
            call ChangeLevel( bj_changeLevelMapName, bj_changeLevelShowScores )
        endif
    endif
endfunction
 
Last edited:
Level 9
Joined
Nov 19, 2011
Messages
516
"Do Nothing" is there becouse I just wanted make him sure that I didn't missed something. Are sure that win/loose should be in loop? Won't be then with 1st picked dead unit win...?

  • Win
  • Events
    • Unit - A unit Dies
  • Conditions
    • (Owner of (Triggering unit)) Equal to Player 2 (Blue)
  • Actions
    • Unit Group - Pick every unit in (Units in (Playable map area) owned by Player 2 (Blue)) and do (Actions)
      • Loop - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Picked unit) is alive) Equal to True
        • Then - Actions
          • Skip remaining actions
        • Else - Actions
          • Do nothing
    • Game - Victory Player 1 (Red) (Show dialogs, Show scores)
    • Game - Defeat Player 2 (Blue) with the message: Defeat!
 
Here's an optimal version:

JASS:
function Trig_Win_A takes nothing returns boolean
    local unit u
    
    call GroupEnumUnitsOfPlayer(udg_tempGroup, Player(1), null)
    loop
        set u = FirstOfGroup(udg_tempGroup)
        exitwhen u == null
        
        if not IsUnitType(u, UNIT_TYPE_DEAD) then
            set u = null
            return false
        endif
        
        call GroupRemoveUnit(udg_tempGroup, u)
    endloop
    
    // Good luck inlining these >_>
    call CustomVictoryBJ(Player(0), true, true)
    call CustomDefeatBJ(Player(1), "Defeat!")
    
    return false
endfunction

function InitTrig_Win takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterPlayerUnitEvent(t, Player(1), EVENT_PLAYER_UNIT_DEATH, null)
    call TriggerAddCondition(t, function Trig_Win_A)
    set t = null
endfunction

I didn't inline those Victory/Defeat BJs because they're ugly.

To implement it, create a new trigger, convert it to custom text (Edit >> Convert to Custom Text) and paste this.
Then create a unit group variable (tempGroup) and you're done.
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
Here's an optimal version:

JASS:
function Trig_Win_A takes nothing returns boolean
    local unit u
    
    call GroupEnumUnitsOfPlayer(udg_tempGroup, Player(1), null)
    loop
        set u = FirstOfGroup(udg_tempGroup)
        exitwhen u == null
        
        if not IsUnitType(u, UNIT_TYPE_DEAD) then
            set u = null
            return false
        endif
        
        call GroupRemoveUnit(udg_tempGroup, u)
    endloop
    
    // Good luck inlining these >_>
    call CustomVictoryBJ(Player(0), true, true)
    call CustomDefeatBJ(Player(1), "Defeat!")
    
    return false
endfunction

function InitTrig_Win takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterPlayerUnitEvent(t, Player(1), EVENT_PLAYER_UNIT_DEATH, null)
    call TriggerAddCondition(t, function Trig_Win_A)
    set t = null
endfunction

I didn't inline those Victory/Defeat BJs because they're ugly.

To implement it, create a new trigger, convert it to custom text (Edit >> Convert to Custom Text) and paste this.
Then create a unit group variable (tempGroup) and you're done.

I see what you did there with the return :)
yesh that's better indeed -,^ thanks

Why a global temp group instead of local one though? does it matter that much?
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
Not to mention the fact that the GUI triggers provided did not work... Or atleast should not work as the return is not in the function you want to stop.

Alternativly you can keep track of the number of units the player owns that is alive in an integer. This is far more efficient than enumerating all units he owns every time a unit dies.
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
Not to mention the fact that the GUI triggers provided did not work... Or atleast should not work as the return is not in the function you want to stop.

Alternativly you can keep track of the number of units the player owns that is alive in an integer. This is far more efficient than enumerating all units he owns every time a unit dies.

How can you set an integer to the amount of units that are alive and owned by a player without enumerating the units of that player :S?

My first thoughts where: a periodic event in which the integer gets updated with the amount of units that are alive by that certain player,
but then it still needs to be enumerated in order to count the units owned by that player? :S

Or are you talking about updating the integer whenever a unit gets created or killed?
 

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,180
How can you set an integer to the amount of units that are alive and owned by a player without enumerating the units of that player :S?
1 enumeration for preplaced units.
Then add the units individually as they come into existance.
Remove the units from the counter when they die.

Be aware of stuff like resurrect which could mess up the count.
 
Level 23
Joined
Jan 1, 2011
Messages
1,504
Just take an indexer and when a unit is given a custom value add unit to a group, when unit is recycled remove unit from the group, have it check to see if the number of units in player 1's group is = 0 then victory the winning team.

I believe this is the most practical way to go about it.
(Most mappers need an indexer anyway)
 
Level 6
Joined
Mar 9, 2009
Messages
175
"Do Nothing" is there becouse I just wanted make him sure that I didn't missed something. Are sure that win/loose should be in loop? Won't be then with 1st picked dead unit win...?

  • Win
  • Events
    • Unit - A unit Dies
  • Conditions
    • (Owner of (Triggering unit)) Equal to Player 2 (Blue)
  • Actions
    • Unit Group - Pick every unit in (Units in (Playable map area) owned by Player 2 (Blue)) and do (Actions)
      • Loop - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ((Picked unit) is alive) Equal to True
        • Then - Actions
          • Skip remaining actions
        • Else - Actions
          • Do nothing
    • Game - Victory Player 1 (Red) (Show dialogs, Show scores)
    • Game - Defeat Player 2 (Blue) with the message: Defeat!

Can I change to every second to check if there is no unit left ??
 
Level 14
Joined
Apr 20, 2009
Messages
1,543
Can I change to every second to check if there is no unit left ??

Check Dr Super Good's Post

1 enumeration for preplaced units.
Then add the units individually as they come into existance.
Remove the units from the counter when they die.

Be aware of stuff like resurrect which could mess up the count.

So basically what you need to do here is create an integer variable and a trigger that at 0.00 seconds of game time picks all the units that are owned by player 2.
(This is so that all the pre-placed units that are put inside your game get picked and added to the integer that your going to use to check if a player has no alive units left)

Then for each unit that is picked the integer should be increased by one. Then in the other triggers that you use for creating units you should also add 1 to the integer for each unit that gets created for this player.

Then create 1 more trigger that checks if a unit of player 2 dies then it should remove 1 from that integer.
(Make sure that when resurrecting unit's through spells the units become alive again, which means the integer needs to be increased for each unit that is resurrected)

This way you can check every ... seconds if that integer variable becomes 0. When it does all units of player 2 are dead.
Which you can then use to show a victory to player 1 and a defeat to player 2.

(Also make sure that this trigger only works after the first unit is created for player 2, if it works before that then this would mean that at start the integer is 0 which then causes player 2 to automatically loose since he/she doesn't have any units at that moment)

EDIT: b.t.w. Dr Super Good
Or are you talking about updating the integer whenever a unit gets created or killed?
That's exactly what I meant with
1 enumeration for preplaced units.
Then add the units individually as they come into existance.
Remove the units from the counter when they die.

Be aware of stuff like resurrect which could mess up the count.
Thanks :)

EDIT 2:
have it check to see if the number of units in player 1's group is = 0 then victory the winning team.
This is also an enumeration which has to be checked every ... seconds. As explained by Dr Super Good it's better to use a stored integer instead of enumerating all units of that player every ... seconds. It would really slow down things if every ... seconds all units of a player need to be checked. Checking a variable that contains this amount is way faster.
Which is explained above in this post.
 
Last edited:
Status
Not open for further replies.
Top