feat(CS-P3): full siege objective chain - guardian statues (Destructible spawn) + dual Crown Switch hold + throne capture gating

This commit is contained in:
Acentech Dev
2026-07-15 01:52:19 +03:00
parent 5549c2bec7
commit c50af5e5c2
7 changed files with 234 additions and 15 deletions

View File

@@ -67,27 +67,53 @@ public class CastleSiegeContextTest
Assert.That(ctx.RegisteredGuilds, Does.Contain("Attackers"));
}
/// <summary>Tests that the throne-holding guild at siege end becomes the owner on settlement (P3).</summary>
/// <summary>Tests the full siege objective chain: destroy statues, hold both switches, then capture the throne.</summary>
[Test]
public async Task ThroneCaptureDuringSiegeBecomesOwnerOnSettlementAsync()
public async Task FullSiegeObjectiveChainToOwnershipAsync()
{
var ctx = new CastleSiegeContext(Config());
await ctx.ForceStartRegistrationAsync(T0);
await ctx.ForcePhaseAsync(CastleSiegePhase.Siege, T0);
ctx.CaptureThrone("Attackers");
ctx.SetStatueCount(2);
// Throne blocked until statues destroyed + both switches held.
Assert.That(ctx.TryCaptureThrone("Attackers").Success, Is.False);
ctx.NotifyStatueDestroyed();
ctx.NotifyStatueDestroyed();
ctx.HoldSwitch(217, "Attackers");
Assert.That(ctx.TryCaptureThrone("Attackers").Success, Is.False); // only one switch held
ctx.HoldSwitch(218, "Attackers");
Assert.That(ctx.TryCaptureThrone("Attackers").Success, Is.True); // both switches + statues down
Assert.That(ctx.OccupierGuildName, Is.EqualTo("Attackers"));
await ctx.TickAsync(T0.AddMinutes(20)); // Siege -> Settlement
await ctx.TickAsync(T0.AddMinutes(20)); // Settlement -> Ownership (owner assigned)
Assert.That(ctx.Phase, Is.EqualTo(CastleSiegePhase.Ownership));
await ctx.TickAsync(T0.AddMinutes(20)); // Settlement -> Ownership
Assert.That(ctx.OwnerGuildName, Is.EqualTo("Attackers"));
}
/// <summary>Tests that capturing the throne outside the siege phase is a no-op.</summary>
/// <summary>Tests that a rival guild holding only one switch cannot steal the throne.</summary>
[Test]
public void CaptureThroneOutsideSiegeIsNoOp()
public async Task ThroneRequiresBothSwitchesBySameGuildAsync()
{
var ctx = new CastleSiegeContext(Config());
ctx.CaptureThrone("Attackers");
await ctx.ForceStartRegistrationAsync(T0);
await ctx.ForcePhaseAsync(CastleSiegePhase.Siege, T0);
ctx.SetStatueCount(0);
ctx.HoldSwitch(217, "A");
ctx.HoldSwitch(218, "B");
Assert.That(ctx.TryCaptureThrone("A").Success, Is.False);
Assert.That(ctx.TryCaptureThrone("B").Success, Is.False);
}
/// <summary>Tests that objective actions outside the siege phase are no-ops.</summary>
[Test]
public void ObjectiveActionsOutsideSiegeAreNoOp()
{
var ctx = new CastleSiegeContext(Config());
ctx.HoldSwitch(217, "A");
Assert.That(ctx.TryCaptureThrone("A").Success, Is.False);
Assert.That(ctx.OccupierGuildName, Is.Null);
}