diff --git a/binaries/data/mods/public/gui/session/menu.js b/binaries/data/mods/public/gui/session/menu.js index 44b004b929..5562ae2b69 100644 --- a/binaries/data/mods/public/gui/session/menu.js +++ b/binaries/data/mods/public/gui/session/menu.js @@ -755,6 +755,7 @@ function toggleDeveloperOverlay() function closeOpenDialogs() { + // TODO: also close message boxes closeMenu(); closeChat(); closeDiplomacy(); diff --git a/binaries/data/mods/public/gui/session/messages.js b/binaries/data/mods/public/gui/session/messages.js index ab895deaec..5392657cbf 100644 --- a/binaries/data/mods/public/gui/session/messages.js +++ b/binaries/data/mods/public/gui/session/messages.js @@ -101,6 +101,7 @@ var g_FormatChatMessage = { "clientlist": msg => getUsernameList(), "message": msg => formatChatCommand(msg), "defeat": msg => formatDefeatMessage(msg), + "won": msg => formatWinMessage(msg), "diplomacy": msg => formatDiplomacyMessage(msg), "tribute": msg => formatTributeMessage(msg), "attack": msg => formatAttackMessage(msg) @@ -194,6 +195,8 @@ var g_DiplomacyMessages = { /** * Defines how the GUI reacts to notifications that are sent by the simulation. + * Don't open new pages (message boxes) here! Otherwise further notifications + * handled in the same turn can't access the GUI objects anymore. */ var g_NotificationsTypes = { @@ -246,9 +249,16 @@ var g_NotificationsTypes = "player": player, "resign": !!notification.resign }); - - updateDiplomacy(); - updateChatAddressees(); + playerFinished(player, false); + }, + "won": function(notification, player) + { + addChatMessage({ + "type": "won", + "guid": findGuidForPlayerID(player), + "player": player + }); + playerFinished(player, true); }, "diplomacy": function(notification, player) { @@ -417,8 +427,7 @@ function findGuidForPlayerID(playerID) */ function handleNotifications() { - let notifications = Engine.GuiInterfaceCall("GetNotifications"); - for (let notification of notifications) + for (let notification of Engine.GuiInterfaceCall("GetNotifications")) { if (!notification.players || !notification.type || !g_NotificationsTypes[notification.type]) { @@ -745,6 +754,13 @@ function formatDefeatMessage(msg) ); } +function formatWinMessage(msg) +{ + return sprintf(translate("%(player)s has won."), { + "player": colorizePlayernameByID(msg.player) + }); +} + function formatDiplomacyMessage(msg) { let messageType; diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js index a92b01e000..4f5f441216 100644 --- a/binaries/data/mods/public/gui/session/session.js +++ b/binaries/data/mods/public/gui/session/session.js @@ -37,6 +37,11 @@ var g_IsObserver = false; */ var g_HasRejoined = false; +/** + * Shows a message box asking the user to leave if "won" or "defeated". + */ +var g_ConfirmExit = false; + /** * True if the current player has paused the game explicitly. */ @@ -118,17 +123,6 @@ var g_TemplateData = {}; var g_TemplateDataWithoutLocalization = {}; var g_TechnologyData = {}; -/** - * Cache concatenated list of player states ("active", "defeated" or "won"). - */ -var g_CachedLastStates = ""; - -/** - * Whether the current player has lost/won and reached the end of their game. - * Used for reporting the gamestate and showing the game-end message only once. - */ -var g_GameEnded = false; - /** * Top coordinate of the research list. * Changes depending on the number of displayed counters. @@ -240,8 +234,6 @@ function init(initData, hotloadData) g_ReplaySelectionData = initData.replaySelectionData; g_HasRejoined = initData.isRejoining; - g_Players = getPlayerData(); - if (initData.savedGUIData) restoreSavedGameData(initData.savedGUIData); @@ -251,15 +243,14 @@ function init(initData, hotloadData) { if (g_IsReplay) g_PlayerAssignments.local.player = -1; - - g_Players = getPlayerData(); } + g_Players = getPlayerData(); + g_CivData = loadCivData(); g_CivData.gaia = { "Code": "gaia", "Name": translate("Gaia") }; initializeMusic(); // before changing the perspective - selectViewPlayer(g_ViewedPlayer); let gameSpeed = Engine.GetGUIObjectByName("gameSpeed"); gameSpeed.list = g_GameSpeeds.Title; @@ -281,10 +272,12 @@ function init(initData, hotloadData) playerNames.push(colorizePlayernameHelper("■", player) + " " + g_Players[player].name); } + // Select "observer" item when rejoining as a defeated player + let viewedPlayer = g_Players[Engine.GetPlayerID()]; let viewPlayerDropdown = Engine.GetGUIObjectByName("viewPlayer"); viewPlayerDropdown.list = playerNames; viewPlayerDropdown.list_data = playerIDs; - viewPlayerDropdown.selected = Engine.GetPlayerID() + 1; + viewPlayerDropdown.selected = viewedPlayer && viewedPlayer.state == "defeated" ? 0 : Engine.GetPlayerID() + 1; // If in Atlas editor, disable the exit button if (Engine.IsAtlasRunning()) @@ -434,6 +427,31 @@ function controlsPlayer(playerID) playerState.state != "defeated" || playerState.controlsAll); } +/** + * Called when a player has won or was defeated. + */ +function playerFinished(player, won) +{ + reportGame(); + updateDiplomacy(); + updateChatAddressees(); + + if (player != Engine.GetPlayerID() || Engine.IsAtlasRunning()) + return; + + global.music.setState( + won ? + global.music.states.VICTORY : + global.music.states.DEFEAT + ); + + // Select "observer" item + if (!won) + Engine.GetGUIObjectByName("viewPlayer").selected = 0; + + g_ConfirmExit = won ? "won" : "defeated"; +} + /** * Sets civ icon for the currently viewed player. * Hides most gui objects for observers. @@ -492,8 +510,6 @@ function resignGame(leaveGameAfterResign) "resign": true }); - updateTopPanel(); - global.music.setState(global.music.states.DEFEAT); if (!leaveGameAfterResign) @@ -582,8 +598,6 @@ function onTick() let tickLength = new Date() - lastTickTime; lastTickTime = now; - checkPlayerState(); - handleNetMessages(); updateCursorAndTooltip(); @@ -609,71 +623,6 @@ function onTick() Engine.GuiInterfaceCall("ClearRenamedEntities"); } -function checkPlayerState() -{ - if (g_GameEnded || Engine.GetPlayerID() < 1) - return; - - // Send a game report for each player in this game. - let m_simState = GetSimState(); - let playerState = m_simState.players[Engine.GetPlayerID()]; - let tempStates = ""; - for (let player of m_simState.players) - tempStates += player.state + ","; - - if (g_CachedLastStates != tempStates) - { - g_CachedLastStates = tempStates; - reportGame(); - } - - if (playerState.state == "active") - return; - - // Make sure nothing is open to avoid stacking. - closeOpenDialogs(); - - // Make sure this doesn't run again. - g_GameEnded = true; - - // Select observermode - Engine.GetGUIObjectByName("viewPlayer").selected = playerState.state == "won" ? g_ViewedPlayer + 1 : 0; - - let btCaptions; - let btCode; - let message; - let title; - if (Engine.IsAtlasRunning()) - { - // If we're in Atlas, we can't leave the game - btCaptions = [translate("OK")]; - btCode = [null]; - message = translate("Press OK to continue"); - } - else - { - btCaptions = [translate("No"), translate("Yes")]; - btCode = [null, leaveGame]; - message = translate("Do you want to quit?"); - } - - if (playerState.state == "defeated") - { - title = translate("DEFEATED!"); - global.music.setState(global.music.states.DEFEAT); - } - else if (playerState.state == "won") - { - title = translate("VICTORIOUS!"); - global.music.setState(global.music.states.VICTORY); - // TODO: Reveal map directly instead of this silly proxy. - if (!Engine.GetGUIObjectByName("devCommandsRevealMap").checked) - Engine.GetGUIObjectByName("devCommandsRevealMap").checked = true; - } - - messageBox(400, 200, message, title, btCaptions, btCode); -} - function changeGameSpeed(speed) { if (!g_IsNetworked) @@ -714,8 +663,39 @@ function onSimulationUpdate() return; handleNotifications(); - updateGUIObjects(); + + if (g_ConfirmExit) + confirmExit(); +} + +/** + * Don't show the message box before all playerstate changes are processed. + */ +function confirmExit() +{ + closeOpenDialogs(); + + let subject = g_ConfirmExit == "won" ? + translate("You have won!") : + translate("You have been defeated!"); + + subject += "\n" + translate("Do you want to quit?"); + + if (g_IsNetworked && g_IsController) + subject += "\n" + translate("Leaving will disconnect all other players."); + + messageBox( + 400, 200, + subject, + g_ConfirmExit == "won" ? + translate("VICTORIOUS!") : + translate("DEFEATED!"), + [translate("No"), translate("Yes")], + [resumeGame, leaveGame] + ); + + g_ConfirmExit = false; } function updateGUIObjects() @@ -747,7 +727,7 @@ function updateGUIObjects() Engine.GetGUIObjectByName("devControlAll").checked = g_DevSettings.controlAll; } - if (g_ViewedPlayer != -1 && !g_GameEnded) + if (!g_IsObserver) { // Update music state on basis of battle state. let battleState = Engine.GuiInterfaceCall("GetBattleState", g_ViewedPlayer); @@ -805,7 +785,6 @@ function updateGUIStatusBar(nameOfBar, points, maxPoints, direction) statusBar.size = healthSize; } - function updateHeroes() { let playerState = GetSimState().players[g_ViewedPlayer]; @@ -1119,7 +1098,10 @@ function playAmbient() function getBuildString() { - return sprintf(translate("Build: %(buildDate)s (%(revision)s)"), { "buildDate": Engine.GetBuildTimestamp(0), revision: Engine.GetBuildTimestamp(2) }); + return sprintf(translate("Build: %(buildDate)s (%(revision)s)"), { + "buildDate": Engine.GetBuildTimestamp(0), + "revision": Engine.GetBuildTimestamp(2) + }); } function showTimeWarpMessageBox() @@ -1137,7 +1119,8 @@ function showTimeWarpMessageBox() function reportGame() { // Only 1v1 games are rated (and Gaia is part of g_Players) - if (!Engine.HasXmppClient() || !Engine.IsRankedGame() || g_Players.length != 3) + if (!Engine.HasXmppClient() || !Engine.IsRankedGame() || + g_Players.length != 3 || Engine.GetPlayerID() == -1) return; let extendedSimState = Engine.GuiInterfaceCall("GetExtendedSimulationState"); diff --git a/binaries/data/mods/public/maps/scripts/ConquestCommon.js b/binaries/data/mods/public/maps/scripts/ConquestCommon.js index 1f4c92276b..b118216ae1 100644 --- a/binaries/data/mods/public/maps/scripts/ConquestCommon.js +++ b/binaries/data/mods/public/maps/scripts/ConquestCommon.js @@ -25,8 +25,12 @@ Trigger.prototype.ConquestHandlerOwnerShipChanged = function(msg) if (index >= 0) { entities.splice(index, 1); - if (!entities.length && Engine.QueryInterface(this.conquestEntitiesByPlayer[msg.from].player, IID_Player).GetState() == "active") - Engine.PostMessage(this.conquestEntitiesByPlayer[msg.from].player, MT_PlayerDefeated, { "playerId": msg.from } ); + if (!entities.length) + { + let cmpPlayer = QueryPlayerIDInterface(msg.from); + if (cmpPlayer) + cmpPlayer.SetState("defeated"); + } } } @@ -67,7 +71,7 @@ Trigger.prototype.ConquestTrainingFinished = function(msg) return; } this.conquestEntitiesByPlayer[player].entities.push(...msg.entities); -} +}; Trigger.prototype.ConquestStartGameCount = function() { @@ -90,7 +94,7 @@ Trigger.prototype.ConquestStartGameCount = function() }); this.conquestDataInit = true; -} +}; var cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); diff --git a/binaries/data/mods/public/maps/scripts/TriggerHelper.js b/binaries/data/mods/public/maps/scripts/TriggerHelper.js index 031739e15e..0b7955e55c 100644 --- a/binaries/data/mods/public/maps/scripts/TriggerHelper.js +++ b/binaries/data/mods/public/maps/scripts/TriggerHelper.js @@ -114,7 +114,8 @@ TriggerHelper.GetResourceType = function(entity) }; /** - * Wins the game for a player + * The given player will win the game. + * If it's not a last man standing game, then allies will win too. */ TriggerHelper.SetPlayerWon = function(playerID) { @@ -127,10 +128,9 @@ TriggerHelper.SetPlayerWon = function(playerID) */ TriggerHelper.DefeatPlayer = function(playerID) { - let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); - let playerEnt = cmpPlayerManager.GetPlayerByID(playerID); - - Engine.PostMessage(playerEnt, MT_PlayerDefeated, { "playerId": playerID } ); + let cmpPlayer = QueryPlayerIDInterface(playerID); + if (cmpPlayer) + cmpPlayer.SetState("defeated"); }; /** diff --git a/binaries/data/mods/public/simulation/components/EndGameManager.js b/binaries/data/mods/public/simulation/components/EndGameManager.js index 502b6fc0bb..ccf4ee1f4e 100644 --- a/binaries/data/mods/public/simulation/components/EndGameManager.js +++ b/binaries/data/mods/public/simulation/components/EndGameManager.js @@ -1,6 +1,6 @@ /** - * System component which regularly checks victory/defeat conditions - * and if they are satisfied then it marks the player as victorious/defeated. + * System component to store the gametype, gametype settings and + * check for allied victory / last-man-standing. */ function EndGameManager() {} @@ -19,6 +19,10 @@ EndGameManager.prototype.Init = function() // False for a "last man standing" game this.alliedVictory = true; + // Don't do any checks before the diplomacies were set for each player + // or when marking a player as won. + this.skipAlliedVictoryCheck = true; + this.lastManStandingMessage = undefined; }; @@ -41,6 +45,7 @@ EndGameManager.prototype.SetGameType = function(newGameType, newSettings = {}) { this.gameType = newGameType; this.gameTypeSettings = newSettings; + this.skipAlliedVictoryCheck = false; Engine.BroadcastMessage(MT_GameTypeChanged, {}); }; @@ -50,26 +55,20 @@ EndGameManager.prototype.MarkPlayerAsWon = function(playerID) let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); let numPlayers = cmpPlayerManager.GetNumPlayers(); - for (let i = 1; i < numPlayers; ++i) - { - let playerEntityId = cmpPlayerManager.GetPlayerByID(i); - let cmpPlayer = Engine.QueryInterface(playerEntityId, IID_Player); + this.skipAlliedVictoryCheck = true; - if (cmpPlayer.GetState() != "active") - continue; + // Group win/defeat messages + for (let won of [false, true]) + for (let i = 1; i < numPlayers; ++i) + { + let cmpPlayer = QueryPlayerIDInterface(i); + let hasWon = playerID == i || this.alliedVictory && cmpPlayer.IsMutualAlly(playerID); - if (playerID == cmpPlayer.GetPlayerID() || this.alliedVictory && cmpPlayer.IsMutualAlly(playerID)) - cmpPlayer.SetState("won"); - else - Engine.PostMessage(playerEntityId, MT_PlayerDefeated, { - "playerId": i, - "skipAlliedVictoryCheck": true - }); - } + if (hasWon == won) + cmpPlayer.SetState(won ? "won" : "defeated"); + } - // Reveal the map to all players - let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); - cmpRangeManager.SetLosRevealAll(-1, true); + this.skipAlliedVictoryCheck = false; }; EndGameManager.prototype.SetAlliedVictory = function(flag) @@ -79,6 +78,9 @@ EndGameManager.prototype.SetAlliedVictory = function(flag) EndGameManager.prototype.AlliedVictoryCheck = function() { + if (this.skipAlliedVictoryCheck) + return; + let cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); if (!cmpGuiInterface || !cmpPlayerManager) @@ -101,18 +103,12 @@ EndGameManager.prototype.AlliedVictoryCheck = function() } if (this.alliedVictory || allies.length == 1) - { for (let playerID of allies) { let cmpPlayer = QueryPlayerIDInterface(playerID); if (cmpPlayer) cmpPlayer.SetState("won"); } - - let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); - if (cmpRangeManager) - cmpRangeManager.SetLosRevealAll(-1, true); - } else this.lastManStandingMessage = cmpGuiInterface.AddTimeNotification({ "message": markForTranslation("Last remaining player wins."), @@ -127,14 +123,12 @@ EndGameManager.prototype.OnInitGame = function(msg) EndGameManager.prototype.OnGlobalDiplomacyChanged = function(msg) { - if (!msg.skipAlliedVictoryCheck) - this.AlliedVictoryCheck(); + this.AlliedVictoryCheck(); }; EndGameManager.prototype.OnGlobalPlayerDefeated = function(msg) { - if (!msg.skipAlliedVictoryCheck) - this.AlliedVictoryCheck(); + this.AlliedVictoryCheck(); }; Engine.RegisterSystemComponentType(IID_EndGameManager, "EndGameManager", EndGameManager); diff --git a/binaries/data/mods/public/simulation/components/Player.js b/binaries/data/mods/public/simulation/components/Player.js index bc98d200fe..4f81bd6254 100644 --- a/binaries/data/mods/public/simulation/components/Player.js +++ b/binaries/data/mods/public/simulation/components/Player.js @@ -359,9 +359,62 @@ Player.prototype.GetState = function() return this.state; }; -Player.prototype.SetState = function(newState) +Player.prototype.SetState = function(newState, resign) { + if (this.state != "active") + return; + + if (newState != "won" && newState != "defeated") + { + warn("Can't change playerstate to " + this.state); + return; + } + this.state = newState; + + let won = newState == "won"; + + // Reveal map to all or only that player + let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); + cmpRangeManager.SetLosRevealAll(won ? -1 : this.playerID, true); + + if (!won) + { + // Reassign all player's entities to Gaia + let entities = cmpRangeManager.GetEntitiesByPlayer(this.playerID); + + // The ownership change is done in two steps so that entities don't hit idle + // (and thus possibly look for "enemies" to attack) before nearby allies get + // converted to Gaia as well. + for (let entity of entities) + { + let cmpOwnership = Engine.QueryInterface(entity, IID_Ownership); + cmpOwnership.SetOwnerQuiet(0); + } + + // With the real ownership change complete, send OwnershipChanged messages. + for (let entity of entities) + Engine.PostMessage(entity, MT_OwnershipChanged, { + "entity": entity, + "from": this.playerID, + "to": 0 + }); + } + + Engine.BroadcastMessage(won ? MT_PlayerWon : MT_PlayerDefeated, { "playerId": this.playerID }); + + let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); + if (won) + cmpGUIInterface.PushNotification({ + "type": "won", + "players": [this.playerID] + }); + else + cmpGUIInterface.PushNotification({ + "type": "defeat", + "players": [this.playerID], + "resign": resign + }); }; Player.prototype.GetTeam = function() @@ -369,7 +422,7 @@ Player.prototype.GetTeam = function() return this.team; }; -Player.prototype.SetTeam = function(team, skipAlliedVictoryCheck = false) +Player.prototype.SetTeam = function(team) { if (this.teamsLocked) return; @@ -385,14 +438,13 @@ Player.prototype.SetTeam = function(team, skipAlliedVictoryCheck = false) if (this.team != cmpPlayer.GetTeam()) continue; - this.SetAlly(i, skipAlliedVictoryCheck); - cmpPlayer.SetAlly(this.playerID, skipAlliedVictoryCheck); + this.SetAlly(i); + cmpPlayer.SetAlly(this.playerID); } Engine.BroadcastMessage(MT_DiplomacyChanged, { "player": this.playerID, - "otherPlayer": null, - "skipAlliedVictoryCheck": skipAlliedVictoryCheck + "otherPlayer": null }); }; @@ -411,18 +463,17 @@ Player.prototype.GetDiplomacy = function() return this.diplomacy; }; -Player.prototype.SetDiplomacy = function(dipl, skipAlliedVictoryCheck = false) +Player.prototype.SetDiplomacy = function(dipl) { this.diplomacy = dipl; Engine.BroadcastMessage(MT_DiplomacyChanged, { "player": this.playerID, - "otherPlayer": null, - "skipAlliedVictoryCheck": skipAlliedVictoryCheck + "otherPlayer": null }); }; -Player.prototype.SetDiplomacyIndex = function(idx, value, skipAlliedVictoryCheck = false) +Player.prototype.SetDiplomacyIndex = function(idx, value) { let cmpPlayer = QueryPlayerIDInterface(idx); if (!cmpPlayer) @@ -435,13 +486,12 @@ Player.prototype.SetDiplomacyIndex = function(idx, value, skipAlliedVictoryCheck Engine.BroadcastMessage(MT_DiplomacyChanged, { "player": this.playerID, - "otherPlayer": cmpPlayer.GetPlayerID(), - "skipAlliedVictoryCheck": skipAlliedVictoryCheck + "otherPlayer": cmpPlayer.GetPlayerID() }); // Mutual worsening of relations if (cmpPlayer.diplomacy[this.playerID] > value) - cmpPlayer.SetDiplomacyIndex(this.playerID, value, skipAlliedVictoryCheck); + cmpPlayer.SetDiplomacyIndex(this.playerID, value); }; Player.prototype.UpdateSharedLos = function() @@ -520,9 +570,9 @@ Player.prototype.IsAI = function() return this.isAI; }; -Player.prototype.SetAlly = function(id, skipAlliedVictoryCheck = false) +Player.prototype.SetAlly = function(id) { - this.SetDiplomacyIndex(id, 1, skipAlliedVictoryCheck); + this.SetDiplomacyIndex(id, 1); }; /** @@ -558,9 +608,9 @@ Player.prototype.IsExclusiveMutualAlly = function(id) return this.playerID != id && this.IsMutualAlly(id); }; -Player.prototype.SetEnemy = function(id, skipAlliedVictoryCheck = false) +Player.prototype.SetEnemy = function(id) { - this.SetDiplomacyIndex(id, -1, skipAlliedVictoryCheck); + this.SetDiplomacyIndex(id, -1); }; /** @@ -583,9 +633,9 @@ Player.prototype.IsEnemy = function(id) return this.diplomacy[id] < 0; }; -Player.prototype.SetNeutral = function(id, skipAlliedVictoryCheck = false) +Player.prototype.SetNeutral = function(id) { - this.SetDiplomacyIndex(id, 0, skipAlliedVictoryCheck); + this.SetDiplomacyIndex(id, 0); }; /** @@ -649,43 +699,6 @@ Player.prototype.OnGlobalOwnershipChanged = function(msg) } }; -Player.prototype.OnPlayerDefeated = function(msg) -{ - this.state = "defeated"; - - // Reassign all player's entities to Gaia - var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); - var entities = cmpRangeManager.GetEntitiesByPlayer(this.playerID); - - // The ownership change is done in two steps so that entities don't hit idle - // (and thus possibly look for "enemies" to attack) before nearby allies get - // converted to Gaia as well. - for (var entity of entities) - { - var cmpOwnership = Engine.QueryInterface(entity, IID_Ownership); - cmpOwnership.SetOwnerQuiet(0); - } - - // With the real ownership change complete, send OwnershipChanged messages. - for (var entity of entities) - Engine.PostMessage(entity, MT_OwnershipChanged, { - "entity": entity, - "from": this.playerID, - "to": 0 - }); - - // Reveal the map for this player. - cmpRangeManager.SetLosRevealAll(this.playerID, true); - - // Send a chat message notifying of the player's defeat. - var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); - cmpGUIInterface.PushNotification({ - "type": "defeat", - "players": [this.playerID], - "resign": !!msg.resign - }); -}; - Player.prototype.OnResearchFinished = function(msg) { if (msg.tech == this.template.SharedLosTech) diff --git a/binaries/data/mods/public/simulation/components/PlayerManager.js b/binaries/data/mods/public/simulation/components/PlayerManager.js index 98ce644f2e..a9f898e28e 100644 --- a/binaries/data/mods/public/simulation/components/PlayerManager.js +++ b/binaries/data/mods/public/simulation/components/PlayerManager.js @@ -23,7 +23,7 @@ PlayerManager.prototype.AddPlayer = function(ent) newDiplo[i] = -1; } newDiplo[id] = 1; - cmpPlayer.SetDiplomacy(newDiplo, true); + cmpPlayer.SetDiplomacy(newDiplo); return id; }; diff --git a/binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js b/binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js index ec84ddd9ee..82a126cbca 100644 --- a/binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js +++ b/binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js @@ -1,3 +1,4 @@ Engine.RegisterInterface("EndGameManager"); Engine.RegisterMessageType("PlayerDefeated"); +Engine.RegisterMessageType("PlayerWon"); Engine.RegisterMessageType("GameTypeChanged"); diff --git a/binaries/data/mods/public/simulation/helpers/Cheat.js b/binaries/data/mods/public/simulation/helpers/Cheat.js index f3164db5e3..0624478afa 100644 --- a/binaries/data/mods/public/simulation/helpers/Cheat.js +++ b/binaries/data/mods/public/simulation/helpers/Cheat.js @@ -48,10 +48,9 @@ function Cheat(input) } return; case "defeatplayer": - var playerEnt = cmpPlayerManager.GetPlayerByID(input.parameter); - if (playerEnt == INVALID_ENTITY) - return; - Engine.PostMessage(playerEnt, MT_PlayerDefeated, { "playerId": input.parameter }); + cmpPlayer = QueryPlayerIDInterface(input.parameter); + if (cmpPlayer) + cmpPlayer.SetState("defeated"); return; case "createunits": var cmpProductionQueue = input.selected.length && Engine.QueryInterface(input.selected[0], IID_ProductionQueue); diff --git a/binaries/data/mods/public/simulation/helpers/Commands.js b/binaries/data/mods/public/simulation/helpers/Commands.js index 5ccb3a957c..fba68fed70 100644 --- a/binaries/data/mods/public/simulation/helpers/Commands.js +++ b/binaries/data/mods/public/simulation/helpers/Commands.js @@ -414,8 +414,9 @@ var g_Commands = { "defeat-player": function(player, cmd, data) { - // Send "OnPlayerDefeated" message to player - Engine.PostMessage(data.playerEnt, MT_PlayerDefeated, { "playerId": player, "resign": !!cmd.resign }); + let cmpPlayer = QueryPlayerIDInterface(player); + if (cmpPlayer) + cmpPlayer.SetState("defeated", !!cmd.resign); }, "garrison": function(player, cmd, data) diff --git a/binaries/data/mods/public/simulation/helpers/Player.js b/binaries/data/mods/public/simulation/helpers/Player.js index 951a457759..833176f059 100644 --- a/binaries/data/mods/public/simulation/helpers/Player.js +++ b/binaries/data/mods/public/simulation/helpers/Player.js @@ -123,7 +123,7 @@ function LoadPlayerSettings(settings, newPlayers) // If diplomacy explicitly defined, use that; otherwise use teams if (getSetting(playerData, playerDefaults, i, "Diplomacy") !== undefined) - cmpPlayer.SetDiplomacy(getSetting(playerData, playerDefaults, i, "Diplomacy"), true); + cmpPlayer.SetDiplomacy(getSetting(playerData, playerDefaults, i, "Diplomacy")); else { // Init diplomacy @@ -137,7 +137,7 @@ function LoadPlayerSettings(settings, newPlayers) else cmpPlayer.SetEnemy(j); } - cmpPlayer.SetTeam(myTeam === undefined ? -1 : myTeam, true); + cmpPlayer.SetTeam(myTeam === undefined ? -1 : myTeam); } // If formations explicitly defined, use that; otherwise use civ defaults