From bf58f045112bebc17679e140fe8588578901ddbd Mon Sep 17 00:00:00 2001 From: sanderd17 Date: Sat, 28 Dec 2013 13:40:39 +0000 Subject: [PATCH] add wonder victory condition. Refs #1649 This was SVN commit r14418. --- .../mods/public/gui/gamesetup/gamesetup.js | 4 +- .../data/mods/public/gui/session/messages.js | 17 +++-- .../data/mods/public/gui/session/session.js | 1 + .../data/mods/public/gui/session/session.xml | 4 ++ .../simulation/components/EndGameManager.js | 33 +++++++++ .../simulation/components/GuiInterface.js | 52 ++++++++++++++ .../public/simulation/components/Wonder.js | 67 +++++++++++++++++++ .../components/interfaces/EndGameManager.js | 1 + .../components/interfaces/Wonder.js | 1 + .../templates/template_structure_wonder.xml | 3 + .../ScenarioEditor/Sections/Map/Map.cpp | 1 + 11 files changed, 176 insertions(+), 8 deletions(-) create mode 100644 binaries/data/mods/public/simulation/components/Wonder.js create mode 100644 binaries/data/mods/public/simulation/components/interfaces/Wonder.js diff --git a/binaries/data/mods/public/gui/gamesetup/gamesetup.js b/binaries/data/mods/public/gui/gamesetup/gamesetup.js index d2f9c7f1b7..845f92a94b 100644 --- a/binaries/data/mods/public/gui/gamesetup/gamesetup.js +++ b/binaries/data/mods/public/gui/gamesetup/gamesetup.js @@ -4,8 +4,8 @@ const DEFAULT_NETWORKED_MAP = "Acropolis 01"; const DEFAULT_OFFLINE_MAP = "Acropolis 01"; // TODO: Move these somewhere like simulation\data\game_types.json, Atlas needs them too -const VICTORY_TEXT = ["Conquest", "None"]; -const VICTORY_DATA = ["conquest", "endless"]; +const VICTORY_TEXT = ["Conquest", "Wonder", "None"]; +const VICTORY_DATA = ["conquest", "wonder", "endless"]; const VICTORY_DEFAULTIDX = 0; const POPULATION_CAP = ["50", "100", "150", "200", "250", "300", "Unlimited"]; const POPULATION_CAP_DATA = [50, 100, 150, 200, 250, 300, 10000]; diff --git a/binaries/data/mods/public/gui/session/messages.js b/binaries/data/mods/public/gui/session/messages.js index b940599e00..31466aeefb 100644 --- a/binaries/data/mods/public/gui/session/messages.js +++ b/binaries/data/mods/public/gui/session/messages.js @@ -136,12 +136,17 @@ function displayNotifications() var messages = []; for each (var n in notifications) messages.push(n.message); - getGUIObjectByName("notificationText").caption = messages.join("\n"); -} - -// Returns [username, playercolor] for the given player -function getUsernameAndColor(player) -{ + getGUIObjectByName("notificationText").caption = messages.join("\n"); +} + +function updateTimeNotifications() +{ + getGUIObjectByName("timeNotificationText").caption = Engine.GuiInterfaceCall("GetTimeNotificationText"); +} + +// Returns [username, playercolor] for the given player +function getUsernameAndColor(player) +{ // This case is hit for AIs, whose names don't exist in playerAssignments. var color = g_Players[player].color; return [ diff --git a/binaries/data/mods/public/gui/session/session.js b/binaries/data/mods/public/gui/session/session.js index 3047067080..45186ce8df 100644 --- a/binaries/data/mods/public/gui/session/session.js +++ b/binaries/data/mods/public/gui/session/session.js @@ -479,6 +479,7 @@ function onSimulationUpdate() updateResearchDisplay(); updateBuildingPlacementPreview(); updateTimeElapsedCounter(); + updateTimeNotifications(); // Update music state on basis of battle state. var battleState = Engine.GuiInterfaceCall("GetBattleState", Engine.GetPlayerID()); diff --git a/binaries/data/mods/public/gui/session/session.xml b/binaries/data/mods/public/gui/session/session.xml index 4487acf0b1..454faa1247 100644 --- a/binaries/data/mods/public/gui/session/session.xml +++ b/binaries/data/mods/public/gui/session/session.xml @@ -345,6 +345,10 @@ + + + + diff --git a/binaries/data/mods/public/simulation/components/EndGameManager.js b/binaries/data/mods/public/simulation/components/EndGameManager.js index f783bca85d..1a0d35bd76 100644 --- a/binaries/data/mods/public/simulation/components/EndGameManager.js +++ b/binaries/data/mods/public/simulation/components/EndGameManager.js @@ -24,6 +24,39 @@ EndGameManager.prototype.Init = function() EndGameManager.prototype.SetGameType = function(newGameType) { this.gameType = newGameType; + Engine.BroadcastMessage(MT_GameTypeChanged, {}); +}; + +EndGameManager.prototype.CheckGameType = function(type) +{ + return this.gameType == type; +}; + +EndGameManager.prototype.RegisterWonder = function(entity) +{ + if (!this.CheckGameType("wonder")) + return; + + var cmpWon = QueryOwnerInterface(entity, IID_Player); + cmpWon.SetState("won"); + + var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); + var numPlayers = cmpPlayerManager.GetNumPlayers(); + for (var i = 1; i < numPlayers; i++) + { + var playerEntityId = cmpPlayerManager.GetPlayerByID(i); + var cmpPlayer = Engine.QueryInterface(playerEntityId, IID_Player); + if (cmpPlayer.GetState() != "active") + continue; + if (this.alliedVictory && cmpPlayer.IsMutualAlly(cmpWon.GetPlayerID())) + cmpPlayer.SetState("won") + else + Engine.PostMessage(playerEntityId, MT_PlayerDefeated, { "playerId": i } ); + } + + // Reveal the map to all players + var cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); + cmpRangeManager.SetLosRevealAll(-1, true); }; EndGameManager.prototype.SetAlliedVictory = function(flag) diff --git a/binaries/data/mods/public/simulation/components/GuiInterface.js b/binaries/data/mods/public/simulation/components/GuiInterface.js index a252b5c237..c169f7ae73 100644 --- a/binaries/data/mods/public/simulation/components/GuiInterface.js +++ b/binaries/data/mods/public/simulation/components/GuiInterface.js @@ -22,6 +22,8 @@ GuiInterface.prototype.Init = function() this.placementWallLastAngle = 0; this.notifications = []; this.renamedEntities = []; + this.timeNotificationID = 1; + this.timeNotifications = []; }; /* @@ -728,6 +730,55 @@ GuiInterface.prototype.GetNeededResources = function(player, amounts) return cmpPlayer.GetNeededResources(amounts); }; +GuiInterface.prototype.AddTimeNotification = function(notification) +{ + var time = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).GetTime(); + notification.endTime = notification.time + time; + notification.id = ++this.timeNotificationID; + this.timeNotifications.push(notification); + this.timeNotifications.sort(function (n1, n2){return n2.endTime - n1.endTime}); + return this.timeNotificationID; +}; + +GuiInterface.prototype.DeleteTimeNotification = function(notificationID) +{ + for (var i in this.timeNotifications) + { + if (this.timeNotifications[i].id == notificationID) + { + this.timeNotifications.splice(i); + return; + } + } +}; + +GuiInterface.prototype.GetTimeNotificationText = function(playerID) +{ + var formatTime = function(time) + { + // add 1000 ms to get ceiled instead of floored millisecons + // displaying 00:00 for a full second isn't nice + time += 1000; + var hours = Math.floor(time / 1000 / 60 / 60); + var minutes = Math.floor(time / 1000 / 60) % 60; + var seconds = Math.floor(time / 1000) % 60; + return (hours ? hours + ':' : "") + (minutes < 10 ? '0' + minutes : minutes) + ':' + (seconds < 10 ? '0' + seconds : seconds); + }; + var time = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).GetTime(); + var text = ""; + for each (var n in this.timeNotifications) + { + if (time >= n.endTime) + { + // delete the notification and start over + this.DeleteTimeNotification(n.id); + return this.GetTimeNotificationText(playerID); + } + if (n.players.indexOf(playerID) >= 0) + text += n.message.replace("%T",formatTime(n.endTime - time))+"\n"; + } + return text; +}; GuiInterface.prototype.PushNotification = function(notification) { @@ -1879,6 +1930,7 @@ var exposedFunctions = { "GetIncomingAttacks": 1, "GetNeededResources": 1, "GetNextNotification": 1, + "GetTimeNotificationText": 1, "GetAvailableFormations": 1, "GetFormationRequirements": 1, diff --git a/binaries/data/mods/public/simulation/components/Wonder.js b/binaries/data/mods/public/simulation/components/Wonder.js new file mode 100644 index 0000000000..c2c1853f31 --- /dev/null +++ b/binaries/data/mods/public/simulation/components/Wonder.js @@ -0,0 +1,67 @@ +function Wonder() {} + +Wonder.prototype.Schema = + "" + + "" + + ""; + +Wonder.prototype.Init = function() +{ +}; + +Wonder.prototype.OnOwnershipChanged = function(msg) +{ + this.ResetTimer(msg.to); +}; + +Wonder.prototype.OnGameTypeChanged = function() +{ + var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); + if (!cmpPlayer) + return; + this.ResetTimer(cmpPlayer.GetPlayerID()); +}; + +Wonder.prototype.ResetTimer = function(ownerID) +{ + var cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); + var cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); + // remove existing messages if any + if (this.timer) + { + cmpTimer.CancelTimer(this.timer); + cmpGuiInterface.DeleteTimeNotification(this.ownMessage); + cmpGuiInterface.DeleteTimeNotification(this.otherMessage); + } + if (ownerID <= 0) + return; + + var cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager); + if (!cmpEndGameManager.CheckGameType("wonder")) + return; + + // create new messages, and start timer to register defeat. + var cmpPlayerManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager); + var numPlayers = cmpPlayerManager.GetNumPlayers(); + var cmpPlayer = QueryOwnerInterface(this.entity, IID_Player); + var players = []; + for (var i = 1; i < numPlayers; i++) + if (i != ownerID) + players.push(i); + + this.otherMessage = cmpGuiInterface.AddTimeNotification( + { + "message": cmpPlayer.GetName() + " will have won in %T", + "players": players, + "time": +this.template.TimeTillVictory*1000 + }); + this.ownMessage = cmpGuiInterface.AddTimeNotification( + { + "message": "You will have won in %T", + "players": [ownerID], + "time": +this.template.TimeTillVictory*1000 + }); + this.timer = cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_EndGameManager, "RegisterWonder", +this.template.TimeTillVictory*1000, this.entity); +}; + +Engine.RegisterComponentType(IID_Wonder, "Wonder", Wonder); diff --git a/binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js b/binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js index 77286b1598..17333a3fff 100644 --- a/binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js +++ b/binaries/data/mods/public/simulation/components/interfaces/EndGameManager.js @@ -1,2 +1,3 @@ Engine.RegisterInterface("EndGameManager"); Engine.RegisterMessageType("PlayerDefeated"); +Engine.RegisterMessageType("GameTypeChanged"); diff --git a/binaries/data/mods/public/simulation/components/interfaces/Wonder.js b/binaries/data/mods/public/simulation/components/interfaces/Wonder.js new file mode 100644 index 0000000000..b02be73d74 --- /dev/null +++ b/binaries/data/mods/public/simulation/components/interfaces/Wonder.js @@ -0,0 +1 @@ +Engine.RegisterInterface("Wonder"); diff --git a/binaries/data/mods/public/simulation/templates/template_structure_wonder.xml b/binaries/data/mods/public/simulation/templates/template_structure_wonder.xml index 1ee0e5e745..b5a87ff46b 100644 --- a/binaries/data/mods/public/simulation/templates/template_structure_wonder.xml +++ b/binaries/data/mods/public/simulation/templates/template_structure_wonder.xml @@ -76,4 +76,7 @@ structures/fndn_6x6.xml + + 300 + diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp index 5e08cbf0e1..55e1d17499 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/Sections/Map/Map.cpp @@ -145,6 +145,7 @@ void MapSettingsControl::CreateWidgets() wxArrayString gameTypes; gameTypes.Add(_T("conquest")); + gameTypes.Add(_T("wonder")); gameTypes.Add(_T("endless")); wxFlexGridSizer* gridSizer = new wxFlexGridSizer(2, 5, 5);