Ticket #2373: resignation_v3_WIP.patch
File resignation_v3_WIP.patch, 17.4 KB (added by , 10 years ago) |
---|
-
binaries/data/mods/public/gui/common/functions_global_object.js
22 22 { 23 23 if (btnCode !== undefined && g_messageBoxBtnFunctions[btnCode]) 24 24 { 25 if (g_messageBoxCallbackArgs[btnCode]) 26 g_messageBoxBtnFunctions[btnCode](g_messageBoxCallbackArgs[btnCode]); 25 // cache the vales to make it possible to call a messageBox from a callback function. 26 var callbackFunction = g_messageBoxBtnFunctions[btnCode]; 27 var callbackArgs = g_messageBoxCallbackArgs[btnCode] 28 g_messageBoxBtnFunctions = []; 29 g_messageBoxCallbackArgs = []; 30 31 if (callbackArgs !== undefined) 32 callbackFunction(callbackArgs); 27 33 else 28 g_messageBoxBtnFunctions[btnCode](); 34 callbackFunction(); 35 36 return; 29 37 } 30 31 38 g_messageBoxBtnFunctions = []; 32 39 g_messageBoxCallbackArgs = []; 33 40 } -
binaries/data/mods/public/gui/session/menu.js
147 147 closeOpenDialogs(); 148 148 pauseGame(); 149 149 var btCaptions = ["Yes", "No"]; 150 var btCode = [ leaveGame, resumeGame];150 var btCode = [g_IsNetworked && !g_GameEnded ? networkReturnQuestion : prepareLeaveGame, resumeGame]; 151 151 messageBox(400, 200, "Are you sure you want to quit?", "Confirmation", 0, btCaptions, btCode); 152 152 } 153 153 154 function networkReturnQuestion() 155 { 156 var btCaptions = ["Yes, I will return", "No, I resign"]; 157 var btCode = [prepareLeaveGame, prepareLeaveGame]; 158 var btArgs = [true, false]; 159 messageBox(400, 200, "You are exiting the game, will you return soon?", "Confirmation", 0, btCaptions, btCode, btArgs); 160 } 154 161 155 162 function openDeleteDialog(selection) 156 163 { -
binaries/data/mods/public/gui/session/messages.js
207 207 { 208 208 if (! message.hosts[host]) 209 209 { 210 // cache values 211 var removedPlayerID = g_PlayerAssignments[host].player; 212 var removedPlayerName = g_PlayerAssignments[host].name; 213 var removedPlayerState = g_Players[removedPlayerID].state; 210 214 // Tell the user about the disconnection 211 215 addChatMessage({ "type": "disconnect", "guid": host }); 212 216 213 217 // Update the cached player data, so we can display the disconnection status 214 218 updatePlayerDataRemove(g_Players, host); 219 220 if (removedPlayerState != "active") 221 return; 222 // start timer and show timeout message 223 Engine.PostNetworkCommand({ 224 "type": "start-player-timeout", 225 "playerID": removedPlayerID, 226 "playerName": removedPlayerName, 227 "rejoinTimeLimit": REJOIN_TIME_LIMIT 228 }); 215 229 } 216 230 } 217 231 … … 225 239 226 240 // Tell the user about the connection 227 241 addChatMessage({ "type": "connect", "guid": host }, message.hosts); 242 243 if (g_Players[message.hosts[host].player].state != "active") 244 return; 245 // stop timer and show timeout message 246 Engine.PostNetworkCommand({ 247 "type": "stop-player-timeout", 248 "playerID": message.hosts[host].player, 249 }); 228 250 } 229 251 } 230 252 -
binaries/data/mods/public/gui/session/session.js
1 1 // Network Mode 2 2 var g_IsNetworked = false; 3 const REJOIN_TIME_LIMIT = 15; // rejoin time limit in seconds 3 4 4 5 // Is this user in control of game settings (i.e. is a network server, or offline player) 5 6 var g_IsController; … … 37 38 // Whether the player has lost/won and reached the end of their game 38 39 var g_GameEnded = false; 39 40 41 // true, if leave game was called 42 var g_leaveGameInProcess = false; 43 40 44 var g_Disconnected = false; // Lost connection to server 41 45 42 46 // Holds player states from the last tick … … 234 238 Engine.SubmitUserReport("profile", 3, JSON.stringify(data)); 235 239 } 236 240 237 function resignGame() 241 /** 242 * let's a player resign 243 * leaveGameAfterResign: if true, game is quit, after resign 244 */ 245 function resignGame(leaveGameAfterResign) 238 246 { 239 247 var simState = GetSimState(); 240 248 … … 241 249 // Players can't resign if they've already won or lost. 242 250 if (simState.players[Engine.GetPlayerID()].state != "active" || g_Disconnected) 243 251 return; 244 245 252 // Tell other players that we have given up and been defeated 246 253 Engine.PostNetworkCommand({ 247 254 "type": "defeat-player", … … 248 255 "playerId": Engine.GetPlayerID() 249 256 }); 250 257 251 global.music.setState(global.music.states.DEFEAT); 252 resumeGame(); 258 // resume to the game, if the resign button was used 259 if (!leaveGameAfterResign) 260 { 261 global.music.setState(global.music.states.DEFEAT); 262 resumeGame(); 263 } 253 264 } 254 265 255 function leaveGame() 266 /** 267 * prepare to leave the game 268 * willRejoin: can be set to true, in case of network game, if the player just has to reboot or restart the game 269 */ 270 function prepareLeaveGame(willRejoin) 256 271 { 257 272 var extendedSimState = Engine.GuiInterfaceCall("GetExtendedSimulationState"); 258 273 var playerState = extendedSimState.players[Engine.GetPlayerID()]; 259 274 var mapSettings = Engine.GetMapSettings(); 260 275 var gameResult; 276 var timeUntilEngineEndsGame = 1; 261 277 262 278 if (g_Disconnected) 263 279 { … … 274 290 else // "active" 275 291 { 276 292 gameResult = "You have abandoned the game."; 277 278 // Tell other players that we have given up and been defeated279 Engine.PostNetworkCommand({280 "type": "defeat-player",281 "playerId": Engine.GetPlayerID()282 });283 284 293 global.music.setState(global.music.states.DEFEAT); 294 295 // resign, if player click on "No, I resign" 296 if (!willRejoin) 297 { 298 gameResult = "You have been defeated..."; 299 resignGame(true); 300 timeUntilEngineEndsGame = 5000; // give engine some time to deliver the network message (before the client disconnects...) 301 } 285 302 } 303 g_leaveGameInProcess = true; 304 setTimeout(function() { leaveGame({"gameResult": gameResult, "extendedSimState": extendedSimState, "mapSettings": mapSettings}); }, timeUntilEngineEndsGame); 305 } 286 306 307 /** 308 * leaves the game; is needed to give network messages time to reach their destination 309 * data: must contain gameResult, extendedSimState and mapSettings 310 */ 311 function leaveGame(data) 312 { 287 313 stopAmbient(); 288 314 Engine.EndGame(); 289 315 … … 291 317 Engine.SendUnregisterGame(); 292 318 293 319 Engine.SwitchGuiPage("page_summary.xml", { 294 "gameResult" : gameResult,295 "timeElapsed" : extendedSimState.timeElapsed,296 "playerStates": extendedSimState.players,320 "gameResult" : data.gameResult, 321 "timeElapsed" : data.extendedSimState.timeElapsed, 322 "playerStates": data.extendedSimState.players, 297 323 "players": g_Players, 298 "mapSettings": mapSettings324 "mapSettings": data.mapSettings 299 325 }); 300 326 } 301 327 … … 427 453 var btCode = [null]; 428 454 var message = "Press OK to continue"; 429 455 } 430 else 456 else if (!g_leaveGameInProcess) 431 457 { 432 458 var btCaptions = ["Yes", "No"]; 433 var btCode = [ leaveGame, null];459 var btCode = [prepareLeaveGame, null]; 434 460 var message = "Do you want to quit?"; 435 461 } 462 else 463 { 464 var btCaptions = ["Ok"]; 465 var btCode = [null]; 466 var message = "You have been defeated. Game will exit now."; 467 } 436 468 437 469 if (playerState.state == "defeated") 438 470 { … … 495 527 updateTimeNotifications(); 496 528 497 529 // Update music state on basis of battle state. 498 var battleState = Engine.GuiInterfaceCall("GetBattleState", Engine.GetPlayerID());499 if (battleState)500 global.music.setState(global.music.states[battleState]);530 //var battleState = Engine.GuiInterfaceCall("GetBattleState", Engine.GetPlayerID()); 531 //if (battleState) 532 // global.music.setState(global.music.states[battleState]); 501 533 502 534 } 503 535 -
binaries/data/mods/public/gui/session/session.xml
776 776 z="40" 777 777 > 778 778 <object size="4 36 100%-4 50%+20"> 779 780 <!-- Manual button --> 781 <object type="button" 782 name="manualButton" 783 style="StoneButtonFancy" 784 size="0 0 100% 28" 785 tooltip_style="sessionToolTip" 786 > 787 Manual 788 <action on="Press">openManual();</action> 789 </object> 790 791 <!-- Chat button --> 792 <object type="button" 793 name="chatButton" 794 style="StoneButtonFancy" 795 size="0 32 100% 60" 796 tooltip_style="sessionToolTip" 797 > 798 Chat 799 <action on="Press">chatMenuButton();</action> 800 </object> 779 801 780 <!-- Settings button --> 781 <object type="button" 782 name="settingsButton" 783 style="StoneButtonFancy" 784 size="0 0 100% 28" 785 tooltip_style="sessionToolTip" 786 > 787 Settings 788 <action on="Press">settingsMenuButton();</action> 789 </object> 802 <!-- Save game button --> 803 <object type="button" 804 name="saveGameButton" 805 style="StoneButtonFancy" 806 size="0 64 100% 92" 807 tooltip_style="sessionToolTip" 808 > 809 Save 810 <action on="Press"> 811 openSave(); 812 </action> 813 </object> 814 815 <!-- Settings button --> 816 <object type="button" 817 name="settingsButton" 818 style="StoneButtonFancy" 819 size="0 96 100% 124" 820 tooltip_style="sessionToolTip" 821 > 822 Settings 823 <action on="Press">settingsMenuButton();</action> 824 </object> 790 825 791 792 <!-- Save game button --> 793 <object type="button" 794 name="saveGameButton" 795 style="StoneButtonFancy" 796 size="0 32 100% 60" 797 tooltip_style="sessionToolTip" 798 > 799 Save 800 <action on="Press"> 801 openSave(); 802 </action> 826 <!-- Pause / Resume Button --> 827 <object type="button" 828 name="pauseButton" 829 style="StoneButtonFancy" 830 size="0 128 100% 156" 831 tooltip_style="sessionToolTip" 832 > 833 <object name="pauseButtonText" type="text" style="CenteredButtonText" ghost="true">Pause</object> 834 <action on="Press">togglePause();</action> 835 </object> 836 837 <!-- Resign button --> 838 <object type="button" 839 name="menuResignButton" 840 style="StoneButtonFancy" 841 size="0 160 100% 188" 842 tooltip_style="sessionToolTip" 843 > 844 Resign 845 <action on="Press">resignMenuButton();</action> 846 </object> 847 848 <!-- Exit button --> 849 <object type="button" 850 name="menuExitButton" 851 style="StoneButtonFancy" 852 size="0 192 100% 220" 853 tooltip_style="sessionToolTip" 854 > 855 Exit 856 <action on="Press">exitMenuButton();</action> 857 </object> 803 858 </object> 804 805 <!-- Chat button -->806 <object type="button"807 name="chatButton"808 style="StoneButtonFancy"809 size="0 64 100% 92"810 tooltip_style="sessionToolTip"811 >812 Chat813 <action on="Press">chatMenuButton();</action>814 </object>815 816 <!-- Resign button -->817 <object type="button"818 name="menuResignButton"819 style="StoneButtonFancy"820 size="0 96 100% 124"821 tooltip_style="sessionToolTip"822 >823 Resign824 <action on="Press">resignMenuButton();</action>825 </object>826 827 <!-- Exit button -->828 <object type="button"829 name="menuExitButton"830 style="StoneButtonFancy"831 size="0 128 100% 156"832 tooltip_style="sessionToolTip"833 >834 Exit835 <action on="Press">exitMenuButton();</action>836 </object>837 838 <!-- Pause / Resume Button -->839 <object type="button"840 name="pauseButton"841 style="StoneButtonFancy"842 size="0 160 100% 188"843 tooltip_style="sessionToolTip"844 >845 <object name="pauseButtonText" type="text" style="CenteredButtonText" ghost="true">Pause</object>846 <action on="Press">togglePause();</action>847 </object>848 849 <!-- Manual button -->850 <object type="button"851 name="manualButton"852 style="StoneButtonFancy"853 size="0 192 100% 220"854 tooltip_style="sessionToolTip"855 >856 Manual857 <action on="Press">openManual();</action>858 </object>859 </object>860 859 </object> 861 860 862 861 <!-- In-progress research --> -
binaries/data/mods/public/simulation/components/EndGameManager.js
19 19 // Allied victory means allied players can win if victory conditions are met for each of them 20 20 // Would be false for a "last man standing" game (when diplomacy is fully implemented) 21 21 this.alliedVictory = true; 22 23 this.autoPlayerTimeout = []; 22 24 }; 23 25 24 26 EndGameManager.prototype.SetGameType = function(newGameType) … … 32 34 return this.gameType == type; 33 35 }; 34 36 37 EndGameManager.prototype.startPlayerTimeout = function(playerID, playerName, timeout) 38 { 39 // check, if the player is active 40 var cmpPlayer = Engine.QueryInterface(playerID, IID_Player); 41 if (!cmpPlayer || cmpPlayer.GetState() != "active") 42 return; 43 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 44 var timeElapsed = cmpTimer.GetTime(); 45 warn("["+timeElapsed+"] state: " + cmpPlayer.GetState() + " (should not be active...)"); 46 47 var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 48 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 49 var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 50 51 if (!cmpGuiInterface || !cmpTimer || !cmpPlayerManager) 52 return; 53 54 // get players to send the message 55 var players = []; 56 for (var i = 1; i < cmpPlayerManager.GetNumPlayers(); i++) 57 players.push(i); 58 59 // add timers 60 var textTimerID = cmpGuiInterface.AddTimeNotification({ 61 "message": playerName + " will be auto-resigned in %T", 62 "players": players, 63 "time": timeout 64 }); 65 var timerID = cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_EndGameManager, "MarkPlayerAsAutoResigned", timeout, playerID); 66 // save timer IDs 67 this.autoPlayerTimeout[playerID] = [textTimerID, timerID]; 68 }; 69 70 EndGameManager.prototype.stopPlayerTimeout = function(playerID) 71 { 72 if (!this.autoPlayerTimeout[playerID]) // no timeout for player 73 return; 74 var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 75 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 76 if (!cmpGuiInterface || !cmpTimer) 77 return; 78 79 // delete the timers 80 var timerIDs = this.autoPlayerTimeout[playerID]; 81 cmpGuiInterface.DeleteTimeNotification(timerIDs[0]); 82 cmpTimer.CancelTimer(timerIDs[1]); 83 delete this.autoPlayerTimeout[playerID]; 84 }; 85 86 87 /* 88 * marks an player as auto resigned after an timeout. 89 * playerID: player ID of the player to mark as auto resigned 90 */ 91 EndGameManager.prototype.MarkPlayerAsAutoResigned = function(playerID) 92 { 93 warn("request for auto mark"); 94 var cmpPlayerMan = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 95 if (!cmpPlayerMan) 96 return; 97 98 var playerEnt = cmpPlayerMan.GetPlayerByID(playerID); 99 if (playerEnt == INVALID_ENTITY) 100 return; 101 warn("auto marked"); 102 // send OnPlayerDefeated message 103 Engine.PostMessage(playerEnt, MT_PlayerDefeated, { "playerId": playerID } ); 104 }; 105 35 106 EndGameManager.prototype.MarkPlayerAsWon = function(playerID) 36 107 { 37 108 var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); -
binaries/data/mods/public/simulation/components/Player.js
576 576 577 577 Player.prototype.OnPlayerDefeated = function(msg) 578 578 { 579 var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); 580 var timeElapsed = cmpTimer.GetTime(); 581 warn("["+timeElapsed+"] OnPlayerDefeated.........."); 579 582 this.state = "defeated"; 580 583 581 584 // TODO: Tribute all resources to this player's active allies (if any) … … 600 603 601 604 // Reveal the map for this player. 602 605 cmpRangeManager.SetLosRevealAll(this.playerID, true); 603 606 var timeElapsed = cmpTimer.GetTime(); 607 warn("["+timeElapsed+"] OnPlayerDefeated.........." + this.state); 604 608 // Send a chat message notifying of the player's defeat. 605 609 var notification = {"type": "defeat", "player": this.playerID}; 606 610 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); -
binaries/data/mods/public/simulation/helpers/Commands.js
323 323 Engine.PostMessage(playerEnt, MT_PlayerDefeated, { "playerId": player } ); 324 324 break; 325 325 326 case "start-player-timeout": 327 var cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager); 328 if (!cmpEndGameManager) 329 return; 330 cmpEndGameManager.startPlayerTimeout(cmd.playerID, cmd.playerName, cmd.rejoinTimeLimit * 1000); 331 break; 332 333 case "stop-player-timeout": 334 var cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager); 335 if (!cmpEndGameManager) 336 return; 337 cmpEndGameManager.stopPlayerTimeout(cmd.playerID); 338 break; 339 326 340 case "garrison": 327 341 // Verify that the building can be controlled by the player or is mutualAlly 328 342 if (CanControlUnitOrIsAlly(cmd.target, player, controlAllUnits))