| 1 | Trigger.prototype.CheckRelicsVictory = function(data) |
| 2 | { |
| 3 | let cmpIdentity = Engine.QueryInterface(data.entity, IID_Identity); |
| 4 | if (!cmpIdentity || !cmpIdentity.HasClass("Relic") || data.from == -1) |
| 5 | return; |
| 6 | |
| 7 | if (data.from != 0) |
| 8 | --this.playerRelicsCount[data.from]; |
| 9 | |
| 10 | ++this.playerRelicsCount[data.to]; |
| 11 | |
| 12 | this.CheckCountdown(); |
| 13 | }; |
| 14 | |
| 15 | /** |
| 16 | * Check if an individual player or a team has acquired all the relics |
| 17 | * Also check if the countdown needs to be stopped if a player/team no longer has all the relics |
| 18 | */ |
| 19 | Trigger.prototype.CheckCountdown = function() |
| 20 | { |
| 21 | for (let playerID = 1; playerID < TriggerHelper.GetNumberOfPlayers(); ++playerID) |
| 22 | { |
| 23 | let playerAndAllies = QueryPlayerIDInterface(playerID).GetMutualAllies(); |
| 24 | let teamRelicsOwned = 0; |
| 25 | |
| 26 | for (let ally of playerAndAllies) |
| 27 | teamRelicsOwned += this.playerRelicsCount[ally]; |
| 28 | |
| 29 | if (teamRelicsOwned == this.relics.length - 1) |
| 30 | { |
| 31 | let data = { "entity": this.relics[playerID], "to": playerAndAllies }; |
| 32 | this.StartCountdown(data, playerAndAllies.length > 1); |
| 33 | return; |
| 34 | } |
| 35 | } |
| 36 | |
| 37 | this.DeleteRelicsVictoryMessages(); |
| 38 | }; |
| 39 | |
| 40 | Trigger.prototype.DeleteRelicsVictoryMessages = function() |
| 41 | { |
| 42 | let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); |
| 43 | let cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); |
| 44 | |
| 45 | for (let ent in this.relicsVictoryMessages) |
| 46 | { |
| 47 | cmpGuiInterface.DeleteTimeNotification(this.relicsVictoryMessages[ent].ownMessage); |
| 48 | cmpGuiInterface.DeleteTimeNotification(this.relicsVictoryMessages[ent].otherMessage); |
| 49 | cmpTimer.CancelTimer(this.relicsVictoryTimers[ent]); |
| 50 | } |
| 51 | }; |
| 52 | |
| 53 | Trigger.prototype.StartCountdown = function(data, isTeam) |
| 54 | { |
| 55 | let timer = this.relicsVictoryTimers[data.entity]; |
| 56 | let messages = this.relicsVictoryMessages[data.entity] || {}; |
| 57 | |
| 58 | let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer); |
| 59 | let cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface); |
| 60 | |
| 61 | if (timer) |
| 62 | { |
| 63 | cmpTimer.CancelTimer(timer); |
| 64 | cmpGuiInterface.DeleteTimeNotification(messages.ownMessage); |
| 65 | cmpGuiInterface.DeleteTimeNotification(messages.otherMessage); |
| 66 | } |
| 67 | |
| 68 | let players = [-1]; |
| 69 | for (let playerID = 1; playerID < TriggerHelper.GetNumberOfPlayers(); ++playerID) |
| 70 | { |
| 71 | let cmpPlayer = QueryPlayerIDInterface(playerID); |
| 72 | if (cmpPlayer.GetState() == "won") |
| 73 | return; |
| 74 | if (data.to.indexOf(playerID) == -1) |
| 75 | players.push(playerID); |
| 76 | } |
| 77 | |
| 78 | let cmpPlayer = QueryOwnerInterface(data.entity, IID_Player); |
| 79 | messages.otherMessage = cmpGuiInterface.AddTimeNotification({ |
| 80 | "message": isTeam ? markForTranslation("%(player)s's team has captured all of the relics. They will have won in %(time)s") : |
| 81 | markForTranslation("%(player)s has captured all of the relics. They will have won in %(time)s"), |
| 82 | "players": players, |
| 83 | "parameters": { |
| 84 | "player": cmpPlayer.GetName() |
| 85 | }, |
| 86 | "translateMessage": true, |
| 87 | "translateParameters": [], |
| 88 | }, 10 * 60 * 1000); // 10 min |
| 89 | |
| 90 | messages.ownMessage = cmpGuiInterface.AddTimeNotification({ |
| 91 | "message": isTeam ? markForTranslation("Your team has captured all of the relics. You will have won in %(time)s") : |
| 92 | markForTranslation("You have captured all of the relics. You will have won in %(time)s"), |
| 93 | "players": data.to, |
| 94 | "translateMessage": true, |
| 95 | }, 10 * 60 * 1000); |
| 96 | |
| 97 | timer = cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_EndGameManager, |
| 98 | "MarkPlayerAsWon", 10 * 60 * 1000, data.to[0]); |
| 99 | |
| 100 | this.relicsVictoryTimers[data.entity] = timer; |
| 101 | this.relicsVictoryMessages[data.entity] = messages; |
| 102 | }; |
| 103 | |
| 104 | Trigger.prototype.InitRelicsGame = function() |
| 105 | { |
| 106 | // Attempt to spawn one relic per player randomly in neutral territory |
| 107 | let cmpRangeManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_RangeManager); |
| 108 | let cmpWaterManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_WaterManager); |
| 109 | let cmpTerritoryManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TerritoryManager); |
| 110 | |
| 111 | let validSpawnPoint = entity => { |
| 112 | |
| 113 | let cmpIdentity = Engine.QueryInterface(entity, IID_Identity); |
| 114 | let cmpPosition = Engine.QueryInterface(entity, IID_Position); |
| 115 | |
| 116 | if (!cmpIdentity || !cmpPosition || !cmpPosition.IsInWorld()) |
| 117 | return false; |
| 118 | |
| 119 | let pos = cmpPosition.GetPosition(); |
| 120 | |
| 121 | // do not spawn relics underwater |
| 122 | if (cmpIdentity.HasClass("SeaCreature") || pos.y <= cmpWaterManager.GetWaterLevel(pos.x, pos.z) || |
| 123 | cmpTerritoryManager.GetOwner(cmpPosition.GetPosition2D().x, cmpPosition.GetPosition2D().y) != 0) |
| 124 | return false; |
| 125 | |
| 126 | return true; |
| 127 | }; |
| 128 | |
| 129 | let gaiaEntities = cmpRangeManager.GetEntitiesByPlayer(0).filter(entity => validSpawnPoint(entity)); |
| 130 | |
| 131 | if (!gaiaEntities.length) |
| 132 | { |
| 133 | error("No relic spawn points on map"); |
| 134 | return; |
| 135 | } |
| 136 | |
| 137 | for (let i = 1; i < TriggerHelper.GetNumberOfPlayers(); ++i) |
| 138 | { |
| 139 | this.relics[i] = TriggerHelper.SpawnUnits(gaiaEntities[Math.floor(Math.random() * gaiaEntities.length)], |
| 140 | "special_units/special_relic", 1, 0)[0]; |
| 141 | this.playerRelicsCount[i] = 0; |
| 142 | |
| 143 | let cmpHealth = Engine.QueryInterface(this.relics[i], IID_Health); |
| 144 | cmpHealth.SetUndeletable(true); |
| 145 | |
| 146 | let cmpDamageReceiver = Engine.QueryInterface(this.relics[i], IID_DamageReceiver); |
| 147 | cmpDamageReceiver.SetInvulnerability(true); |
| 148 | } |
| 149 | }; |
| 150 | |
| 151 | let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger); |
| 152 | cmpTrigger.relics = []; |
| 153 | cmpTrigger.playerRelicsCount = []; |
| 154 | cmpTrigger.relicsVictoryTimers = {}; |
| 155 | cmpTrigger.relicsVictoryMessages = {}; |
| 156 | |
| 157 | cmpTrigger.DoAfterDelay(0, "InitRelicsGame", {}); |
| 158 | cmpTrigger.RegisterTrigger("OnOwnershipChanged", "CheckRelicsVictory", { "enabled": true }); |
| 159 | cmpTrigger.RegisterTrigger("OnDiplomacyChanged", "CheckCountdown", { "enabled": true }); |