0ad/binaries/data/mods/public/maps/scripts/CaptureTheRelic.js
Ralph Sennhauser 60fc382bd8
Fix eslint rule 'prefer-const' in maps/scripts
eslint --no-config-lookup --fix --rule '"prefer-const": 1' \
    binaries/data/mods/public/maps/scripts

Ref: #7812
Signed-off-by: Ralph Sennhauser <ralph.sennhauser@gmail.com>
2025-05-09 19:46:31 +02:00

195 lines
7.1 KiB
JavaScript

Trigger.prototype.InitCaptureTheRelic = function()
{
const cmpTemplateManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_TemplateManager);
const catafalqueTemplates = shuffleArray(cmpTemplateManager.FindAllTemplates(false).filter(
name => GetIdentityClasses(cmpTemplateManager.GetTemplate(name).Identity || {}).indexOf("Relic") != -1));
const potentialSpawnPoints = TriggerHelper.GetLandSpawnPoints();
if (!potentialSpawnPoints.length)
{
error("No gaia entities found on this map that could be used as spawn points!");
return;
}
const cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
const numSpawnedRelics = cmpEndGameManager.GetGameSettings().relicCount;
this.playerRelicsCount = new Array(TriggerHelper.GetNumberOfPlayers()).fill(0, 1);
this.playerRelicsCount[0] = numSpawnedRelics;
for (let i = 0; i < numSpawnedRelics; ++i)
{
this.relics[i] = TriggerHelper.SpawnUnits(pickRandom(potentialSpawnPoints), catafalqueTemplates[i], 1, 0)[0];
const cmpPositionRelic = Engine.QueryInterface(this.relics[i], IID_Position);
cmpPositionRelic.SetYRotation(randomAngle());
}
};
Trigger.prototype.CheckCaptureTheRelicVictory = function(data)
{
const cmpIdentity = Engine.QueryInterface(data.entity, IID_Identity);
if (!cmpIdentity || !cmpIdentity.HasClass("Relic") || data.from == INVALID_PLAYER)
return;
--this.playerRelicsCount[data.from];
if (data.to == -1)
{
warn("Relic entity " + data.entity + " has been destroyed.");
this.relics.splice(this.relics.indexOf(data.entity), 1);
}
else
++this.playerRelicsCount[data.to];
this.DeleteCaptureTheRelicVictoryMessages();
this.CheckCaptureTheRelicCountdown();
};
/**
* Check if a group of mutually allied players have acquired all relics.
* The winning players are the relic owners and all players mutually allied to all relic owners.
* Reset the countdown if the group of winning players changes or extends.
*/
Trigger.prototype.CheckCaptureTheRelicCountdown = function()
{
if (this.playerRelicsCount[0])
{
this.DeleteCaptureTheRelicVictoryMessages();
return;
}
const activePlayers = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetActivePlayers();
const relicOwners = activePlayers.filter(playerID => this.playerRelicsCount[playerID]);
if (!relicOwners.length)
{
this.DeleteCaptureTheRelicVictoryMessages();
return;
}
const winningPlayers = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager).GetAlliedVictory() ?
activePlayers.filter(playerID => relicOwners.every(owner => QueryPlayerIDInterface(playerID, IID_Diplomacy).IsMutualAlly(owner))) :
[relicOwners[0]];
// All relicOwners should be mutually allied
if (relicOwners.some(owner => winningPlayers.indexOf(owner) == -1))
{
this.DeleteCaptureTheRelicVictoryMessages();
return;
}
// Reset the timer when playerAndAllies isn't the same as this.relicsVictoryCountdownPlayers
if (winningPlayers.length != this.relicsVictoryCountdownPlayers.length ||
winningPlayers.some(player => this.relicsVictoryCountdownPlayers.indexOf(player) == -1))
{
this.relicsVictoryCountdownPlayers = winningPlayers;
this.StartCaptureTheRelicCountdown(winningPlayers);
}
};
Trigger.prototype.DeleteCaptureTheRelicVictoryMessages = function()
{
if (!this.relicsVictoryTimer)
return;
Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer).CancelTimer(this.relicsVictoryTimer);
this.relicsVictoryTimer = undefined;
const cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
cmpGuiInterface.DeleteTimeNotification(this.ownRelicsVictoryMessage);
cmpGuiInterface.DeleteTimeNotification(this.othersRelicsVictoryMessage);
this.relicsVictoryCountdownPlayers = [];
};
Trigger.prototype.StartCaptureTheRelicCountdown = function(winningPlayers)
{
const cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
const cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
if (this.relicsVictoryTimer)
{
cmpTimer.CancelTimer(this.relicsVictoryTimer);
cmpGuiInterface.DeleteTimeNotification(this.ownRelicsVictoryMessage);
cmpGuiInterface.DeleteTimeNotification(this.othersRelicsVictoryMessage);
}
if (!this.relics.length)
return;
const others = [-1];
for (let playerID = 1; playerID < TriggerHelper.GetNumberOfPlayers(); ++playerID)
{
const cmpPlayer = QueryPlayerIDInterface(playerID);
if (cmpPlayer.GetState() == "won")
return;
if (winningPlayers.indexOf(playerID) == -1)
others.push(playerID);
}
const cmpPlayer = QueryOwnerInterface(this.relics[0], IID_Player);
if (!cmpPlayer)
{
warn("Relic entity " + this.relics[0] + " has no owner.");
this.relics.splice(0, 1);
this.CheckCaptureTheRelicCountdown();
return;
}
const cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
const captureTheRelicDuration = cmpEndGameManager.GetGameSettings().relicDuration;
const isTeam = winningPlayers.length > 1;
this.ownRelicsVictoryMessage = cmpGuiInterface.AddTimeNotification({
"message": isTeam ?
markForTranslation("%(_player_)s and their allies have captured all relics and will win in %(time)s.") :
markForTranslation("%(_player_)s has captured all relics and will win in %(time)s."),
"players": others,
"parameters": {
"_player_": cmpPlayer.GetPlayerID()
},
"translateMessage": true,
"translateParameters": []
}, captureTheRelicDuration);
this.othersRelicsVictoryMessage = cmpGuiInterface.AddTimeNotification({
"message": isTeam ?
markForTranslation("You and your allies have captured all relics and will win in %(time)s.") :
markForTranslation("You have captured all relics and will win in %(time)s."),
"players": winningPlayers,
"translateMessage": true
}, captureTheRelicDuration);
this.relicsVictoryTimer = cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_Trigger,
"CaptureTheRelicVictorySetWinner", captureTheRelicDuration, winningPlayers);
};
Trigger.prototype.CaptureTheRelicVictorySetWinner = function(winningPlayers)
{
const cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
cmpEndGameManager.MarkPlayersAsWon(
winningPlayers,
n => markForPluralTranslation(
"%(lastPlayer)s has won (Capture the Relic).",
"%(players)s and %(lastPlayer)s have won (Capture the Relic).",
n),
n => markForPluralTranslation(
"%(lastPlayer)s has been defeated (Capture the Relic).",
"%(players)s and %(lastPlayer)s have been defeated (Capture the Relic).",
n));
};
{
const cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
cmpTrigger.relics = [];
cmpTrigger.playerRelicsCount = [];
cmpTrigger.relicsVictoryTimer = undefined;
cmpTrigger.ownRelicsVictoryMessage = undefined;
cmpTrigger.othersRelicsVictoryMessage = undefined;
cmpTrigger.relicsVictoryCountdownPlayers = [];
cmpTrigger.DoAfterDelay(0, "InitCaptureTheRelic", {});
cmpTrigger.RegisterTrigger("OnDiplomacyChanged", "CheckCaptureTheRelicCountdown", { "enabled": true });
cmpTrigger.RegisterTrigger("OnOwnershipChanged", "CheckCaptureTheRelicVictory", { "enabled": true });
cmpTrigger.RegisterTrigger("OnPlayerWon", "DeleteCaptureTheRelicVictoryMessages", { "enabled": true });
cmpTrigger.RegisterTrigger("OnPlayerDefeated", "CheckCaptureTheRelicCountdown", { "enabled": true });
}