champions-of-luneraria/Assets/Luneraria/Tests/UI/PlayMode/S1RulesViewsTests.cs
Martin Stickelbroeck fb5c92dd37 S3 Neutrallager und Fog of War mit Spähern (LoL, Dota 2)
Erweiterte Regeln: in jeder dritten Runde ein neutraler Wächter in jeder
Lanemitte; wer beim Fall mehr Einheiten (dann mehr Leben) in 8 m hat, nimmt
das Lager: Glutsegen (+10 % Schaden), Mondschild (Schild 10 %), Beute
(50 Gold je Spieler). Fog of War (LuneFog, nur Darstellung): Gegner sichtbar
in 9 m um eigene Einheiten, 10 m um Gebäude, 12 m um Späher; Späher (40 Gold,
3 Runden, Teamwirkung) zeigen in der Planung die gegnerische Armee ihrer Lane.
HUD: Teampanel SPÄHER und LAGER, Lager-Sechseck, Nebel in Feld, Minimap,
Namensschildern und Lane-Zählung.
Kern 597/597 (s3 31), EditMode 33/33, PlayMode 18/18, Verify 718/0,
Selbsttest 30/30, Golden 0, Fingerabdruck unverändert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 16:30:57 +02:00

121 lines
5.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections;
using System.Linq;
using Luneraria.Core;
using Luneraria.View;
using NUnit.Framework;
using UnityEngine;
using UnityEngine.TestTools;
namespace Luneraria.UI.Tests
{
/// <summary>
/// S1: the extended rules in the real scene. S1Hud checks the champion income in the gold display and the champion tooltip, the barracks mark of a
/// lane, exhaustion and the buyback button of the hero window, and the Mondsegen in the team
/// header. Fixtures set public match state only (a fallen tower, a fallen hero, blessing
/// stacks), as the G3 verify does. S1Bilder (explicit) captures the evidence at 1920×1080;
/// LUNE_EVIDENCE names the folder below docs/port/screenshots (default s1/spiel).
/// </summary>
public sealed class S1RulesViewsTests
{
static void Send(HudSession s, Command command)
{
CommandResult result = s.Match.Submit(HudSession.Human, command);
Assert.IsTrue(result.Ok, command.Type + ": " + result.Message);
s.Game.RebuildPreview();
s.Sync();
}
static IEnumerator WaitReady(HudSession s)
{
float waited = 0f;
while (s.Hud.ReadyBlocked() && waited < 5f)
{
waited += Time.unscaledDeltaTime;
yield return null;
}
}
/// <summary>One round with a booked champion and a hero that falls; returns in the next planning.</summary>
static IEnumerator Prepare(HudSession s)
{
Assert.IsTrue(s.Match.Extended, "the driver started an extended match");
yield return s.Starter();
s.Leave();
Send(s, Command.HeroBuy("held_sylvara"));
Send(s, Command.ChampionBook("ch_belagerung", "mid"));
s.Game.Key(KeyCode.Space);
yield return HudSession.Frames(2);
Assert.AreEqual(LuneMatchRunner.Stage.Combat, s.Runner.Current, "combat starts");
LuneUnit hero = s.Match.Combat.Units.First(u => u.Kind == "hero" && u.OwnerSlot == HudSession.Human);
hero.Hp = 0.0;
yield return s.FinishCombat();
yield return WaitReady(s);
// Public fixtures: Rot's inner mid tower fell earlier, Blau won the grotto twice.
s.Match.BuildingHp["rot_mid_inner"] = 0.0;
s.Match.BuildingHp["rot_mid_outer"] = 0.0;
s.Match.Boss.Blessing[0] = 2;
s.Sync();
}
[UnityTest, Timeout(600000)]
public IEnumerator S1Hud()
{
var s = new HudSession();
yield return s.Open(1920, 1080, seed: 4, startRound: 6, extraGold: 1500, extended: true);
yield return Prepare(s);
Assert.AreEqual(15, s.Me.IncomeBonus, "the Keilbrecher adds 15 income");
string texts = s.Texts();
StringAssert.Contains("davon 15 Söldner", texts, "the gold display shows the champion income");
StringAssert.Contains("SEGEN 2/4", texts, "the team header shows the Mondsegen");
Assert.IsTrue(HudSession.Visible(s.Hud.Lanes["mid"].Barracks), "mid shows the barracks mark");
bool topBroken = s.Match.BarracksBroken(0, "top") || s.Match.BarracksBroken(1, "top");
Assert.AreEqual(topBroken, HudSession.Visible(s.Hud.Lanes["top"].Barracks), "top shows the mark exactly when an inner top tower fell");
Assert.IsTrue(s.Me.Hero.Exhausted, "the fallen hero is exhausted");
s.Hud.OpenHero();
yield return HudSession.Frames(2);
s.Sync();
Assert.IsNotNull(s.Hud.HeroDetail.BuybackButton, "the hero window offers the buyback");
int gold = s.Me.Draft.Gold;
int cost = s.Match.BuybackCost(s.Me.Draft.Hero);
s.Click(s.Hud.HeroDetail.BuybackButton);
yield return HudSession.Frames(2);
s.Sync();
Assert.AreEqual(gold - cost, s.Me.Draft.Gold, "the buyback costs " + cost);
Assert.IsFalse(s.Me.Draft.Hero.Exhausted, "the hero is bought back");
Assert.IsNull(s.Hud.HeroDetail.BuybackButton, "no buyback button afterwards");
s.Hud.CloseModal();
s.Close();
}
[UnityTest, Timeout(600000), Explicit("Bildwerkzeug: nur gezielt per -testFilter")]
public IEnumerator S1Bilder()
{
string evidence = Environment.GetEnvironmentVariable("LUNE_EVIDENCE");
string folder = "docs/port/screenshots/" + (string.IsNullOrEmpty(evidence) ? "s1/spiel" : evidence) + "/";
var s = new HudSession();
yield return s.Open(1920, 1080, seed: 4, startRound: 6, extraGold: 1500, extended: true);
yield return Prepare(s);
yield return new WaitForSecondsRealtime(.5f);
yield return s.Shot(folder + "01-planung-einkommen-kaserne-mondsegen.png");
s.Hover(s.Hud.Lanes["mid"]);
yield return new WaitForSecondsRealtime(.3f);
yield return s.Shot(folder + "02-kaserne-tooltip.png");
s.Leave();
s.Hud.OpenHero();
yield return new WaitForSecondsRealtime(.6f);
yield return s.Shot(folder + "03-rueckkauf.png");
s.Hud.CloseModal();
s.Game.Key(KeyCode.Space);
yield return HudSession.Frames(2);
yield return s.Fight(12.0);
s.Driver.Paused = true;
LuneUnit monster = s.Match.Combat.Units.Where(u => u.Kind == "monster" && u.Team == 0 && u.Lane == "mid" && u.Alive).OrderByDescending(u => u.Progress).FirstOrDefault();
if (monster != null)
s.Rig.LookAt(monster.Position, 20f, true);
yield return new WaitForSecondsRealtime(.5f);
yield return s.Shot(folder + "04-verstaerkte-welle-mid.png");
s.Close();
}
}
}