Add notifications when a player capture a relic

This commit is contained in:
Atrik 2026-05-01 20:27:45 +02:00
parent 0892b6e434
commit b20b908a11

View file

@ -13,6 +13,7 @@ Trigger.prototype.InitCaptureTheRelic = function()
const cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
const numSpawnedRelics = cmpEndGameManager.GetGameSettings().relicCount;
this.totalRelics = numSpawnedRelics;
this.playerRelicsCount = new Array(TriggerHelper.GetNumberOfPlayers()).fill(0, 1);
this.playerRelicsCount[0] = numSpawnedRelics;
@ -37,14 +38,216 @@ Trigger.prototype.CheckCaptureTheRelicVictory = function(data)
{
warn("Relic entity " + data.entity + " has been destroyed.");
this.relics.splice(this.relics.indexOf(data.entity), 1);
--this.totalRelics;
}
else
{
++this.playerRelicsCount[data.to];
this.SendRelicCaptureNotification(data.to);
}
this.DeleteCaptureTheRelicVictoryMessages();
this.CheckCaptureTheRelicCountdown();
};
Trigger.prototype.GetTeamRelicCounts = function()
{
const activePlayers = Engine.QueryInterface(SYSTEM_ENTITY, IID_PlayerManager).GetActivePlayers();
const cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
// If not allied victory, just use individual counts
if (!cmpEndGameManager.GetAlliedVictory())
return {
"getTeamCount": (playerID) => this.playerRelicsCount[playerID] || 0,
"getTeamForPlayer": (playerID) => ({ "players": [playerID], "count": this.playerRelicsCount[playerID] || 0 })
};
// For allied victory, sum relics of all mutual allies
return {
"getTeamCount": (playerID) =>
{
const cmpDiplomacy = QueryPlayerIDInterface(playerID, IID_Diplomacy);
if (!cmpDiplomacy)
return this.playerRelicsCount[playerID] || 0;
return cmpDiplomacy.GetMutualAllies().reduce((sum, pid) =>
{
if (activePlayers.indexOf(pid) !== -1)
sum += this.playerRelicsCount[pid] || 0;
return sum;
}, 0);
},
"getTeamForPlayer": (playerID) =>
{
const cmpDiplomacy = QueryPlayerIDInterface(playerID, IID_Diplomacy);
if (!cmpDiplomacy)
return { "players": [playerID], "count": this.playerRelicsCount[playerID] || 0 };
const team = cmpDiplomacy.GetMutualAllies().filter(pid => activePlayers.indexOf(pid) !== -1);
return {
"players": team,
"count": team.reduce((sum, pid) => sum + (this.playerRelicsCount[pid] || 0), 0)
};
}
};
};
Trigger.prototype.SendRelicCaptureNotification = function(playerID)
{
const teamData = this.GetTeamRelicCounts();
const teamCount = teamData.getTeamCount(playerID);
const total = this.totalRelics;
const isCompleted = teamCount >= total;
const cmpEndGameManager = Engine.QueryInterface(SYSTEM_ENTITY, IID_EndGameManager);
const isAlliedVictory = cmpEndGameManager.GetAlliedVictory();
if (isAlliedVictory)
{
const alliance = teamData.getTeamForPlayer(playerID);
const isMultiPlayer = alliance.players.length > 1;
// Get player groups
const alliesExceptCapturer = isMultiPlayer ? alliance.players.filter(pid => pid !== playerID) : [];
const allPlayers = [];
for (let i = 1; i < TriggerHelper.GetNumberOfPlayers(); ++i)
{
const cmpPlayer = QueryPlayerIDInterface(i);
if (cmpPlayer && cmpPlayer.GetState() !== "defeated")
allPlayers.push(i);
}
const nonAllies = allPlayers.filter(pid => pid !== playerID && alliance.players.indexOf(pid) === -1);
if (isCompleted)
{
// Capturer
const ownerMessage = isMultiPlayer ?
markForTranslation("You and your allies have captured all relics!") :
markForTranslation("You have captured all relics!");
TriggerHelper.SendNotification(ownerMessage, [playerID], 10000);
// Allies
if (alliesExceptCapturer.length > 0)
{
const allyMessage = markForTranslation("%(_player_)s has captured the last relic! Your alliance has captured all relics!");
TriggerHelper.SendNotification(allyMessage, alliesExceptCapturer, 10000,
{ "_player_": playerID }, ["_player_"]);
}
// Non-allies
if (nonAllies.length > 0)
{
const othersMessage = isMultiPlayer ?
markForPluralTranslation(
"%(_player_)s has captured the last relic!",
"%(_player_)s and their allies have captured all %(total)s relics!",
total) :
markForPluralTranslation(
"%(_player_)s has captured the last relic!",
"%(_player_)s has captured all %(total)s relics!",
total);
TriggerHelper.SendNotification(othersMessage, nonAllies, 10000,
{ "total": total, "_player_": playerID }, ["_player_"]);
}
}
else
{
if (isMultiPlayer)
{
// Capturer
const ownerMessage = markForTranslation("You have captured a relic. Your alliance now has %(count)s of %(total)s relics.");
TriggerHelper.SendNotification(ownerMessage, [playerID], 10000,
{ "count": teamCount, "total": total });
// Allies
if (alliesExceptCapturer.length > 0)
{
const allyMessage = markForTranslation("%(_player_)s has captured a relic. Your alliance now has %(count)s of %(total)s relics.");
TriggerHelper.SendNotification(allyMessage, alliesExceptCapturer, 10000,
{ "count": teamCount, "total": total, "_player_": playerID }, ["_player_"]);
}
// Non-allies
if (nonAllies.length > 0)
{
const othersMessage = markForTranslation("%(_player_)s has captured a relic. Their alliance now has %(count)s of %(total)s relics.");
TriggerHelper.SendNotification(othersMessage, nonAllies, 10000,
{ "count": teamCount, "total": total, "_player_": playerID }, ["_player_"]);
}
}
else
{
// Single player, no allies - use dual notification
const othersMessage = markForPluralTranslation(
"%(_player_)s has captured a relic (%(count)s/%(total)s).",
"%(_player_)s has captured %(count)s of %(total)s relics.",
teamCount);
const ownerMessage = markForPluralTranslation(
"You have captured a relic (%(count)s/%(total)s).",
"You have captured %(count)s of %(total)s relics.",
teamCount);
TriggerHelper.SendDualNotification(
playerID,
ownerMessage,
othersMessage,
10000,
{ "count": teamCount, "total": total },
{},
{ "_player_": playerID }
);
}
}
}
else
{
// Non-allied victory - individual counts only
const count = this.playerRelicsCount[playerID];
if (isCompleted)
{
const othersMessage = markForPluralTranslation(
"%(_player_)s has captured the last relic!",
"%(_player_)s has captured all %(total)s relics!",
total);
const ownerMessage = markForTranslation("You have captured all relics!");
TriggerHelper.SendDualNotification(
playerID,
ownerMessage,
othersMessage,
10000,
{ "total": total },
{},
{ "_player_": playerID }
);
}
else
{
const othersMessage = markForPluralTranslation(
"%(_player_)s has captured a relic (%(count)s/%(total)s).",
"%(_player_)s has captured %(count)s of %(total)s relics.",
count);
const ownerMessage = markForPluralTranslation(
"You have captured a relic (%(count)s/%(total)s).",
"You have captured %(count)s of %(total)s relics.",
count);
TriggerHelper.SendDualNotification(
playerID,
ownerMessage,
othersMessage,
10000,
{ "count": count, "total": total },
{},
{ "_player_": playerID }
);
}
}
};
/**
* 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.
@ -126,38 +329,66 @@ Trigger.prototype.StartCaptureTheRelicCountdown = function(winningPlayers)
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 isAlliedVictory = cmpEndGameManager.GetAlliedVictory();
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);
if (isAlliedVictory && winningPlayers.length > 1)
{
// Use first relic owner as representative
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;
}
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.othersRelicsVictoryMessage = cmpGuiInterface.AddTimeNotification({
"message": markForTranslation("%(_player_)s and their allies have captured all relics and will win in %(time)s."),
"players": others,
"parameters": {
"_player_": cmpPlayer.GetPlayerID()
},
"translateMessage": true,
"translateParameters": ["_player_"]
}, captureTheRelicDuration);
this.ownRelicsVictoryMessage = cmpGuiInterface.AddTimeNotification({
"message": markForTranslation("You and your allies have captured all relics and will win in %(time)s."),
"players": winningPlayers,
"translateMessage": true
}, captureTheRelicDuration);
}
else
{
// Single player victory
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;
}
this.othersRelicsVictoryMessage = cmpGuiInterface.AddTimeNotification({
"message": markForTranslation("%(_player_)s has captured all relics and will win in %(time)s."),
"players": others,
"parameters": {
"_player_": cmpPlayer.GetPlayerID()
},
"translateMessage": true,
"translateParameters": ["_player_"]
}, captureTheRelicDuration);
this.ownRelicsVictoryMessage = cmpGuiInterface.AddTimeNotification({
"message": 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);
@ -182,6 +413,7 @@ Trigger.prototype.CaptureTheRelicVictorySetWinner = function(winningPlayers)
const cmpTrigger = Engine.QueryInterface(SYSTEM_ENTITY, IID_Trigger);
cmpTrigger.relics = [];
cmpTrigger.playerRelicsCount = [];
cmpTrigger.totalRelics = 0;
cmpTrigger.relicsVictoryTimer = undefined;
cmpTrigger.ownRelicsVictoryMessage = undefined;
cmpTrigger.othersRelicsVictoryMessage = undefined;