HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Question about Victory/Defeat

02-24-2007, 02:37 PM#1
StockBreak
Hi all, I have a quite simple question: why if I use the command "Defeat Player", the player will receive a dialog menu with: "Restart", "Reduce Difficulty" etc... and not only a "You have lost!", "Continue Game", "Exit Game" menu? This only happens if I test my map on single player or I should use another command? I tried to play alone on Battle.net with my map but the menu was always the same... Any idea? Thanks.
02-24-2007, 03:05 PM#2
zen87
well totally remake the CustomDefeat/Victory native, then you can make it become whatever you wan it to be...
02-24-2007, 07:45 PM#3
The)TideHunter(
Its simple to make your Defeat/Victory system.

All you have to do, is instead of using Defeat ~Player~, show a dialog for him, saying Defeat or whatever, with one button, saying whatever you want, and when its clicked, hide the multiboard and defeat the player without showing the dialog, then it looks like the wc3 one.
02-25-2007, 08:17 PM#4
StockBreak
Ok, I made my custom defeat system but i have some more questions (they will be commented, thanks):

Collapse JASS:
//**************************************************************************
//*
//* Custom Defeat
//* -------------
//*
//* The first function is CustomDefeat, my questions are listed below.
//* The first question is on the bottom of the code, thanks!
//*
//**************************************************************************

function CustomDefeatQuit takes nothing returns nothing
    // 2) Isn't this function useless?
    if bj_isSinglePlayer then
        call PauseGame( false )
    endif

    // Bump the difficulty back up to the default.
    // 3) Isn't this function useless?
    call SetGameDifficulty(GetDefaultDifficulty())

    // 4) Ok, this is my main question:
    //    -----------------------------
    //    What does this function exactly do?
    //    It ends the game if the player click on the dialog button, but
    //    doesn't it end the game for ALL the players? I mean, it doesn't take
    //    ANY argument... Can you explain?
    call EndGame( true )
endfunction

function CustomDefeatDialog takes player whichPlayer, string message returns nothing
    local trigger t = CreateTrigger(  )
    local dialog  d = DialogCreate(  )
    local button  b = DialogAddButton( d, GetLocalizedString( "GAMEOVER_QUIT_MISSION" ), GetLocalizedHotkey( "GAMEOVER_QUIT_MISSION" ) )
    local player  p = GetLocalPlayer(  )

    call DialogSetMessage( d, message )

    // Ok, now there is only one clickable button
    call TriggerRegisterDialogButtonEvent( t, b )
    // Follow this function for my next question
    call TriggerAddAction( t, function CustomDefeatQuit )

    // 5) What does this "if" do?
    if ( p == whichPlayer) then
        // 6) What does it do?
        call EnableUserControl( true )
        // 7) What doesn it do?
        call EnableUserUI( false )
    endif

    // 8) Is it necessary?
    call DialogDisplay( whichPlayer, d, true )
    call VolumeGroupSetVolumeForPlayerBJ( whichPlayer, SOUND_VOLUMEGROUP_UI, 1.0 )
    call StartSoundForPlayerBJ( whichPlayer, bj_defeatDialogSound )

    set t = null
    set d = null
    set b = null
    set p = null
endfunction

function CustomDefeat takes player whichPlayer, string message returns nothing
    // 1) What does this function exactly do?
    //    When a player is removed without any other actions, it seems that it
    //    can't no more move its units, issue orders etc...
    call RemovePlayer( whichPlayer, PLAYER_GAME_RESULT_DEFEAT )

    // Ok, just a message for the other players
    call DisplayTimedTextFromPlayer( whichPlayer, 0, 0, 60, GetLocalizedString( "PLAYER_DEFEATED" ) )

    // UI only needs to be displayed to users.
    if ( GetPlayerController( whichPlayer ) == MAP_CONTROL_USER ) then
        call CustomDefeatDialog( whichPlayer, message )
    endif
endfunction
02-25-2007, 09:04 PM#5
The)TideHunter(
I might aswell post my old custom defeat system, it was used in my CF stuff.
I have edited it to work without CF.
It requires a gamecache called udg_GC.

Collapse JASS:
function GC takes nothing returns gamecache
    if(udg_GC==null)then
        call FlushGameCache(InitGameCache("GC"))
        set udg_GC=InitGameCache("GC")
    endif
    return udg_GC
endfunction

function H2I takes handle H returns integer
    return H
    return 0
endfunction

function I2Dialog takes integer I returns dialog
    return I
    return null
endfunction



function CustomDefeatActions takes nothing returns nothing
    local trigger t = GetTriggeringTrigger()
    local gamecache g = GC()
    local string s = I2S(H2I(t))
    local dialog d = I2Dialog(GetStoredInteger(g,s,"DefeatPlayer_Dialog"))
    local boolean SS = GetStoredBoolean(g,s,"DefeatPlayer_Button")
    local player p = Player(GetStoredInteger(g,s,"DefeatPlayer_Id"))
    call CustomVictoryBJ(p, false, SS)
    call DialogClear(d)
    call FlushStoredMission(g,s)
    call DestroyTrigger(t)
    call DialogDestroy(d)
    set t = null
    set g =  null
    set d = null
    set p = null
endfunction           

function CustomDefeat takes player whichPlayer, string Msg, string ButtonMsg, boolean ShowScores returns nothing
    local dialog d = DialogCreate()
    local trigger t = CreateTrigger()
    local gamecache g = GC()
    local string s = I2S(H2I(t))
    call DialogSetMessage(d, Msg)
    call DialogAddButton(d, ButtonMsg, 0)
    if(GetLocalPlayer() != whichPlayer) then
        call DialogDisplay(whichPlayer, d, false)
    endif
    call DialogDisplay(whichPlayer, d, true)
    call StoreInteger(g,s,"DefeatPlayer_Dialog",H2I(d))
    call StoreBoolean(g,s,"DefeatPlayer_SS",ShowScores)
    call StoreInteger(g,s,"DefeatPlayer_Id",GetPlayerId(whichPlayer))
    call TriggerRegisterDialogButtonEvent(t,b)
    call TriggerAddAction(t,function CustomDefeatActions)
    set d = null
    set b = null
    set t = null
    set g = null
endfunction

If you already have a GC functon, H2I function or I2Dialog function, replace those with the one i posted.

To use, do:
call CustomDefeat(whichPlayer, Msg, ButtonMsg, ShowScores)
Example:
call CustomDefeat(Player(0),"You have been Defeated!","Exit Game",false)
02-26-2007, 10:27 AM#6
StockBreak
Thanks for your help! I saw that you uses the bj CustomVictoryBJ which uses the function EndGame; as I asked on my 4th question (see above post), doesn't it interrupt the game for ALL the players and not only for the "clicking player" (since it doesn't take any argument)? Thanks.
02-26-2007, 02:48 PM#7
The)TideHunter(
I'm not sure, thats why i use the big BJ.
But if it does effect all players, use GetLocalPlayer if block to solve it.
02-26-2007, 05:45 PM#8
StockBreak
Quote:
Originally Posted by The)TideHunter(
I'm not sure, thats why i use the big BJ.
But if it does effect all players, use GetLocalPlayer if block to solve it.
Ok, I will use it too :)
Just another question: how to use the "GetLocalPlayer if block", how does it work? How to use it, for example, in order to make a unit tinted with a color only for a player? Thanks!
02-26-2007, 06:21 PM#9
The)TideHunter(
The GetLocalPlayer if block does a global action for one player, or a player group or whatever.

GetLocalPlayer is ran on each players computer, and only fishes out if its matched to a player.

For example:

if(GetLocalPlayer()==Player(0)) then
It will check if the code is running on Player(0)'s computer, if it is, do the global action, if not, don't.
So, it only does that global action on that computer.
So, to tint a unit for only one player, you can use:
Collapse JASS:
if(GetLocalPlayer()==YourPlayer) then
    call SetUnitVertexColor(YourUnit,YourRed,YourGreen,YourBlue,YourAlpha)
endif

Its that simple!

But be carful, everybodies computers are checked to see if they are Synced, (meaning the game is all the same). If they are not Synced, they are Desynced, a Desync will cause a dissconnect.
An example of a desync is a unit on player ones computer is at the top left corner, and the same unit for player two is at the bottom right, that will cause a Desync, which leads to a game crash.
So, if its an important piece of infomation, like a units X/Y/Z, then yes, it will cause a Desync, i don't think it will be the same for Vertex, as thats just for viewing.
But you could do:

Collapse JASS:
    local string s = "Hello"
    if(GetLocalPlayer()==Player(0))then
        set s = "I am purple"
    endif

The variable s, is different for Player(0), which is fine if its an atomic type (string,integer,real,boolean).

If you use that code, and show the variable s for all players, the string will show different for Player(0).

Anyway, thats the basics of GetLocalPlayer, you can use it literally anywhere, but be careful of core game infomation which causes Desync's.
02-26-2007, 06:28 PM#10
StockBreak
Very good explanation and thanks for your help! REP added!

EDIT: just another thing. I tested some things:
a) The CustomDefeatBJ works properly on LAN/Battle.net games (it doesn't show Restart etc... options)
b) The function EndGame, if used on a normal function interrupt the game for all players, BUT if used on the TriggerRegisterDialogButtonEvent function it works only for the player that clicks on the button, why???