mirror of
https://gitea.wildfiregames.com/0ad/0ad.git
synced 2026-11-08 10:29:00 +00:00
1 parent
46db652641
commit
0adb53e30b
1 file changed
+118
-38
@@ -13,6 +13,7 @@ Trigger.prototype.InitCaptureTheRelic = function()
|
||||
|
||||
const cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
|
||||
const numSpawnedRelics = cmpEndGameManager.GetGameSettings().relicCount;
|
||||
this.totalRemainingRelics = numSpawnedRelics;
|
||||
this.playerRelicsCount = new Array(TriggerHelper.GetNumberOfPlayers()).fill(0, 1);
|
||||
this.playerRelicsCount[0] = numSpawnedRelics;
|
||||
|
||||
@@ -37,20 +38,121 @@ Trigger.prototype.CheckCaptureTheRelicVictory = function(data)
|
||||
{
|
||||
warn("Relic entity " + data.entity + " has been destroyed.");
|
||||
this.relics.splice(this.relics.indexOf(data.entity), 1);
|
||||
--this.totalRemainingRelics;
|
||||
}
|
||||
else
|
||||
++this.playerRelicsCount[data.to];
|
||||
|
||||
const capturer = data.to == -1 ? undefined : data.to;
|
||||
this.DeleteCaptureTheRelicVictoryMessages();
|
||||
this.CheckCaptureTheRelicCountdown();
|
||||
this.CheckCaptureTheRelicCountdown({ "capturer": capturer });
|
||||
|
||||
// A started countdown has already sent its notifications.
|
||||
if (capturer !== undefined && !this.relicsVictoryTimer)
|
||||
this.SendRelicCaptureNotification(capturer);
|
||||
};
|
||||
|
||||
Trigger.prototype.SendRelicCaptureNotification = function(playerID)
|
||||
{
|
||||
const cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
|
||||
const total = this.totalRemainingRelics;
|
||||
const duration = this.CAPTURE_NOTIFICATION_DURATION;
|
||||
|
||||
if (!this.relicsVictoryTimer)
|
||||
{
|
||||
const alliance = cmpEndGameManager.GetAlliedVictory() ?
|
||||
QueryPlayerIDInterface(playerID, IID_Diplomacy).GetMutualAllies().filter(pid => QueryPlayerIDInterface(pid).IsActive()) :
|
||||
[playerID];
|
||||
const parameters = {
|
||||
"count": alliance.reduce((sum, pid) => sum + this.playerRelicsCount[pid], 0),
|
||||
"total": total,
|
||||
"_player_": playerID
|
||||
};
|
||||
|
||||
if (alliance.length == 1)
|
||||
{
|
||||
TriggerHelper.SendDualNotification(playerID,
|
||||
markForTranslation("You have captured a relic. You now have %(count)s of %(total)s relics."),
|
||||
markForTranslation("%(_player_)s has captured a relic. They now have %(count)s of %(total)s relics."),
|
||||
duration, parameters);
|
||||
return;
|
||||
}
|
||||
|
||||
const nonAllies = [-1];
|
||||
for (let i = 1; i < TriggerHelper.GetNumberOfPlayers(); ++i)
|
||||
{
|
||||
const cmpPlayer = QueryPlayerIDInterface(i);
|
||||
if (alliance.indexOf(i) == -1 && cmpPlayer && cmpPlayer.GetState() != "defeated")
|
||||
nonAllies.push(i);
|
||||
}
|
||||
|
||||
TriggerHelper.SendNotification(markForTranslation("You have captured a relic. Your alliance now has %(count)s of %(total)s relics."),
|
||||
[playerID], duration, parameters, ["_player_"]);
|
||||
TriggerHelper.SendNotification(markForTranslation("%(_player_)s has captured a relic. Your alliance now has %(count)s of %(total)s relics."),
|
||||
alliance.filter(pid => pid != playerID), duration, parameters, ["_player_"]);
|
||||
TriggerHelper.SendNotification(markForTranslation("%(_player_)s has captured a relic. Their alliance now has %(count)s of %(total)s relics."),
|
||||
nonAllies, duration, parameters, ["_player_"]);
|
||||
return;
|
||||
}
|
||||
|
||||
const winningPlayers = this.relicsVictoryCountdownPlayers;
|
||||
const others = [-1];
|
||||
for (let i = 1; i < TriggerHelper.GetNumberOfPlayers(); ++i)
|
||||
if (winningPlayers.indexOf(i) == -1)
|
||||
others.push(i);
|
||||
|
||||
const isTeam = winningPlayers.length > 1;
|
||||
const relicDuration = cmpEndGameManager.GetGameSettings().relicDuration;
|
||||
if (relicDuration)
|
||||
{
|
||||
const cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
|
||||
this.othersRelicsVictoryMessage = 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_": playerID
|
||||
},
|
||||
"translateMessage": true,
|
||||
"translateParameters": ["_player_"]
|
||||
}, relicDuration);
|
||||
|
||||
this.ownRelicsVictoryMessage = 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
|
||||
}, relicDuration);
|
||||
return;
|
||||
}
|
||||
|
||||
const victoryParameters = { "total": total, "_player_": playerID };
|
||||
if (!isTeam)
|
||||
{
|
||||
TriggerHelper.SendDualNotification(playerID,
|
||||
markForTranslation("You have captured all relics!"),
|
||||
markForTranslation("%(_player_)s has captured all %(total)s relics!"),
|
||||
duration, victoryParameters);
|
||||
return;
|
||||
}
|
||||
|
||||
TriggerHelper.SendNotification(markForTranslation("You and your allies have captured all relics!"),
|
||||
[playerID], duration, victoryParameters, ["_player_"]);
|
||||
TriggerHelper.SendNotification(markForTranslation("%(_player_)s has captured the last relic! Your alliance has captured all relics!"),
|
||||
winningPlayers.filter(pid => pid != playerID), duration, victoryParameters, ["_player_"]);
|
||||
TriggerHelper.SendNotification(markForTranslation("%(_player_)s and their allies have captured all %(total)s relics!"),
|
||||
others, duration, victoryParameters, ["_player_"]);
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param {Object} [data] - Holds the "capturer" when called after a relic capture.
|
||||
*/
|
||||
Trigger.prototype.CheckCaptureTheRelicCountdown = function()
|
||||
Trigger.prototype.CheckCaptureTheRelicCountdown = function(data)
|
||||
{
|
||||
if (this.playerRelicsCount[0])
|
||||
{
|
||||
@@ -82,7 +184,7 @@ Trigger.prototype.CheckCaptureTheRelicCountdown = function()
|
||||
winningPlayers.some(player => this.relicsVictoryCountdownPlayers.indexOf(player) == -1))
|
||||
{
|
||||
this.relicsVictoryCountdownPlayers = winningPlayers;
|
||||
this.StartCaptureTheRelicCountdown(winningPlayers);
|
||||
this.StartCaptureTheRelicCountdown(winningPlayers, data?.capturer);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -100,14 +202,16 @@ Trigger.prototype.DeleteCaptureTheRelicVictoryMessages = function()
|
||||
this.relicsVictoryCountdownPlayers = [];
|
||||
};
|
||||
|
||||
Trigger.prototype.StartCaptureTheRelicCountdown = function(winningPlayers)
|
||||
Trigger.prototype.StartCaptureTheRelicCountdown = function(winningPlayers, capturer)
|
||||
{
|
||||
const cmpTimer = Engine.QueryInterface(SYSTEM_ENTITY, IID_Timer);
|
||||
const cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
|
||||
|
||||
if (this.relicsVictoryTimer)
|
||||
{
|
||||
cmpTimer.CancelTimer(this.relicsVictoryTimer);
|
||||
this.relicsVictoryTimer = undefined;
|
||||
|
||||
const cmpGuiInterface = Engine.QueryInterface(SYSTEM_ENTITY, IID_GuiInterface);
|
||||
cmpGuiInterface.DeleteTimeNotification(this.ownRelicsVictoryMessage);
|
||||
cmpGuiInterface.DeleteTimeNotification(this.othersRelicsVictoryMessage);
|
||||
}
|
||||
@@ -115,52 +219,25 @@ Trigger.prototype.StartCaptureTheRelicCountdown = function(winningPlayers)
|
||||
if (!this.relics.length)
|
||||
return;
|
||||
|
||||
const others = [-1];
|
||||
for (let playerID = 1; playerID < TriggerHelper.GetNumberOfPlayers(); ++playerID)
|
||||
{
|
||||
const cmpPlayer = QueryPlayerIDInterface(playerID);
|
||||
if (cmpPlayer.HasWon())
|
||||
if (QueryPlayerIDInterface(playerID).HasWon())
|
||||
return;
|
||||
|
||||
if (winningPlayers.indexOf(playerID) == -1)
|
||||
others.push(playerID);
|
||||
}
|
||||
|
||||
// The first relic owner represents the winning players when no capture triggered the countdown (diplomacy changed).
|
||||
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();
|
||||
this.CheckCaptureTheRelicCountdown({ "capturer": capturer });
|
||||
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);
|
||||
|
||||
const captureTheRelicDuration = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager).GetGameSettings().relicDuration;
|
||||
this.relicsVictoryTimer = cmpTimer.SetTimeout(SYSTEM_ENTITY, IID_Trigger,
|
||||
"CaptureTheRelicVictorySetWinner", captureTheRelicDuration, winningPlayers);
|
||||
|
||||
this.SendRelicCaptureNotification(capturer ?? cmpPlayer.GetPlayerID());
|
||||
};
|
||||
|
||||
Trigger.prototype.CaptureTheRelicVictorySetWinner = function(winningPlayers)
|
||||
@@ -182,6 +259,7 @@ Trigger.prototype.CaptureTheRelicVictorySetWinner = function(winningPlayers)
|
||||
const cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
|
||||
cmpTrigger.relics = [];
|
||||
cmpTrigger.playerRelicsCount = [];
|
||||
cmpTrigger.totalRemainingRelics = 0;
|
||||
cmpTrigger.relicsVictoryTimer = undefined;
|
||||
cmpTrigger.ownRelicsVictoryMessage = undefined;
|
||||
cmpTrigger.othersRelicsVictoryMessage = undefined;
|
||||
@@ -193,3 +271,5 @@ Trigger.prototype.CaptureTheRelicVictorySetWinner = function(winningPlayers)
|
||||
cmpTrigger.RegisterTrigger("OnPlayerWon", "DeleteCaptureTheRelicVictoryMessages", { "enabled": true });
|
||||
cmpTrigger.RegisterTrigger("OnPlayerDefeated", "CheckCaptureTheRelicCountdown", { "enabled": true });
|
||||
}
|
||||
|
||||
Trigger.prototype.CAPTURE_NOTIFICATION_DURATION = 10000;
|
||||
Reference in new issue
Block a user