Fix deferred province conquest notifications (#8709)

This commit is contained in:
2026-07-18 21:31:25 -07:00
committed by GitHub
parent 33f4c41fdd
commit 8a29847cc4
6 changed files with 102 additions and 33 deletions
@@ -41,6 +41,7 @@ namespace eagle.Notifications {
{ PrisonerReleasedDetails, PrisonerReleasedDetailsNotificationGenerator.Generator },
{ PrisonerExiledDetails, PrisonerExiledDetailsNotificationGenerator.Generator },
{ PrisonerReturnedDetails, PrisonerReturnedDetailsNotificationGenerator.Generator },
{ ProvinceConqueredDetails, ProvinceConqueredDetailsNotificationGenerator.Generator },
{ ProvinceHeldDetails, ProvinceHeldDetailsNotificationGenerator.Generator },
{ QuestFailed, QuestFailedDetailsNotificationGenerator.Generator },
{ QuestFulfilled, QuestFulfilledDetailsNotificationGenerator.Generator },
@@ -0,0 +1,29 @@
using System.Collections.Generic;
using Net.Eagle0.Eagle.Views;
namespace eagle.Notifications.ARNNotifications {
public static class ProvinceConqueredDetailsNotificationGenerator {
public static readonly ARNNotificationGenerator Generator = GenerateNotification;
private static IEnumerable<Notification> GenerateNotification(
Net.Eagle0.Eagle.Common.Notification notification,
IGameModel currentModel) {
var playerId = currentModel.PlayerId;
var details = notification.Details.ProvinceConqueredDetails;
var province = currentModel.Provinces[details.ProvinceId];
var winner = currentModel.MaybeDestroyedFaction(details.ConqueringFactionId);
var loser = currentModel.MaybeDestroyedFaction(details.DefendingFactionId);
var winnerHead = currentModel.Heroes[winner.FactionHeadId];
var loserHead = currentModel.Heroes[loser.FactionHeadId];
if (!playerId.HasValue || (playerId.Value != winner.Id && playerId.Value != loser.Id)) {
yield return new Notification(
title: "Province Conquered",
text: $"{winner.Name} has conquered {province.Name} from {loser.Name}.",
singleProvinceId: details.ProvinceId,
displayedHeroes: new List<HeroView> { winnerHead, loserHead });
}
}
}
}
@@ -16,7 +16,6 @@ namespace eagle.Notifications {
{ NewRoundAction, NewRoundNotificationGenerator.Generator },
{ PrisonerEscaped, PrisonerEscapedNotificationGenerator.Generator },
{ PrisonerReturnTookEffect, PrisonerReturnedNotificationGenerator.Generator },
{ ProvinceConquered, ProvinceConqueredNotificationGenerator.Generator },
{ ProvinceEventsChanged, ProvinceEventsNotificationGenerator.Generator },
{ RiotAverted, RiotAvertedNotificationGenerator.Generator },
{ RiotOccurred, RiotOccurredNotificationGenerator.Generator },
@@ -43,4 +42,4 @@ namespace eagle.Notifications {
}
}
}
}
}
@@ -1,31 +0,0 @@
using System.Collections.Generic;
using Net.Eagle0.Eagle.Views;
namespace eagle.Notifications {
public static class ProvinceConqueredNotificationGenerator {
public static readonly NotificationGenerator Generator = GenerateNotification;
private static IEnumerable<Notification> GenerateNotification(
ActionResultView actionResultView,
IGameModel currentModel) {
var playerId = currentModel.PlayerId;
var provinceBefore = currentModel.Provinces[actionResultView.Province.Value];
if (provinceBefore.RulingFactionId.HasValue) {
var winner = currentModel.MaybeDestroyedFaction(actionResultView.Player.Value);
var loser =
currentModel.MaybeDestroyedFaction(provinceBefore.RulingFactionId.Value);
var winnerHead = currentModel.Heroes[winner.FactionHeadId];
var loserHead = currentModel.Heroes[loser.FactionHeadId];
if (!playerId.HasValue ||
(playerId.Value != winner.Id && playerId.Value != loser.Id)) {
yield return new Notification(
title: "Province Conquered",
text: $"{winner.Name} has conquered {provinceBefore.Name} from {loser.Name}.",
singleProvinceId: actionResultView.Province.Value,displayedHeroes: new List<HeroView> { winnerHead,loserHead });
}
}
}
}
}
@@ -44,6 +44,77 @@ namespace eagle0.Tests {
Assert.DoesNotThrow(updater.Dispose);
}
[Test]
public void EndAftermathDeliversDeferredProvinceConqueredNotification() {
const long gameId = 7128;
const int observingFactionId = 3;
const int conqueringFactionId = 1;
const int defendingFactionId = 5;
const int conqueringHeroId = 10;
const int defendingHeroId = 50;
const int provinceId = 35;
var notifications = new List<Notification>();
var updater = new GameModelUpdater(gameId, observingFactionId, null) {
NoteRecipient = notifications.Add,
UpdateAction =
_ => {}
};
var startingState = new GameStateView { GameId = gameId };
startingState.Factions.Add(
conqueringFactionId,
new FactionView {
Id = conqueringFactionId,
FactionHeadId = conqueringHeroId,
Name = "The Eagle"
});
startingState.Factions.Add(
defendingFactionId,
new FactionView {
Id = defendingFactionId,
FactionHeadId = defendingHeroId,
Name = "Tumala's Defenders"
});
startingState.Heroes.Add(conqueringHeroId, new HeroView { Id = conqueringHeroId });
startingState.Heroes.Add(defendingHeroId, new HeroView { Id = defendingHeroId });
startingState.Provinces.Add(
provinceId,
new ProvinceView {
Id = provinceId,
Name = "Tumala",
RulingFactionId = conqueringFactionId
});
updater.ReceiveGameUpdate(new GameUpdate {
GameId = gameId,
StartingState = startingState,
ActionResultResponse = new ActionResultResponse()
});
var endAftermath = new ActionResultView { Type = ActionResultType.EndAftermathPhase };
endAftermath.Notifications.Add(new Net.Eagle0.Eagle.Common.Notification {
Details =
new Net.Eagle0.Eagle.Common.NotificationDetails {
ProvinceConqueredDetails =
new Net.Eagle0.Eagle.Common.ProvinceConqueredDetails {
ProvinceId = provinceId,
ConqueringFactionId = conqueringFactionId,
DefendingFactionId = defendingFactionId
}
}
});
var response = new ActionResultResponse { UnfilteredResultCountAfter = 1 };
response.ActionResultViews.Add(endAftermath);
updater.ReceiveGameUpdate(
new GameUpdate { GameId = gameId, ActionResultResponse = response });
Assert.AreEqual(1, notifications.Count);
Assert.AreEqual("Province Conquered", notifications[0].Title);
Assert.AreEqual(
"The Eagle has conquered Tumala from Tumala's Defenders.",
notifications[0].Text);
CollectionAssert.AreEqual(new[] { provinceId }, notifications[0].ProvinceIds);
}
[Test]
public void ResultBearingUpdateDefensivelyReplacesCommandsWhenTokenIsUnchanged() {
const long gameId = 7124;