Add randomAngle helper function to abbreviate calls.
[0ad.git] / binaries / data / mods / public / maps / scripts / CaptureTheRelic.js
blob69733633afa78d18db12d638f12afb18a0e86b58
1 Trigger.prototype.InitCaptureTheRelic = function()
3         let cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
4         let catafalqueTemplates = shuffleArray(cmpTemplateManager.FindAllTemplates(false).filter(
5                 name => GetIdentityClasses(cmpTemplateManager.GetTemplate(name).Identity || {}).indexOf("Relic") != -1));
7         let potentialSpawnPoints = TriggerHelper.GetLandSpawnPoints();
8         if (!potentialSpawnPoints.length)
9         {
10                 error("No gaia entities found on this map that could be used as spawn points!");
11                 return;
12         }
14         let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
15         let numSpawnedRelics = cmpEndGameManager.GetGameTypeSettings().relicCount;
16         this.playerRelicsCount = new Array(TriggerHelper.GetNumberOfPlayers()).fill(0, 1);
17         this.playerRelicsCount[0] = numSpawnedRelics;
19         for (let i = 0; i < numSpawnedRelics; ++i)
20         {
21                 this.relics[i] = TriggerHelper.SpawnUnits(pickRandom(potentialSpawnPoints), catafalqueTemplates[i], 1, 0)[0];
23                 let cmpDamageReceiver = Engine.QueryInterface(this.relics[i], IID_DamageReceiver);
24                 cmpDamageReceiver.SetInvulnerability(true);
26                 let cmpPositionRelic = Engine.QueryInterface(this.relics[i], IID_Position);
27                 cmpPositionRelic.SetYRotation(randomAngle());
28         }
31 Trigger.prototype.CheckCaptureTheRelicVictory = function(data)
33         let cmpIdentity = Engine.QueryInterface(data.entity, IID_Identity);
34         if (!cmpIdentity || !cmpIdentity.HasClass("Relic") || data.from == -1)
35                 return;
37         --this.playerRelicsCount[data.from];
39         if (data.to == -1)
40         {
41                 warn("Relic entity " + data.entity + " has been destroyed");
42                 this.relics.splice(this.relics.indexOf(data.entity), 1);
43         }
44         else
45                 ++this.playerRelicsCount[data.to];
47         this.CheckCaptureTheRelicCountdown();
50 /**
51  * Check if an individual player or team has acquired all relics.
52  * Also check if the countdown needs to be stopped if a player/team no longer has all relics.
53  * Reset the countdown if any of the original allies tries to change their diplomacy with one of these allies.
54  */
55 Trigger.prototype.CheckCaptureTheRelicCountdown = function(data)
57         let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
59         for (let playerID = 1; playerID < TriggerHelper.GetNumberOfPlayers(); ++playerID)
60         {
61                 let playerAndAllies = cmpEndGameManager.GetAlliedVictory() ?
62                         QueryPlayerIDInterface(playerID).GetMutualAllies() : [playerID];
64                 let teamRelicsOwned = 0;
66                 for (let ally of playerAndAllies)
67                         teamRelicsOwned += this.playerRelicsCount[ally];
69                 if (teamRelicsOwned == this.relics.length)
70                 {
71                         if (!data ||
72                             !this.relicsVictoryCountdownPlayers.length ||
73                             this.relicsVictoryCountdownPlayers.indexOf(data.player) != -1 &&
74                             this.relicsVictoryCountdownPlayers.indexOf(data.otherPlayer) != -1)
75                         {
76                                 this.relicsVictoryCountdownPlayers = playerAndAllies;
77                                 this.StartCaptureTheRelicCountdown(playerAndAllies);
78                         }
79                         return;
80                 }
81         }
83         this.DeleteCaptureTheRelicVictoryMessages();
86 Trigger.prototype.DeleteCaptureTheRelicVictoryMessages = function()
88         let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
89         cmpTimer.CancelTimer(this.relicsVictoryTimer);
91         let cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
92         cmpGuiInterface.DeleteTimeNotification(this.ownRelicsVictoryMessage);
93         cmpGuiInterface.DeleteTimeNotification(this.othersRelicsVictoryMessage);
94         this.relicsVictoryCountdownPlayers = [];
97 Trigger.prototype.StartCaptureTheRelicCountdown = function(playerAndAllies)
99         let cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
100         let cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
102         if (this.relicsVictoryTimer)
103         {
104                 cmpTimer.CancelTimer(this.relicsVictoryTimer);
105                 cmpGuiInterface.DeleteTimeNotification(this.ownRelicsVictoryMessage);
106                 cmpGuiInterface.DeleteTimeNotification(this.othersRelicsVictoryMessage);
107         }
109         if (!this.relics.length)
110                 return;
112         let others = [-1];
113         for (let playerID = 1; playerID < TriggerHelper.GetNumberOfPlayers(); ++playerID)
114         {
115                 let cmpPlayer = QueryPlayerIDInterface(playerID);
116                 if (cmpPlayer.GetState() == "won")
117                         return;
119                 if (playerAndAllies.indexOf(playerID) == -1)
120                         others.push(playerID);
121         }
123         let cmpPlayer = QueryOwnerInterface(this.relics[0], IID_Player);
124         let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
125         let captureTheRelicDuration = cmpEndGameManager.GetGameTypeSettings().relicDuration;
127         let isTeam = playerAndAllies.length > 1;
128         this.ownRelicsVictoryMessage = cmpGuiInterface.AddTimeNotification({
129                 "message": isTeam ?
130                         markForTranslation("%(_player_)s's team has captured all relics and will win in %(time)s.") :
131                         markForTranslation("%(_player_)s has captured all relics and will win in %(time)s."),
132                 "players": others,
133                 "parameters": {
134                         "_player_": cmpPlayer.GetPlayerID()
135                 },
136                 "translateMessage": true,
137                 "translateParameters": []
138         }, captureTheRelicDuration);
140         this.othersRelicsVictoryMessage = cmpGuiInterface.AddTimeNotification({
141                 "message": isTeam ?
142                         markForTranslation("Your team has captured all relics and will win in %(time)s.") :
143                         markForTranslation("You have captured all relics and will win in %(time)s."),
144                 "players": playerAndAllies,
145                 "translateMessage": true
146         }, captureTheRelicDuration);
148         this.relicsVictoryTimer = cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_Trigger,
149                 "CaptureTheRelicVictorySetWinner", captureTheRelicDuration, playerAndAllies[0]);
152 Trigger.prototype.CaptureTheRelicVictorySetWinner = function(playerID)
154         let cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
155         cmpEndGameManager.MarkPlayerAsWon(
156                 playerID,
157                 n => markForPluralTranslation(
158                         "%(lastPlayer)s has won (Capture the Relic).",
159                         "%(players)s and %(lastPlayer)s have won (Capture the Relic).",
160                         n),
161                 n => markForPluralTranslation(
162                         "%(lastPlayer)s has been defeated (Capture the Relic).",
163                         "%(players)s and %(lastPlayer)s have been defeated (Capture the Relic).",
164                         n));
168         let cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
169         cmpTrigger.relics = [];
170         cmpTrigger.playerRelicsCount = [];
171         cmpTrigger.relicsVictoryTimer = undefined;
172         cmpTrigger.ownRelicsVictoryMessage = undefined;
173         cmpTrigger.othersRelicsVictoryMessage = undefined;
174         cmpTrigger.relicsVictoryCountdownPlayers = [];
176         cmpTrigger.DoAfterDelay(0, "InitCaptureTheRelic", {});
177         cmpTrigger.RegisterTrigger("OnDiplomacyChanged", "CheckCaptureTheRelicCountdown", { "enabled": true });
178         cmpTrigger.RegisterTrigger("OnOwnershipChanged", "CheckCaptureTheRelicVictory", { "enabled": true });
179         cmpTrigger.RegisterTrigger("OnPlayerWon", "DeleteCaptureTheRelicVictoryMessages", { "enabled": true });