Adds HeykelSavasiContext runtime logic for Task 4.2: per-team statue break progress/winner tracking (extracted into a pure, testable StatueProgressState), OnDestructibleDied wiring against the base MiniGameContext's existing Destructible->Died auto-subscription, and SpawnStatueAsync which spawns the next statue (561) + 4 guards (580) via the map initializer using placeholder line-of-statues coordinates. OnGameStartAsync now spawns each team's first statue after the warp.
85 lines
3.5 KiB
C#
85 lines
3.5 KiB
C#
// <copyright file="HeykelSavasiContextTests.cs" company="MUnique">
|
|
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
|
|
// </copyright>
|
|
|
|
namespace MUnique.OpenMU.Tests.HeykelSavasi;
|
|
|
|
using MUnique.OpenMU.GameLogic.MiniGames;
|
|
|
|
/// <summary>
|
|
/// Tests for the Heykel Savasi team-balance rule.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <see cref="HeykelSavasiContext"/> derives from <see cref="MiniGameContext"/>, whose constructor
|
|
/// creates a map and launches a background game loop via <c>Task.Run</c>. Constructing a full context
|
|
/// is impractical in a fast unit test, so the balance decision is exposed as a pure static method,
|
|
/// <see cref="HeykelSavasiContext.IsJoinAllowed"/>, and tested directly against it.
|
|
/// </remarks>
|
|
[TestFixture]
|
|
public class HeykelSavasiContextTests
|
|
{
|
|
[Test]
|
|
public void BalanceRule_BlocksJoinWhenDifferenceWouldExceedTwo()
|
|
{
|
|
// Red 0, Blue 0 -> either team may be joined.
|
|
Assert.That(HeykelSavasiContext.IsJoinAllowed(0, 0, HeykelSavasiTeam.Red), Is.True);
|
|
|
|
// Red already has 2, Blue has 0. Adding a 3rd to Red would make the difference 3.
|
|
Assert.That(HeykelSavasiContext.IsJoinAllowed(2, 0, HeykelSavasiTeam.Red), Is.False, "2-0 iken Red'e katilim farki 3 yapar");
|
|
Assert.That(HeykelSavasiContext.IsJoinAllowed(2, 0, HeykelSavasiTeam.Blue), Is.True);
|
|
}
|
|
|
|
[Test]
|
|
public void BalanceRule_NoneTeamIsNeverJoinable()
|
|
{
|
|
Assert.That(HeykelSavasiContext.IsJoinAllowed(0, 0, HeykelSavasiTeam.None), Is.False);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exercises the statue-break progress/win-detection transition used by
|
|
/// <c>HeykelSavasiContext.HandleStatueDestroyed</c> (runtime) and
|
|
/// <c>HeykelSavasiContext.RegisterStatueDestroyedForTest</c> (test-only wrapper around it).
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Like <see cref="HeykelSavasiContext.IsJoinAllowed"/> above, the progress/winner transition is
|
|
/// extracted into a small dependency-free type, <see cref="HeykelSavasiContext.StatueProgressState"/>,
|
|
/// so it can be driven directly here instead of through a fully constructed
|
|
/// <see cref="HeykelSavasiContext"/> (which needs a live game context/map initializer and starts a
|
|
/// background game loop).
|
|
/// </remarks>
|
|
[Test]
|
|
public void StatueProgress_IncrementsAndDetectsWin()
|
|
{
|
|
var state = new HeykelSavasiContext.StatueProgressState();
|
|
|
|
// Red breaks Blue's 7 statues, one by one; the winner must not be set before the 7th.
|
|
for (var i = 0; i < 7; i++)
|
|
{
|
|
Assert.That(state.GetWinner(), Is.EqualTo(HeykelSavasiTeam.None));
|
|
state.RegisterDestroyed(i, HeykelSavasiTeam.Red);
|
|
}
|
|
|
|
Assert.That(state.GetWinner(), Is.EqualTo(HeykelSavasiTeam.Red));
|
|
Assert.That(state.GetProgress(HeykelSavasiTeam.Red), Is.EqualTo(7));
|
|
}
|
|
|
|
[Test]
|
|
public void StatueProgress_IgnoresFurtherRegistrationsAfterWinnerIsSet()
|
|
{
|
|
var state = new HeykelSavasiContext.StatueProgressState();
|
|
|
|
for (var i = 0; i < 7; i++)
|
|
{
|
|
state.RegisterDestroyed(i, HeykelSavasiTeam.Blue);
|
|
}
|
|
|
|
Assert.That(state.GetWinner(), Is.EqualTo(HeykelSavasiTeam.Blue));
|
|
|
|
// A further "destruction" for the other team must not overwrite the already-decided winner.
|
|
state.RegisterDestroyed(0, HeykelSavasiTeam.Red);
|
|
|
|
Assert.That(state.GetWinner(), Is.EqualTo(HeykelSavasiTeam.Blue));
|
|
Assert.That(state.GetProgress(HeykelSavasiTeam.Red), Is.EqualTo(0));
|
|
}
|
|
}
|