mirror of
https://gitea.wildfiregames.com/0ad/0ad
synced 2026-06-16 05:13:58 -07:00
Win and defeat cleanup, fixes #4013.
Add a new simulation message and chat notification for players who won. Avoid duplicate playerstate messages in the sim and GUI by triggering changes with a function instead of a message. Reveal the map on defeat/win exclusively in the player component (instead of having a silly GUI proxy and doing it also in the EndGameManager sometimes). Remove the skipAlliedVictory argument from the player component, since that shouldn't contain references to the EndGameManager, refs #3970. Show a proper message box on win/loss and add the hint for hosts disconnecting other players. Do defeat/win procedure in the GUI when such a message arrives, instead of checking onTick for playerstate changes. Thus don't show that confirmation again on every rejoin. Don't show a pointless message box if IsAtlasRunning. Explain that the session.js variable is needed to avoid an order-of-execution bug. Select "observer" item when rejoining as a defeated player. Remove an unneeded call to updateTopPanel. This was SVN commit r18441.
This commit is contained in:
parent
8da8d28102
commit
9f796068f8
12 changed files with 211 additions and 199 deletions
|
|
@ -755,6 +755,7 @@ function toggleDeveloperOverlay()
|
|||
|
||||
function closeOpenDialogs()
|
||||
{
|
||||
// TODO: also close message boxes
|
||||
closeMenu();
|
||||
closeChat();
|
||||
closeDiplomacy();
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ PlayerManager.prototype.AddPlayer = function(ent)
|
|||
newDiplo[i] = -1;
|
||||
}
|
||||
newDiplo[id] = 1;
|
||||
cmpPlayer.SetDiplomacy(newDiplo, true);
|
||||
cmpPlayer.SetDiplomacy(newDiplo);
|
||||
|
||||
return id;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
Engine.RegisterInterface("EndGameManager");
|
||||
Engine.RegisterMessageType("PlayerDefeated");
|
||||
Engine.RegisterMessageType("PlayerWon");
|
||||
Engine.RegisterMessageType("GameTypeChanged");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue