Preserve final tactical battle action (#8623)

This commit is contained in:
2026-07-15 13:57:36 -07:00
committed by GitHub
parent 0d361f5ad7
commit fcf9246562
2 changed files with 84 additions and 2 deletions
@@ -1097,6 +1097,10 @@ namespace eagle {
if (entry.NewDate is {} newDate) {
_currentModel.GsView.CurrentDate = newDate;
foreach (var shardokGameId in _currentModel.ShardokGameModels.Keys) {
_shardokResultCounts.TryRemove(shardokGameId, out _);
_shardokNeedsResync.TryRemove(shardokGameId, out _);
}
_currentModel.ShardokGameModels.Clear();
}
@@ -1135,9 +1139,14 @@ namespace eagle {
// the Eagle update removing the battle arrives before the Shardok Victory update.
if (_currentModel.ShardokGameModels.TryGetValue(rb, out var sgm)) {
sgm.MarkBattleEnded("Battle has ended.");
_currentModel.ShardokGameModels.TryRemove(rb, out _);
// Keep the model and its result count until the normal date-change cleanup.
// A final Shardok result can still be queued behind this Eagle update. It
// must reach the existing model so the last action and unit removals appear
// before the player exits the battle.
} else {
_shardokResultCounts.TryRemove(rb, out _);
_shardokNeedsResync.TryRemove(rb, out _);
}
_shardokResultCounts.TryRemove(rb, out _);
for (int i = 0; i < _currentModel.ShardokBattles.Count; i++) {
if (_currentModel.ShardokBattles[i].ShardokGameId == rb) {
@@ -95,6 +95,79 @@ namespace eagle0.Tests {
command.SealedValueCase);
}
[Test]
public void RemovedBattleRetainsModelForQueuedFinalShardokResult() {
const long gameId = 7125;
const string shardokGameId = "finished-battle";
const int fleeingUnitId = 41;
IGameModel currentModel = null;
var updater = new GameModelUpdater(gameId, null, null) {
UpdateAction = model => currentModel = model
};
updater.ReceiveGameUpdate(new GameUpdate {
GameId = gameId,
ActionResultResponse = new ActionResultResponse()
});
var shardokModel = new ShardokGameModel(
gameId,
shardokGameId,
0,
null,
null,
"Test Province",
1,
new List<ShardokGameModel.PlayerWithHostility>(),
new Dictionary<int, string>(),
new Dictionary<int, string>(),
new Dictionary<int, string>());
shardokModel.UnitsById[fleeingUnitId] = new UnitViewWithName(
new Net.Eagle0.Shardok.Api.UnitView { UnitId = fleeingUnitId },
null,
null,
null);
currentModel.ShardokGameModels[shardokGameId] = shardokModel;
var battleRemovedDiff = new GameStateViewDiff();
battleRemovedDiff.RemovedBattleIds.Add(shardokGameId);
var battleRemovedResponse = new ActionResultResponse { UnfilteredResultCountAfter = 1 };
battleRemovedResponse.ActionResultViews.Add(new ActionResultView {
Type = ActionResultType.QuestFulfilled,
GameStateDiff = battleRemovedDiff
});
updater.ReceiveGameUpdate(new GameUpdate {
GameId = gameId,
ActionResultResponse = battleRemovedResponse
});
Assert.IsTrue(shardokModel.CanExitBattle);
Assert.AreSame(shardokModel, currentModel.ShardokGameModels[shardokGameId]);
var finalDiff = new Net.Eagle0.Shardok.Api.GameStateViewDiff();
finalDiff.RemovedUnits.Add(fleeingUnitId);
var finalShardokResponse =
new ShardokActionResultResponse.Types.SingleShardokGameResultResponse {
ShardokGameId = shardokGameId,
NewResultViewCount = 1,
AvailableCommands = new Net.Eagle0.Shardok.Api.AvailableCommands()
};
finalShardokResponse.ActionResultViews.Add(new Net.Eagle0.Shardok.Api.ActionResultView {
Type = Net.Eagle0.Shardok.Common.ActionType.Fled,
Actor = fleeingUnitId,
GameStateViewDiff = finalDiff
});
updater.ReceiveGameUpdate(new GameUpdate {
GameId = gameId,
ShardokActionResultResponse =
new ShardokActionResultResponse {
ShardokGameResponses = { finalShardokResponse }
}
});
Assert.AreEqual(1, shardokModel.History.Count);
Assert.IsFalse(shardokModel.UnitsById.ContainsKey(fleeingUnitId));
}
private static AvailableCommands
AvailableCommandsWith(long token, int provinceId, AvailableCommand command) {
var result = new AvailableCommands { Token = token, SuggestedProvinceId = provinceId };