Ticket #1090: playercomponent_savegamesummaryreplaycleanup.patch
File playercomponent_savegamesummaryreplaycleanup.patch, 45.1 KB (added by , 8 years ago) |
---|
-
binaries/data/mods/public/gui/common/functions_utility.js
function clearChatMessages() 206 206 } 207 207 } 208 208 209 209 /** 210 210 * Returns a formatted string describing the player assignments. 211 * Including civs, teams, AI settings and player colors 212 * which are given in data (array of objects per player). 211 * Needs g_CivData to translate! 213 212 * 213 * @param {object} playerDataArray - As known from gamesetup and simstate. 214 * @param {(string[]|false)} playerStates - One of "won", "defeated", "active" for each player. 214 215 * @returns {string} 215 216 */ 216 function formatPlayerInfo( data)217 function formatPlayerInfo(playerDataArray, playerStates) 217 218 { 218 219 let playerDescriptions = {}; 219 220 let playerIdx = 0; 220 for (let playerData of data) 221 222 for (let playerData of playerDataArray) 221 223 { 224 if (playerData == null || playerData.Civ == "gaia") 225 continue; 226 222 227 ++playerIdx; 223 228 let teamIdx = playerData.Team; 224 let showDefeated = playerData.state && playerData.state == "defeated";225 229 let isAI = playerData.AI && playerData.AI != ""; 230 let playerState = playerStates && playerStates[playerIdx]; 231 let isActive = !playerState || playerState == "active"; 226 232 227 let translated; 228 if (!isAI && !showDefeated) 229 translated = translateWithContext("replay", "%(playerName)s (%(civ)s)"); 230 else if (!isAI && showDefeated) 231 translated = translateWithContext("replay", "%(playerName)s (%(civ)s, defeated)"); 232 else if (isAI && !showDefeated) 233 translated = translateWithContext("replay", "%(playerName)s (%(civ)s, %(AIdifficulty)s %(AIname)s)"); 233 let playerDescription; 234 if (isAI) 235 { 236 if (isActive) 237 playerDescription = translateWithContext("replay", "%(playerName)s (%(civ)s, %(AIdifficulty)s %(AIname)s, %(state)s)"); 238 else 239 playerDescription = translateWithContext("replay", "%(playerName)s (%(civ)s, %(AIdifficulty)s %(AIname)s)"); 240 } 234 241 else 235 translated = translateWithContext("replay", "%(playerName)s (%(civ)s, %(AIdifficulty)s %(AIname)s, defeated)"); 242 { 243 if (isActive) 244 playerDescription = translateWithContext("replay", "%(playerName)s (%(civ)s, %(state)s)"); 245 else 246 playerDescription = translateWithContext("replay", "%(playerName)s (%(civ)s)"); 247 } 236 248 237 249 // Sort player descriptions by team 238 250 if (!playerDescriptions[teamIdx]) 239 251 playerDescriptions[teamIdx] = []; 240 playerDescriptions[teamIdx].push(sprintf(translated, { 241 "playerName": '[color="' + rgbToGuiColor(playerData.Color) + '"]' + escapeText(playerData.Name) + "[/color]", 242 "civ": playerData.Civ, 252 253 playerDescriptions[teamIdx].push(sprintf(playerDescription, { 254 "playerName": 255 '[color="' + 256 rgbToGuiColor(playerData.Color || g_Settings.PlayerDefaults[playerIdx].Color) + 257 '"]' + escapeText(playerData.Name) + "[/color]", 258 259 "civ": 260 !playerData.Civ ? 261 translate("Unknown Civilization") : 262 g_CivData && g_CivData[playerData.Civ] && g_CivData[playerData.Civ].Name ? 263 translate(g_CivData[playerData.Civ].Name) : 264 playerData.Civ, 265 266 "state": 267 playerState == "defeated" ? 268 translateWithContext("playerState", "Defeated") : 269 translateWithContext("playerState", "Won"), 270 243 271 "AIname": isAI ? translateAIName(playerData.AI) : "", 244 272 "AIdifficulty": isAI ? translateAIDifficulty(playerData.AIDiff) : "" 245 273 })); 246 274 } 247 275 … … function formatPlayerInfo(data) 251 279 if (teams.length == 1) 252 280 return playerDescriptions[teams[0]].join("\n") + "\n"; 253 281 254 282 // If there are teams, merge "Team N:" + playerDescriptions 255 283 return teams.map(team => { 256 let teamCaption = (team == -1) ? translate("No Team") : sprintf(translate("Team %(team)s"), { "team": +team + 1 }); 257 return '[font="sans-bold-14"]' + teamCaption + "[/font]:\n" + playerDescriptions[team].join("\n"); 284 285 let teamCaption = team == -1 ? 286 translate("No Team") : 287 sprintf(translate("Team %(team)s"), { "team": +team + 1 }); 288 289 return sprintf(translateWithContext("replay", "%(team)s:\n%(playerDescriptions)s"), { 290 "team": '[font="sans-bold-14"]' + teamCaption + "[/font]", 291 "playerDescriptions": playerDescriptions[team].join("\n") 292 }); 258 293 }).join("\n\n"); 259 294 } -
binaries/data/mods/public/gui/replaymenu/replay_menu.js
2 2 * Used for checking replay compatibility. 3 3 */ 4 4 const g_EngineInfo = Engine.GetEngineInfo(); 5 5 6 6 /** 7 * To show the titles of the selected civs in the replaydetails.7 * Needed for formatPlayerInfo to show the player civs in the details. 8 8 */ 9 9 const g_CivData = loadCivData(); 10 10 11 11 /** 12 12 * Used for creating the mapsize filter. … … function displayReplayList() 188 188 if (replaySelection.selected != -1) 189 189 g_SelectedReplayDirectory = g_ReplaysFiltered[replaySelection.selected].directory; 190 190 191 191 filterReplays(); 192 192 193 // Create GUI list data194 193 var list = g_ReplaysFiltered.map(replay => { 195 194 let works = replay.isCompatible; 196 195 return { 197 196 "directories": replay.directory, 198 197 "months": greyout(getReplayDateTime(replay), works), … … function displayReplayList() 202 201 "durations": greyout(getReplayDuration(replay), works), 203 202 "playerNames": greyout(getReplayPlayernames(replay), works) 204 203 }; 205 204 }); 206 205 207 // Extract arrays208 206 if (list.length) 209 207 list = prepareForDropdown(list); 210 208 211 209 // Push to GUI 212 210 replaySelection.selected = -1; … … function displayReplayList() 219 217 220 218 // Change these last, otherwise crash 221 219 replaySelection.list = list.directories || []; 222 220 replaySelection.list_data = list.directories || []; 223 221 224 // Restore selection225 222 replaySelection.selected = replaySelection.list.findIndex(directory => directory == g_SelectedReplayDirectory); 226 223 227 224 displayReplayDetails(); 228 225 } 229 226 230 227 /** 231 228 * Shows preview image, description and player text in the right panel. 232 229 */ 233 230 function displayReplayDetails() 234 231 { 235 varselected = Engine.GetGUIObjectByName("replaySelection").selected;236 varreplaySelected = selected > -1;232 let selected = Engine.GetGUIObjectByName("replaySelection").selected; 233 let replaySelected = selected > -1; 237 234 238 235 Engine.GetGUIObjectByName("replayInfo").hidden = !replaySelected; 239 236 Engine.GetGUIObjectByName("replayInfoEmpty").hidden = replaySelected; 240 237 Engine.GetGUIObjectByName("startReplayButton").enabled = replaySelected; 241 238 Engine.GetGUIObjectByName("deleteReplayButton").enabled = replaySelected; 242 239 Engine.GetGUIObjectByName("summaryButton").hidden = true; 243 240 244 241 if (!replaySelected) 245 242 return; 246 243 247 var replay = g_ReplaysFiltered[selected]; 248 var mapData = getMapDescriptionAndPreview(replay.attribs.settings.mapType, replay.attribs.map); 244 let replay = g_ReplaysFiltered[selected]; 249 245 250 // Update GUI251 246 Engine.GetGUIObjectByName("sgMapName").caption = translate(replay.attribs.settings.Name); 252 247 Engine.GetGUIObjectByName("sgMapSize").caption = translateMapSize(replay.attribs.settings.Size); 253 248 Engine.GetGUIObjectByName("sgMapType").caption = translateMapType(replay.attribs.settings.mapType); 254 249 Engine.GetGUIObjectByName("sgVictory").caption = translateVictoryCondition(replay.attribs.settings.GameType); 255 250 Engine.GetGUIObjectByName("sgNbPlayers").caption = replay.attribs.settings.PlayerData.length; 256 Engine.GetGUIObjectByName("sgPlayersNames").caption = getReplayTeamText(replay); 251 252 let metadata = Engine.GetReplayMetadata(replay.directory); 253 let mapData = getMapDescriptionAndPreview(replay.attribs.settings.mapType, replay.attribs.map); 254 let playerStates = 255 Engine.GetGUIObjectByName("showSpoiler").checked && 256 metadata && 257 metadata.playerStates && 258 metadata.playerStates.map(pState => pState.state); 259 260 Engine.GetGUIObjectByName("sgPlayersNames").caption = formatPlayerInfo(replay.attribs.settings.PlayerData, playerStates); 257 261 Engine.GetGUIObjectByName("sgMapDescription").caption = mapData.description; 258 262 Engine.GetGUIObjectByName("summaryButton").hidden = !Engine.HasReplayMetadata(replay.directory); 259 263 260 264 setMapPreviewImage("sgMapPreview", mapData.preview); 261 265 } … … function isReplayCompatible(replay) 329 333 */ 330 334 function replayHasSameEngineVersion(replay) 331 335 { 332 336 return replay.attribs.engine_version && replay.attribs.engine_version == g_EngineInfo.engine_version; 333 337 } 334 335 /**336 * Returns a description of the player assignments.337 * Including civs, teams, AI settings and player colors.338 *339 * If the spoiler-checkbox is checked, it also shows defeated players.340 *341 * @returns {string}342 */343 function getReplayTeamText(replay)344 {345 // Load replay metadata346 const metadata = Engine.GetReplayMetadata(replay.directory);347 const spoiler = Engine.GetGUIObjectByName("showSpoiler").checked;348 349 let data = [];350 let playerIdx = 0;351 for (let playerData of replay.attribs.settings.PlayerData)352 {353 ++playerIdx;354 data.push({355 "Team": playerData.Team,356 "Name": playerData.Name,357 "Civ": !playerData.Civ ? translate("Unknown Civilization") :358 (g_CivData[playerData.Civ] && g_CivData[playerData.Civ].Name ? translate(g_CivData[playerData.Civ].Name) : playerData.Civ),359 "Color": playerData.Color ? playerData.Color : g_Settings.PlayerDefaults[playerIdx].Color,360 "AI": playerData.AI,361 "AIDiff": playerData.AIDiff,362 "Defeated": spoiler && metadata && metadata.playerStates && metadata.playerStates[playerIdx].state == "defeated"363 });364 }365 366 return formatPlayerInfo(data);367 } -
binaries/data/mods/public/gui/savedgames/load.js
1 1 var g_SavedGamesMetadata = []; 2 2 3 /** 4 * Needed for formatPlayerInfo to show the player civs in the details. 5 */ 6 const g_CivData = loadCivData(); 7 3 8 function init() 4 9 { 5 10 let gameSelection = Engine.GetGUIObjectByName("gameSelection"); 6 11 7 12 let savedGames = Engine.GetSavedGames().sort(sortDecreasingDate); … … function selectionChanged() 56 61 let caption = sprintf(translate("Mods: %(mods)s"), { "mods": metadata.mods.join(translate(", ")) }); 57 62 if (!hasSameMods(metadata, Engine.GetEngineInfo())) 58 63 caption = "[color=\"orange\"]" + caption + "[/color]"; 59 64 Engine.GetGUIObjectByName("savedMods").caption = caption; 60 65 61 let data = []; 62 let playerIdx = 0; 63 for (let playerData of metadata.initAttributes.settings.PlayerData) 64 { 65 if (playerData == null || playerData.Civ == "gaia") 66 continue; 67 ++playerIdx; 68 data.push({ 69 "Team": playerData.Team, 70 "Name": playerData.Name, 71 "Civ": playerData.Civ, 72 "Color": playerData.Color, 73 "AI": playerData.AI, 74 "AIDiff": playerData.AIDiff, 75 "Defeated": metadata.gui.states && metadata.gui.states[playerIdx] == "defeated" 76 }); 77 } 78 79 Engine.GetGUIObjectByName("savedPlayersNames").caption = formatPlayerInfo(data); 66 Engine.GetGUIObjectByName("savedPlayersNames").caption = formatPlayerInfo( 67 metadata.initAttributes.settings.PlayerData, 68 metadata.gui.states 69 ); 80 70 } 81 71 82 72 function loadGame() 83 73 { 84 74 let gameSelection = Engine.GetGUIObjectByName("gameSelection"); -
binaries/data/mods/public/gui/savedgames/load.xml
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 3 3 <objects> 4 4 5 5 <script file="gui/common/color.js" /> 6 <script file="gui/common/functions_civinfo.js"/> 6 7 <script file="gui/common/functions_global_object.js" /> 7 8 <script file="gui/common/functions_utility.js" /> 8 9 <script file="gui/common/functions_utility_loadsave.js" /> 9 10 <script file="gui/common/settings.js" /> 10 11 <script file="gui/savedgames/load.js" /> … … 28 29 <action on="Press">Engine.PopGuiPage();</action> 29 30 </object> 30 31 31 32 <object name="deleteGameButton" type="button" size="33%+20 100%-60 66%-15 100%-32" style="StoneButton" hotkey="session.savedgames.delete"> 32 33 <translatableAttribute id="caption">Delete</translatableAttribute> 33 <action on="Press"> 34 if (!this.enabled) 35 return; 36 if (Engine.HotkeyIsPressed("session.savedgames.noconfirmation")) 37 deleteGameWithoutConfirmation(); 38 else 39 deleteGame(); 40 </action> 34 <action on="Press">deleteGame();</action> 41 35 </object> 42 36 43 37 <object name="loadGameButton" type="button" style="StoneButton" size="66%-5 100%-60 100%-25 100%-32"> 44 38 <translatableAttribute id="caption">Load</translatableAttribute> 45 39 <action on="Press">loadGame();</action> -
binaries/data/mods/public/gui/savedgames/save.js
function selectDescription() 15 15 function init(data) 16 16 { 17 17 g_SavedGameData = data && data.savedGameData || {}; 18 18 let simulationState = Engine.GuiInterfaceCall("GetSimulationState"); 19 19 g_SavedGameData.timeElapsed = simulationState.timeElapsed; 20 g_SavedGameData.states = []; 21 for (let player of simulationState.players) 22 g_SavedGameData.states.push(player.state); 20 g_SavedGameData.states = simulationState.players.map(pState => pState.state); 23 21 24 22 let gameSelection = Engine.GetGUIObjectByName("gameSelection"); 25 23 Engine.GetGUIObjectByName("deleteGameButton").enabled = false; 26 24 27 25 let savedGames = Engine.GetSavedGames().sort(sortDecreasingDate); -
binaries/data/mods/public/gui/session/messages.js
var g_FormatChatMessage = { 99 99 } 100 100 ), 101 101 "clientlist": msg => getUsernameList(), 102 102 "message": msg => formatChatCommand(msg), 103 103 "defeat": msg => formatDefeatMessage(msg), 104 "won": msg => formatWonMessage(msg), 104 105 "diplomacy": msg => formatDiplomacyMessage(msg), 105 106 "tribute": msg => formatTributeMessage(msg), 106 107 "attack": msg => formatAttackMessage(msg) 107 108 }; 108 109 … … var g_NotificationsTypes = 244 245 "type": "defeat", 245 246 "guid": findGuidForPlayerID(player), 246 247 "player": player, 247 248 "resign": !!notification.resign 248 249 }); 249 250 updateDiplomacy(); 251 updateChatAddressees(); 250 playerFinished(player, false); 251 }, 252 "won": function(notification, player) 253 { 254 addChatMessage({ 255 "type": "won", 256 "guid": findGuidForPlayerID(player), 257 "player": player 258 }); 259 playerFinished(player, true); 252 260 }, 253 261 "diplomacy": function(notification, player) 254 262 { 255 263 addChatMessage({ 256 264 "type": "diplomacy", … … function formatDefeatMessage(msg) 743 751 translate("%(player)s has been defeated."), 744 752 { "player": colorizePlayernameByID(msg.player) } 745 753 ); 746 754 } 747 755 756 function formatWonMessage(msg) 757 { 758 return sprintf(translate("%(player)s has won."), { 759 "player": colorizePlayernameByID(msg.player) 760 }); 761 } 762 748 763 function formatDiplomacyMessage(msg) 749 764 { 750 765 let messageType; 751 766 752 767 if (g_IsObserver) -
binaries/data/mods/public/gui/session/session.js
var g_EntityStates = {}; 117 117 var g_TemplateData = {}; 118 118 var g_TemplateDataWithoutLocalization = {}; 119 119 var g_TechnologyData = {}; 120 120 121 121 /** 122 * Cache concatenated list of player states ("active", "defeated" or "won").123 */124 var g_CachedLastStates = "";125 126 /**127 * Whether the current player has lost/won and reached the end of their game.128 * Used for reporting the gamestate and showing the game-end message only once.129 */130 var g_GameEnded = false;131 132 /**133 122 * Top coordinate of the research list. 134 123 * Changes depending on the number of displayed counters. 135 124 */ 136 125 var g_ResearchListTop = 4; 137 126 … … function init(initData, hotloadData) 238 227 g_PlayerAssignments = initData.playerAssignments; 239 228 g_MatchID = initData.attribs.matchID; 240 229 g_ReplaySelectionData = initData.replaySelectionData; 241 230 g_HasRejoined = initData.isRejoining; 242 231 243 g_Players = getPlayerData();244 245 232 if (initData.savedGUIData) 246 233 restoreSavedGameData(initData.savedGUIData); 247 234 248 235 Engine.GetGUIObjectByName("gameSpeedButton").hidden = g_IsNetworked; 249 236 } 250 237 else // Needed for autostart loading option 251 238 { 252 239 if (g_IsReplay) 253 240 g_PlayerAssignments.local.player = -1; 254 255 g_Players = getPlayerData();256 241 } 257 242 243 g_Players = getPlayerData(); 244 258 245 g_CivData = loadCivData(); 259 246 g_CivData.gaia = { "Code": "gaia", "Name": translate("Gaia") }; 260 247 261 248 initializeMusic(); // before changing the perspective 262 249 selectViewPlayer(g_ViewedPlayer); … … function controlsPlayer(playerID) 433 420 return playerState && ( 434 421 playerState.state != "defeated" || playerState.controlsAll); 435 422 } 436 423 437 424 /** 425 * Called when a player has won or was defeated. 426 */ 427 function playerFinished(player, won) 428 { 429 reportGame(); 430 updateDiplomacy(); 431 updateChatAddressees(); 432 433 if (player != Engine.GetPlayerID() || Engine.IsAtlasRunning()) 434 return; 435 436 global.music.setState( 437 won ? 438 global.music.states.VICTORY : 439 global.music.states.DEFEAT 440 ); 441 442 closeOpenDialogs(); 443 444 // Select observermode 445 if (!won) 446 Engine.GetGUIObjectByName("viewPlayer").selected = 0; 447 448 messageBox( 449 400, 200, 450 g_IsNetworked && g_IsController ? 451 translate("Do you want to quit? Leaving will disconnect all other players.") : 452 translate("Do you want to quit?"), 453 won ? 454 translate("VICTORIOUS!") : 455 translate("DEFEATED!"), 456 [translate("No"), translate("Yes")], 457 [null, leaveGame] 458 ); 459 } 460 461 /** 438 462 * Sets civ icon for the currently viewed player. 439 463 * Hides most gui objects for observers. 440 464 */ 441 465 function updateTopPanel() 442 466 { … … function resignGame(leaveGameAfterResign 505 529 * @param willRejoin If player is going to be rejoining a networked game. 506 530 */ 507 531 function leaveGame(willRejoin) 508 532 { 509 533 let extendedSimState = Engine.GuiInterfaceCall("GetExtendedSimulationState"); 510 let mapSettings = Engine.GetMapSettings(); 511 let gameResult; 512 513 if (Engine.GetPlayerID() == -1) 514 { 515 gameResult = translate("You have left the game."); 516 global.music.setState(global.music.states.VICTORY); 517 } 518 else 519 { 520 let playerState = extendedSimState.players[Engine.GetPlayerID()]; 521 if (g_Disconnected) 522 gameResult = translate("You have been disconnected."); 523 else if (playerState.state == "won") 524 gameResult = translate("You have won the battle!"); 525 else if (playerState.state == "defeated") 526 gameResult = translate("You have been defeated..."); 527 else // "active" 528 { 529 global.music.setState(global.music.states.DEFEAT); 530 if (willRejoin) 531 gameResult = translate("You have left the game."); 532 else 533 { 534 gameResult = translate("You have abandoned the game."); 535 resignGame(true); 536 } 537 } 538 } 539 540 let summary = { 534 let simData = { 541 535 "timeElapsed" : extendedSimState.timeElapsed, 542 536 "playerStates": extendedSimState.players, 543 "players": g_Players, 544 "mapSettings": Engine.GetMapSettings(), 537 "mapSettings": Engine.GetMapSettings() 545 538 }; 546 539 547 540 if (!g_IsReplay) 548 Engine.SaveReplayMetadata(JSON.stringify(s ummary));541 Engine.SaveReplayMetadata(JSON.stringify(simData)); 549 542 550 if (!g_HasRejoined) 551 summary.replayDirectory = Engine.GetCurrentReplayDirectory(); 552 summary.replaySelectionData = g_ReplaySelectionData; 543 let guiData = { 544 "assignedPlayer": Engine.GetPlayerID(), 545 "disconnected": g_Disconnected, 546 "isReplay": g_IsReplay, 547 "replayDirectory": !g_HasRejoined && Engine.GetCurrentReplayDirectory(), 548 "replaySelectionData": g_ReplaySelectionData, 549 }; 550 551 if (!willRejoin && 552 simData[Engine.GetPlayerID()] && 553 simData[Engine.GetPlayerID()].state == "active") 554 resignGame(true); 553 555 554 556 Engine.EndGame(); 555 557 556 558 if (g_IsController && Engine.HasXmppClient()) 557 559 Engine.SendUnregisterGame(); 558 560 559 summary.gameResult = gameResult; 560 summary.isReplay = g_IsReplay; 561 Engine.SwitchGuiPage("page_summary.xml", summary); 561 Engine.SwitchGuiPage("page_summary.xml", { 562 "gui": guiData, 563 "sim": simData 564 }); 562 565 } 563 566 564 567 // Return some data that we'll use when hotloading this file after changes 565 568 function getHotloadData() 566 569 { … … function onTick() 603 606 604 607 let now = new Date(); 605 608 let tickLength = new Date() - lastTickTime; 606 609 lastTickTime = now; 607 610 608 checkPlayerState();609 610 611 handleNetMessages(); 611 612 612 613 updateCursorAndTooltip(); 613 614 614 615 if (g_Selection.dirty) … … function onTick() 630 631 Engine.GetGUIObjectByName("resourcePop").textcolor = g_IsTrainingBlocked && Date.now() % 1000 < 500 ? g_PopulationAlertColor : g_DefaultPopulationColor; 631 632 632 633 Engine.GuiInterfaceCall("ClearRenamedEntities"); 633 634 } 634 635 635 function checkPlayerState()636 {637 if (g_GameEnded || Engine.GetPlayerID() < 1)638 return;639 640 // Send a game report for each player in this game.641 let m_simState = GetSimState();642 let playerState = m_simState.players[Engine.GetPlayerID()];643 let tempStates = "";644 for (let player of m_simState.players)645 tempStates += player.state + ",";646 647 if (g_CachedLastStates != tempStates)648 {649 g_CachedLastStates = tempStates;650 reportGame();651 }652 653 if (playerState.state == "active")654 return;655 656 // Make sure nothing is open to avoid stacking.657 closeOpenDialogs();658 659 // Make sure this doesn't run again.660 g_GameEnded = true;661 662 // Select observermode663 Engine.GetGUIObjectByName("viewPlayer").selected = playerState.state == "won" ? g_ViewedPlayer + 1 : 0;664 665 let btCaptions;666 let btCode;667 let message;668 let title;669 if (Engine.IsAtlasRunning())670 {671 // If we're in Atlas, we can't leave the game672 btCaptions = [translate("OK")];673 btCode = [null];674 message = translate("Press OK to continue");675 }676 else677 {678 btCaptions = [translate("No"), translate("Yes")];679 btCode = [null, leaveGame];680 message = translate("Do you want to quit?");681 }682 683 if (playerState.state == "defeated")684 {685 title = translate("DEFEATED!");686 global.music.setState(global.music.states.DEFEAT);687 }688 else if (playerState.state == "won")689 {690 title = translate("VICTORIOUS!");691 global.music.setState(global.music.states.VICTORY);692 // TODO: Reveal map directly instead of this silly proxy.693 if (!Engine.GetGUIObjectByName("devCommandsRevealMap").checked)694 Engine.GetGUIObjectByName("devCommandsRevealMap").checked = true;695 }696 697 messageBox(400, 200, message, title, btCaptions, btCode);698 }699 700 636 function changeGameSpeed(speed) 701 637 { 702 638 if (!g_IsNetworked) 703 639 Engine.SetSimRate(speed); 704 640 } … … function onSimulationUpdate() 735 671 736 672 if (!g_SimState) 737 673 return; 738 674 739 675 handleNotifications(); 740 741 676 updateGUIObjects(); 742 677 } 743 678 744 679 function updateGUIObjects() 745 680 { … … function updateGUIObjects() 768 703 let playerState = GetSimState().players[g_ViewedPlayer]; 769 704 g_DevSettings.controlAll = playerState && playerState.controlsAll; 770 705 Engine.GetGUIObjectByName("devControlAll").checked = g_DevSettings.controlAll; 771 706 } 772 707 773 if ( g_ViewedPlayer != -1 && !g_GameEnded)708 if (!g_IsObserver) 774 709 { 775 710 // Update music state on basis of battle state. 776 711 let battleState = Engine.GuiInterfaceCall("GetBattleState", g_ViewedPlayer); 777 712 if (battleState) 778 713 global.music.setState(global.music.states[battleState]); … … function updateGUIStatusBar(nameOfBar, p 826 761 healthSize.rtop = value; 827 762 828 763 statusBar.size = healthSize; 829 764 } 830 765 831 832 766 function updateHeroes() 833 767 { 834 768 let playerState = GetSimState().players[g_ViewedPlayer]; 835 769 let heroes = playerState ? playerState.heroes : []; 836 770 … … function playAmbient() 1140 1074 Engine.PlayAmbientSound(g_Ambient[Math.floor(Math.random() * g_Ambient.length)], true); 1141 1075 } 1142 1076 1143 1077 function getBuildString() 1144 1078 { 1145 return sprintf(translate("Build: %(buildDate)s (%(revision)s)"), { "buildDate": Engine.GetBuildTimestamp(0), revision: Engine.GetBuildTimestamp(2) }); 1079 return sprintf(translate("Build: %(buildDate)s (%(revision)s)"), { 1080 "buildDate": Engine.GetBuildTimestamp(0), 1081 "revision": Engine.GetBuildTimestamp(2) 1082 }); 1146 1083 } 1147 1084 1148 1085 function showTimeWarpMessageBox() 1149 1086 { 1150 1087 messageBox( … … function showTimeWarpMessageBox() 1158 1095 * Send a report on the gamestatus to the lobby. 1159 1096 */ 1160 1097 function reportGame() 1161 1098 { 1162 1099 // Only 1v1 games are rated (and Gaia is part of g_Players) 1163 if (!Engine.HasXmppClient() || !Engine.IsRankedGame() || g_Players.length != 3) 1100 if (!Engine.HasXmppClient() || !Engine.IsRankedGame() || 1101 g_Players.length != 3 || Engine.GetPlayerID() == -1) 1164 1102 return; 1165 1103 1166 1104 let extendedSimState = Engine.GuiInterfaceCall("GetExtendedSimulationState"); 1167 1105 1168 1106 let unitsClasses = [ -
binaries/data/mods/public/gui/session/utility_functions.js
1 /** 2 * Before removing data, consider this data is partially used in the replay menu. 3 */ 1 4 function getPlayerData(previousData = undefined) 2 5 { 3 6 let players = []; 4 7 5 8 let simState = GetSimState(); -
binaries/data/mods/public/gui/summary/layout.js
function updateGeneralPanelTeams() 315 315 // If there are no players without team, hide "player name" heading 316 316 if (!g_WithoutTeam) 317 317 Engine.GetGUIObjectByName("playerNameHeading").caption = ""; 318 318 } 319 319 320 function updateObjectPlayerPosition()320 function initPlayerBoxPositions() 321 321 { 322 322 for (let h = 0; h < g_MaxPlayers; ++h) 323 323 { 324 324 let playerBox = Engine.GetGUIObjectByName("playerBox[" + h + "]"); 325 325 let boxSize = playerBox.size; -
binaries/data/mods/public/gui/summary/summary.js
function updatePanelData(panelInfo) 80 80 updateGeneralPanelTeams(); 81 81 82 82 let playerBoxesCounts = [ ]; 83 83 for (let i = 0; i < g_PlayerCount; ++i) 84 84 { 85 let playerState = g_GameData. playerStates[i+1];85 let playerState = g_GameData.sim.playerStates[i+1]; 86 86 87 87 if (!playerBoxesCounts[playerState.team+1]) 88 88 playerBoxesCounts[playerState.team+1] = 1; 89 89 else 90 90 playerBoxesCounts[playerState.team+1] += 1; … … function updatePanelData(panelInfo) 104 104 playerCivicBoxColumn = "civIcont[" + playerState.team + "][" + positionObject + "]"; 105 105 playerCounterValue = "valueDataTeam[" + playerState.team + "][" + positionObject + "]"; 106 106 } 107 107 108 108 let colorString = "color: " + 109 110 111 109 Math.floor(playerState.color.r * 255) + " " + 110 Math.floor(playerState.color.g * 255) + " " + 111 Math.floor(playerState.color.b * 255); 112 112 113 113 let rowPlayerObject = Engine.GetGUIObjectByName(rowPlayer); 114 114 rowPlayerObject.hidden = false; 115 115 rowPlayerObject.sprite = colorString + g_PlayerBoxAlpha; 116 116 … … function updatePanelData(panelInfo) 119 119 rowPlayerObject.size = boxSize; 120 120 121 121 let playerColorBox = Engine.GetGUIObjectByName(playerColorBoxColumn); 122 122 playerColorBox.sprite = colorString + g_PlayerColorBoxAlpha; 123 123 124 Engine.GetGUIObjectByName(playerNameColumn).caption = g_GameData. players[i+1].name;124 Engine.GetGUIObjectByName(playerNameColumn).caption = g_GameData.sim.playerStates[i+1].name; 125 125 126 126 let civIcon = Engine.GetGUIObjectByName(playerCivicBoxColumn); 127 127 civIcon.sprite = "stretched:" + g_CivData[playerState.civ].Emblem; 128 128 civIcon.tooltip = g_CivData[playerState.civ].Name; 129 129 … … function updatePanelData(panelInfo) 135 135 let teamCounterFn = panelInfo.teamCounterFn; 136 136 if (g_Teams && teamCounterFn) 137 137 teamCounterFn(panelInfo.counters); 138 138 } 139 139 140 function confirmStartReplay() 141 { 142 if (Engine.HasXmppClient()) 143 messageBox( 144 400, 200, 145 translate("Are you sure you want to quit the lobby?"), 146 translate("Confirmation"), 147 [translate("No"), translate("Yes")], 148 [null, startReplay] 149 ); 150 else 151 startReplay(); 152 } 153 154 function continueButton() 155 { 156 if (g_GameData.gui.isInGame) 157 Engine.PopGuiPageCB(0); 158 else if (g_GameData.gui.isReplay) 159 Engine.SwitchGuiPage("page_replaymenu.xml", { 160 "replaySelectionData": g_GameData.gui.replaySelectionData 161 }); 162 else if (Engine.HasXmppClient()) 163 Engine.SwitchGuiPage("page_lobby.xml"); 164 else 165 Engine.SwitchGuiPage("page_pregame.xml"); 166 } 167 140 168 function startReplay() 141 169 { 142 170 if (Engine.HasXmppClient()) 143 171 Engine.StopXmppClient(); 144 172 145 Engine.StartVisualReplay(g_GameData. replayDirectory);173 Engine.StartVisualReplay(g_GameData.gui.replayDirectory); 146 174 Engine.SwitchGuiPage("page_loading.xml", { 147 "attribs": Engine.GetReplayAttributes(g_GameData. replayDirectory),175 "attribs": Engine.GetReplayAttributes(g_GameData.gui.replayDirectory), 148 176 "isNetworked": false, 149 177 "playerAssignments": { 150 178 "local": { 151 179 "name": singleplayerName(), 152 180 "player": -1 153 181 } 154 182 }, 155 183 "savedGUIData": "", 156 184 "isReplay": true, 157 "replaySelectionData": g_GameData. replaySelectionData185 "replaySelectionData": g_GameData.gui.replaySelectionData 158 186 }); 159 187 } 160 188 161 189 function init(data) 162 190 { 163 updateObjectPlayerPosition();164 191 g_GameData = data; 165 192 166 let mapSize = data.mapSettings.Size && g_Settings.MapSizes.find(size => size.Tiles == data.mapSettings.Size); 167 let mapType = g_Settings.MapTypes.find(mapType => mapType.Name == data.mapSettings.mapType); 193 let assignedState = g_GameData.sim.playerStates[g_GameData.gui.assignedPlayer || -1]; 168 194 195 Engine.GetGUIObjectByName("summaryText").caption = 196 !assignedState ? 197 translate("You have left the game.") : 198 g_GameData.gui.disconnected ? 199 translate("You have been disconnected.") : 200 assignedState.state == "won" ? 201 translate("You have won the battle!") : 202 assignedState.state == "defeated" ? 203 translate("You have been defeated...") : 204 translate("You have abandoned the game."); 205 206 initPlayerBoxPositions(); 207 169 208 Engine.GetGUIObjectByName("timeElapsed").caption = sprintf( 170 209 translate("Game time elapsed: %(time)s"), { 171 "time": timeToString( data.timeElapsed)210 "time": timeToString(g_GameData.sim.timeElapsed) 172 211 }); 173 212 174 Engine.GetGUIObjectByName("summaryText").caption = data.gameResult; 213 let mapType = g_Settings.MapTypes.find(mapType => mapType.Name == g_GameData.sim.mapSettings.mapType); 214 let mapSize = g_Settings.MapSizes.find(size => size.Tiles == g_GameData.sim.mapSettings.Size || 0); 175 215 176 216 Engine.GetGUIObjectByName("mapName").caption = sprintf( 177 217 translate("%(mapName)s - %(mapType)s"), { 178 "mapName": translate( data.mapSettings.Name),218 "mapName": translate(g_GameData.sim.mapSettings.Name), 179 219 "mapType": mapSize ? mapSize.LongName : (mapType ? mapType.Title : "") 180 220 }); 181 221 182 Engine.GetGUIObjectByName("replayButton").hidden = g_GameData. isInGame || !g_GameData.replayDirectory;222 Engine.GetGUIObjectByName("replayButton").hidden = g_GameData.gui.isInGame || !g_GameData.gui.replayDirectory; 183 223 184 224 // Panels 185 g_PlayerCount = data. playerStates.length - 1;225 g_PlayerCount = data.sim.playerStates.length - 1; 186 226 187 if (data. mapSettings.LockTeams)227 if (data.sim.mapSettings.LockTeams) 188 228 { 189 229 // Count teams 190 230 for (let t = 0; t < g_PlayerCount; ++t) 191 231 { 192 let playerTeam = data.playerStates[t+1].team;232 let playerTeam = g_GameData.sim.playerStates[t+1].team; 193 233 g_Teams[playerTeam] = (g_Teams[playerTeam] || 0) + 1; 194 234 } 195 235 196 236 if (g_Teams.length == g_PlayerCount) 197 237 g_Teams = false; // Each player has his own team. Displaying teams makes no sense. … … function init(data) 201 241 202 242 // Erase teams data if teams are not displayed 203 243 if (!g_Teams) 204 244 { 205 245 for (let p = 0; p < g_PlayerCount; ++p) 206 data.playerStates[p+1].team = -1;246 g_GameData.sim.playerStates[p+1].team = -1; 207 247 } 208 248 209 249 g_WithoutTeam = g_PlayerCount; 210 250 if (g_Teams) 211 251 { -
binaries/data/mods/public/gui/summary/summary.xml
1 1 <?xml version="1.0" encoding="utf-8"?> 2 2 3 <!--4 ==========================================5 - POST-GAME SUMMARY SCREEN -6 ==========================================7 -->8 9 3 <objects> 10 4 <script file="gui/common/functions_global_object.js"/> 11 5 <script file="gui/common/functions_civinfo.js"/> 12 6 <script file="gui/common/functions_utility.js"/> 13 7 <script file="gui/common/settings.js"/> … … 162 156 </object> 163 157 </object> 164 158 165 159 <object type="button" name="replayButton" style="ModernButtonRed" size="100%-310 100%-48 100%-170 100%-20"> 166 160 <translatableAttribute id="caption">Replay</translatableAttribute> 167 <action on="Press"><![CDATA[ 168 if (g_GameData.isInGame) 169 return; 170 171 if (Engine.HasXmppClient()) 172 messageBox( 173 400, 200, 174 translate("Are you sure you want to quit the lobby?"), 175 translate("Confirmation"), 176 [translate("No"), translate("Yes")], 177 [null, startReplay] 178 ); 179 else 180 startReplay(); 181 ]]> 182 </action> 161 <action on="Press">confirmStartReplay();</action> 183 162 </object> 184 163 185 164 <object type="button" style="ModernButtonRed" size="100%-160 100%-48 100%-20 100%-20"> 186 165 <translatableAttribute id="caption">Continue</translatableAttribute> 187 <action on="Press"><![CDATA[ 188 if (g_GameData.isInGame) 189 { 190 Engine.PopGuiPageCB(0); 191 } 192 else if (g_GameData.isReplay) 193 { 194 Engine.SwitchGuiPage("page_replaymenu.xml", { "replaySelectionData": g_GameData.replaySelectionData }); 195 } 196 else if (!Engine.HasXmppClient()) 197 { 198 Engine.SwitchGuiPage("page_pregame.xml"); 199 } 200 else 201 { 202 Engine.LobbySetPlayerPresence("available"); 203 Engine.SwitchGuiPage("page_lobby.xml"); 204 } 205 ]]> 206 </action> 166 <action on="Press">continueButton();</action> 207 167 </object> 208 168 </object> 209 169 </objects> -
binaries/data/mods/public/maps/scripts/ConquestCommon.js
Trigger.prototype.ConquestHandlerOwnerSh 23 23 let index = entities.indexOf(msg.entity); 24 24 25 25 if (index >= 0) 26 26 { 27 27 entities.splice(index, 1); 28 if (!entities.length && Engine.QueryInterface(this.conquestEntitiesByPlayer[msg.from].player, IID_Player).GetState() == "active") 29 Engine.PostMessage(this.conquestEntitiesByPlayer[msg.from].player, MT_PlayerDefeated, { "playerId": msg.from } ); 28 if (!entities.length) 29 { 30 let cmpPlayer = QueryPlayerIDInterface(msg.from); 31 if (cmpPlayer) 32 cmpPlayer.SetState("defeated"); 33 } 30 34 } 31 35 } 32 36 33 37 Trigger.prototype.ConquestAddStructure = function(msg) 34 38 { -
binaries/data/mods/public/maps/scripts/TriggerHelper.js
TriggerHelper.SetPlayerWon = function(pl 125 125 /** 126 126 * Defeats a player 127 127 */ 128 128 TriggerHelper.DefeatPlayer = function(playerID) 129 129 { 130 let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 131 let playerEnt = cmpPlayerManager.GetPlayerByID(playerID); 132 133 Engine.PostMessage(playerEnt, MT_PlayerDefeated, { "playerId": playerID } ); 130 let cmpPlayer = QueryPlayerIDInterface(playerID); 131 if (cmpPlayer) 132 cmpPlayer.SetState("defeated"); 134 133 }; 135 134 136 135 /** 137 136 * Returns the number of current players 138 137 */ -
binaries/data/mods/public/simulation/components/EndGameManager.js
1 1 /** 2 * System component which regularly checks victory/defeat conditions 3 * and ifthey are satisfied then it marks the player as victorious/defeated.2 * System component which regularly checks victory/defeat conditions and if 3 * they are satisfied then it marks the player as victorious/defeated. 4 4 */ 5 5 function EndGameManager() {} 6 6 7 7 EndGameManager.prototype.Schema = 8 8 "<a:component type='system'/><empty/>"; … … EndGameManager.prototype.MarkPlayerAsWon 50 50 let cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); 51 51 let numPlayers = cmpPlayerManager.GetNumPlayers(); 52 52 53 53 for (let i = 1; i < numPlayers; ++i) 54 54 { 55 let playerEntityId = cmpPlayerManager.GetPlayerByID(i); 56 let cmpPlayer = Engine.QueryInterface(playerEntityId, IID_Player); 55 let cmpPlayer = QueryPlayerIDInterface(i); 57 56 58 if (cmpPlayer.GetState() != "active") 59 continue; 60 61 if (playerID == cmpPlayer.GetPlayerID() || this.alliedVictory && cmpPlayer.IsMutualAlly(playerID)) 57 if (playerID == i || this.alliedVictory && cmpPlayer.IsMutualAlly(playerID)) 62 58 cmpPlayer.SetState("won"); 63 59 else 64 Engine.PostMessage(playerEntityId, MT_PlayerDefeated, { 65 "playerId": i, 66 "skipAlliedVictoryCheck": true 67 }); 60 cmpPlayer.SetState("defeated"); 68 61 } 69 70 // Reveal the map to all players71 let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);72 cmpRangeManager.SetLosRevealAll(-1, true);73 62 }; 74 63 75 64 EndGameManager.prototype.SetAlliedVictory = function(flag) 76 65 { 77 66 this.alliedVictory = flag; … … EndGameManager.prototype.AlliedVictoryCh 99 88 100 89 allies.push(playerID); 101 90 } 102 91 103 92 if (this.alliedVictory || allies.length == 1) 104 {105 93 for (let playerID of allies) 106 94 { 107 95 let cmpPlayer = QueryPlayerIDInterface(playerID); 108 96 if (cmpPlayer) 109 97 cmpPlayer.SetState("won"); 110 98 } 111 112 let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);113 if (cmpRangeManager)114 cmpRangeManager.SetLosRevealAll(-1, true);115 }116 99 else 117 100 this.lastManStandingMessage = cmpGuiInterface.AddTimeNotification({ 118 101 "message": markForTranslation("Last remaining player wins."), 119 102 "translateMessage": true, 120 103 }, 12 * 60 * 60 * 1000); // 12 hours -
binaries/data/mods/public/simulation/components/Player.js
Player.prototype.SetTradingGoods = funct 357 357 Player.prototype.GetState = function() 358 358 { 359 359 return this.state; 360 360 }; 361 361 362 Player.prototype.SetState = function(newState )362 Player.prototype.SetState = function(newState, resign, skipAlliedVictoryCheck) 363 363 { 364 if (this.state != "active") 365 return; 366 367 if (newState != "won" && newState != "defeated") 368 { 369 warn("Can't change playerstate to " + this.state); 370 return; 371 } 372 364 373 this.state = newState; 374 375 let won = newState == "won"; 376 377 // Reveal map to all or only that player 378 let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); 379 cmpRangeManager.SetLosRevealAll(won ? -1 : this.playerID, true); 380 381 if (!won) 382 { 383 // Reassign all player's entities to Gaia 384 let entities = cmpRangeManager.GetEntitiesByPlayer(this.playerID); 385 386 // The ownership change is done in two steps so that entities don't hit idle 387 // (and thus possibly look for "enemies" to attack) before nearby allies get 388 // converted to Gaia as well. 389 for (let entity of entities) 390 { 391 let cmpOwnership = Engine.QueryInterface(entity, IID_Ownership); 392 cmpOwnership.SetOwnerQuiet(0); 393 } 394 395 // With the real ownership change complete, send OwnershipChanged messages. 396 for (let entity of entities) 397 Engine.PostMessage(entity, MT_OwnershipChanged, { 398 "entity": entity, 399 "from": this.playerID, 400 "to": 0 401 }); 402 } 403 404 // Inform the simulation 405 if (won) 406 Engine.BroadcastMessage(MT_PlayerWon, { "playerId": this.playerID }); 407 else 408 Engine.BroadcastMessage(MT_PlayerDefeated, { 409 "playerId": this.playerID, 410 "skipAlliedVictoryCheck": skipAlliedVictoryCheck 411 }); 412 413 // Inform the GUI 414 let cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); 415 if (won) 416 cmpGUIInterface.PushNotification({ 417 "type": "won", 418 "players": [this.playerID] 419 }); 420 else 421 cmpGUIInterface.PushNotification({ 422 "type": "defeat", 423 "players": [this.playerID], 424 "resign": resign 425 }); 365 426 }; 366 427 367 428 Player.prototype.GetTeam = function() 368 429 { 369 430 return this.team; … … Player.prototype.OnGlobalOwnershipChange 647 708 if (cmpIdentity && cmpIdentity.HasClass("Hero")) 648 709 this.heroes.push(msg.entity); 649 710 } 650 711 }; 651 712 652 Player.prototype.OnPlayerDefeated = function(msg)653 {654 this.state = "defeated";655 656 // Reassign all player's entities to Gaia657 var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager);658 var entities = cmpRangeManager.GetEntitiesByPlayer(this.playerID);659 660 // The ownership change is done in two steps so that entities don't hit idle661 // (and thus possibly look for "enemies" to attack) before nearby allies get662 // converted to Gaia as well.663 for (var entity of entities)664 {665 var cmpOwnership = Engine.QueryInterface(entity, IID_Ownership);666 cmpOwnership.SetOwnerQuiet(0);667 }668 669 // With the real ownership change complete, send OwnershipChanged messages.670 for (var entity of entities)671 Engine.PostMessage(entity, MT_OwnershipChanged, {672 "entity": entity,673 "from": this.playerID,674 "to": 0675 });676 677 // Reveal the map for this player.678 cmpRangeManager.SetLosRevealAll(this.playerID, true);679 680 // Send a chat message notifying of the player's defeat.681 var cmpGUIInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);682 cmpGUIInterface.PushNotification({683 "type": "defeat",684 "players": [this.playerID],685 "resign": !!msg.resign686 });687 };688 689 713 Player.prototype.OnResearchFinished = function(msg) 690 714 { 691 715 if (msg.tech == this.template.SharedLosTech) 692 716 this.UpdateSharedLos(); 693 717 else if (msg.tech == this.template.SharedDropsitesTech) -
binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js
1 1 Engine.RegisterInterface("EndGameManager"); 2 2 Engine.RegisterMessageType("PlayerDefeated"); 3 Engine.RegisterMessageType("PlayerWon"); 3 4 Engine.RegisterMessageType("GameTypeChanged"); -
binaries/data/mods/public/simulation/helpers/Cheat.js
function Cheat(input) 46 46 else 47 47 Engine.DestroyEntity(ent); 48 48 } 49 49 return; 50 50 case "defeatplayer": 51 var playerEnt = cmpPlayerManager.GetPlayerByID(input.parameter); 52 if (playerEnt == INVALID_ENTITY) 53 return; 54 Engine.PostMessage(playerEnt, MT_PlayerDefeated, { "playerId": input.parameter }); 51 cmpPlayer = QueryPlayerIDInterface(input.parameter); 52 if (cmpPlayer) 53 cmpPlayer.SetState("defeated"); 55 54 return; 56 55 case "createunits": 57 56 var cmpProductionQueue = input.selected.length && Engine.QueryInterface(input.selected[0], IID_ProductionQueue); 58 57 if (!cmpProductionQueue) 59 58 { -
binaries/data/mods/public/simulation/helpers/Commands.js
var g_Commands = { 412 412 } 413 413 }, 414 414 415 415 "defeat-player": function(player, cmd, data) 416 416 { 417 // Send "OnPlayerDefeated" message to player 418 Engine.PostMessage(data.playerEnt, MT_PlayerDefeated, { "playerId": player, "resign": !!cmd.resign }); 417 let cmpPlayer = QueryPlayerIDInterface(player); 418 if (cmpPlayer) 419 cmpPlayer.SetState("defeated", !!cmd.resign); 419 420 }, 420 421 421 422 "garrison": function(player, cmd, data) 422 423 { 423 424 // Verify that the building can be controlled by the player or is mutualAlly