203 lines
9.6 KiB
C#
203 lines
9.6 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using BumpCombat.Defense;
|
|
using BumpCombat.Defense.Comparison;
|
|
using NUnit.Framework;
|
|
|
|
namespace BumpCombat.PlayModeTests
|
|
{
|
|
public sealed class Defense25DPersonalMissionPlayModeTests
|
|
{
|
|
private readonly List<int> openPortalIds = new();
|
|
private readonly List<Defense25DPersonalMissionSpawnRequest> spawnedRequests = new();
|
|
private readonly List<string> queuedRewardTokens = new();
|
|
private Defense25DPersonalMissions missions;
|
|
private bool runCanAcceptMissions;
|
|
private bool allowRewardQueue;
|
|
private int nextSpawnId;
|
|
|
|
[SetUp]
|
|
public void SetUp()
|
|
{
|
|
openPortalIds.Clear();
|
|
spawnedRequests.Clear();
|
|
queuedRewardTokens.Clear();
|
|
runCanAcceptMissions = true;
|
|
allowRewardQueue = true;
|
|
nextSpawnId = 100;
|
|
missions = new Defense25DPersonalMissions();
|
|
missions.Bind(
|
|
new[] { 3, 6, 3 },
|
|
() => runCanAcceptMissions,
|
|
() => openPortalIds,
|
|
SpawnTargets,
|
|
QueueReward);
|
|
missions.Reset(7, 12345);
|
|
}
|
|
|
|
[Test]
|
|
public void StartRequiresEnoughOpenPortalsAndRejectsConcurrentMission()
|
|
{
|
|
openPortalIds.AddRange(new[] { 2, 0, 2 });
|
|
|
|
Assert.That(missions.CanStart(1, out string reason), Is.False);
|
|
Assert.That(reason, Does.Contain("3"));
|
|
Assert.That(missions.TryStart(1), Is.False);
|
|
Assert.That(spawnedRequests, Is.Empty);
|
|
|
|
openPortalIds.AddRange(new[] { 1, 3 });
|
|
Assert.That(missions.TryStart(1), Is.True);
|
|
Assert.That(spawnedRequests, Has.Count.EqualTo(3));
|
|
Assert.That(spawnedRequests.Select(request => request.PortalId).Distinct().Count(), Is.EqualTo(3));
|
|
Assert.That(spawnedRequests.All(request =>
|
|
request.RunGeneration == 7
|
|
&& request.MissionId == 1
|
|
&& request.MissionInstanceId == 1
|
|
&& request.Source == Defense25DSpawnSource.PersonalMission), Is.True);
|
|
Assert.That(missions.TryStart(2), Is.False);
|
|
}
|
|
|
|
[Test]
|
|
public void MissionTargetsAreThreeSixAndThreeAndOnlyDeathsQueueOneReward()
|
|
{
|
|
for (int missionId = 1; missionId <= 3; missionId++)
|
|
{
|
|
openPortalIds.Clear();
|
|
for (int portalId = 0; portalId < 6; portalId++)
|
|
openPortalIds.Add(portalId);
|
|
|
|
int firstSpawnIndex = spawnedRequests.Count;
|
|
Assert.That(missions.TryStart(missionId), Is.True);
|
|
int targetCount = new[] { 3, 6, 3 }[missionId - 1];
|
|
IReadOnlyList<int> targetIds = missions.States[missionId - 1].TargetSpawnIds;
|
|
Assert.That(targetIds, Has.Count.EqualTo(targetCount));
|
|
|
|
for (int i = 0; i < targetIds.Count - 1; i++)
|
|
{
|
|
Assert.That(missions.ResolveTarget(7, targetIds[i], Defense25DSpawnSource.PersonalMission,
|
|
missionId, missions.States[missionId - 1].MissionInstanceId, DefenseEnemyResolution.Death), Is.True);
|
|
Assert.That(missions.States[missionId - 1].Status, Is.EqualTo(Defense25DPersonalMissionStatus.Active));
|
|
}
|
|
|
|
Assert.That(missions.ResolveTarget(7, targetIds[targetIds.Count - 1],
|
|
Defense25DSpawnSource.PersonalMission, missionId,
|
|
missions.States[missionId - 1].MissionInstanceId, DefenseEnemyResolution.Death), Is.True);
|
|
Assert.That(missions.States[missionId - 1].Status, Is.EqualTo(Defense25DPersonalMissionStatus.RewardPending));
|
|
Assert.That(missions.ResolveTarget(7, targetIds[0], DefenseEnemyResolution.Death), Is.False);
|
|
Assert.That(queuedRewardTokens, Has.Count.EqualTo(missionId));
|
|
Assert.That(queuedRewardTokens[missionId - 1], Is.EqualTo($"personal-mission:7:{missionId}"));
|
|
if (missionId < 3)
|
|
Assert.That(missions.TryStart(missionId + 1), Is.False);
|
|
Assert.That(missions.TryCompleteReward(7, missions.States[missionId - 1].MissionInstanceId), Is.True);
|
|
Assert.That(missions.States[missionId - 1].Status, Is.EqualTo(Defense25DPersonalMissionStatus.Completed));
|
|
Assert.That(missions.TryCompleteReward(7, missions.States[missionId - 1].MissionInstanceId), Is.False);
|
|
Assert.That(spawnedRequests.Skip(firstSpawnIndex).Take(targetCount)
|
|
.Select(request => request.PortalId).Distinct().Count(), Is.EqualTo(targetCount));
|
|
}
|
|
}
|
|
|
|
[Test]
|
|
public void RewardQueueFailureStaysPendingUntilQueuedAndChoiceIsConfirmed()
|
|
{
|
|
openPortalIds.AddRange(Enumerable.Range(0, 3));
|
|
Assert.That(missions.TryStart(1), Is.True);
|
|
Defense25DPersonalMissionState mission = missions.States[0];
|
|
allowRewardQueue = false;
|
|
|
|
foreach (int spawnId in mission.TargetSpawnIds)
|
|
Assert.That(missions.ResolveTarget(7, spawnId, DefenseEnemyResolution.Death), Is.True);
|
|
|
|
Assert.That(mission.Status, Is.EqualTo(Defense25DPersonalMissionStatus.RewardPending));
|
|
Assert.That(mission.RewardQueued, Is.False);
|
|
Assert.That(queuedRewardTokens, Is.Empty);
|
|
Assert.That(missions.TryCompleteReward(7, mission.MissionInstanceId), Is.False);
|
|
|
|
allowRewardQueue = true;
|
|
Assert.That(missions.TryQueuePendingReward(7, mission.MissionInstanceId), Is.True);
|
|
Assert.That(queuedRewardTokens, Has.Count.EqualTo(1));
|
|
Assert.That(missions.TryQueuePendingReward(7, mission.MissionInstanceId), Is.False);
|
|
Assert.That(mission.Status, Is.EqualTo(Defense25DPersonalMissionStatus.RewardPending));
|
|
Assert.That(missions.TryStart(2), Is.False);
|
|
Assert.That(missions.TryCompleteReward(7, mission.MissionInstanceId), Is.True);
|
|
Assert.That(mission.Status, Is.EqualTo(Defense25DPersonalMissionStatus.Completed));
|
|
}
|
|
|
|
[Test]
|
|
public void ArrivalFailsImmediatelyAndDoesNotResolveRemainingEnemiesOrReward()
|
|
{
|
|
openPortalIds.AddRange(Enumerable.Range(0, 3));
|
|
Assert.That(missions.TryStart(1), Is.True);
|
|
IReadOnlyList<int> targets = missions.States[0].TargetSpawnIds;
|
|
|
|
Assert.That(missions.ResolveTarget(7, targets[0], DefenseEnemyResolution.Arrival), Is.True);
|
|
Assert.That(missions.States[0].Status, Is.EqualTo(Defense25DPersonalMissionStatus.Failed));
|
|
Assert.That(missions.States[0].RemainingTargetCount, Is.EqualTo(2));
|
|
Assert.That(missions.ResolveTarget(7, targets[1], DefenseEnemyResolution.Death), Is.True);
|
|
Assert.That(missions.States[0].RemainingTargetCount, Is.EqualTo(1));
|
|
Assert.That(queuedRewardTokens, Is.Empty);
|
|
}
|
|
|
|
[Test]
|
|
public void UnownedGlobalEliteAndBossSummonIdsCannotCountAsMissionTargets()
|
|
{
|
|
openPortalIds.AddRange(Enumerable.Range(0, 3));
|
|
Assert.That(missions.TryStart(1), Is.True);
|
|
Defense25DPersonalMissionState mission = missions.States[0];
|
|
int globalEliteId = mission.TargetSpawnIds[0];
|
|
int bossSummonId = mission.TargetSpawnIds[1];
|
|
|
|
Assert.That(missions.ResolveTarget(7, globalEliteId, Defense25DSpawnSource.GlobalElite,
|
|
1, mission.MissionInstanceId, DefenseEnemyResolution.Death), Is.False);
|
|
Assert.That(missions.ResolveTarget(7, bossSummonId, Defense25DSpawnSource.BossSummon,
|
|
1, mission.MissionInstanceId, DefenseEnemyResolution.Death), Is.False);
|
|
Assert.That(missions.States[0].RemainingTargetCount, Is.EqualTo(3));
|
|
Assert.That(queuedRewardTokens, Is.Empty);
|
|
Assert.That(spawnedRequests.All(request => request.Source == Defense25DSpawnSource.PersonalMission), Is.True);
|
|
}
|
|
|
|
[Test]
|
|
public void ResetClearsMissionOwnershipAndRejectsStaleGenerationCallbacks()
|
|
{
|
|
openPortalIds.AddRange(Enumerable.Range(0, 3));
|
|
Assert.That(missions.TryStart(1), Is.True);
|
|
int staleSpawnId = missions.States[0].TargetSpawnIds[0];
|
|
|
|
missions.Reset(8, 54321);
|
|
|
|
Assert.That(missions.Generation, Is.EqualTo(8));
|
|
Assert.That(missions.States.All(state => state.Status == Defense25DPersonalMissionStatus.Available), Is.True);
|
|
Assert.That(missions.ResolveTarget(7, staleSpawnId, DefenseEnemyResolution.Death), Is.False);
|
|
Assert.That(missions.TryCompleteReward(7, 1), Is.False);
|
|
Assert.That(queuedRewardTokens, Is.Empty);
|
|
|
|
Assert.That(missions.TryStart(1), Is.True);
|
|
Assert.That(missions.States[0].MissionInstanceId, Is.EqualTo(1));
|
|
Assert.That(missions.States[0].TargetSpawnIds[0], Is.Not.EqualTo(staleSpawnId));
|
|
}
|
|
|
|
private bool SpawnTargets(
|
|
IReadOnlyList<Defense25DPersonalMissionSpawnRequest> requests,
|
|
out IReadOnlyList<int> spawnIds)
|
|
{
|
|
var ids = new List<int>(requests.Count);
|
|
foreach (Defense25DPersonalMissionSpawnRequest request in requests)
|
|
{
|
|
spawnedRequests.Add(request);
|
|
ids.Add(nextSpawnId++);
|
|
}
|
|
|
|
spawnIds = ids;
|
|
return true;
|
|
}
|
|
|
|
private bool QueueReward(string token)
|
|
{
|
|
if (!allowRewardQueue)
|
|
return false;
|
|
|
|
queuedRewardTokens.Add(token);
|
|
return true;
|
|
}
|
|
}
|
|
}
|