champions-of-luneraria/Assets/Luneraria/Tests/UI/PlayMode/H1HeroViewsTests.cs
Martin Stickelbroeck 542a9646c8 H2 Brunhild: Figur, Skin Eiswalküre, Oberfläche, Nachweise
Meshy-Figur Brunhild (28.706 Dreiecke mit Lane-Fassung und Speer) mit
Ultimate-Clip Jump Attack, 113 Credits. Skin Eiswalküre über skin_variant.py
(Farbband über Rot, Mindestsättigung schützt Hauttöne). Heldenwahl bei fünf
Helden kompakter; Tests auf fünf Helden angehoben.
Kern 619/619 (h2 22), EditMode 34/34, PlayMode 19/19, Verify 718/0,
Selbsttest 30/30, Golden 0, Fingerabdruck unverändert; A/B mit Sylvara:
Karte gleich, Mid nah -4 %.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 17:21:50 +02:00

180 lines
9.2 KiB
C#
Raw Permalink 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>
/// H1: Sylvara in the real scene. SylvaraHud checks the HUD (four heroes to recruit, the tab
/// "Ultimate & Skin" with four rule cards and two skin cards, the command slot of the hero
/// card, commands from the cards) and that her figure, clips and skin material reach the
/// field. SylvaraBilder is the capture tool for the H1 evidence (1920×1080): recruiting,
/// the ultimate tab, the planning formation, the leap, the Mondsicheltanz and the Blutmond
/// skin; -testFilter "Luneraria.UI.Tests.H1HeroViewsTests.SylvaraBilder", LUNE_EVIDENCE
/// names the folder below docs/port/screenshots (default h1/spiel).
/// </summary>
public sealed class H1HeroViewsTests
{
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 LuneUnit Hero(HudSession s)
{
return s.Match.Combat?.Units.FirstOrDefault(u => u.Kind == "hero" && u.OwnerSlot == HudSession.Human);
}
static LuneUnitView ViewOf(LuneUnit unit)
{
return UnityEngine.Object.FindObjectsByType<LuneUnitView>(FindObjectsSortMode.None).FirstOrDefault(v => v.Unit == unit);
}
/// <summary>Steps the combat in single simulation steps until the condition holds (or the combat ends).</summary>
static IEnumerator Until(HudSession s, Func<bool> done, double limit = 60.0)
{
double time = 0.0;
while (!done() && time < limit && s.Runner.Current == LuneMatchRunner.Stage.Combat)
{
s.Runner.Advance(.05);
time += .05;
if ((int)(time / .05) % 10 == 0)
yield return null;
}
yield return HudSession.Frames(2);
s.Sync();
}
[UnityTest, Timeout(600000)]
public IEnumerator SylvaraHud()
{
var s = new HudSession();
yield return s.Open(1920, 1080, seed: 4, startRound: 6, extraGold: 1500);
s.Hud.OpenHero();
yield return HudSession.Frames(2);
s.Sync();
Assert.AreEqual(LuneContent.Heroes.Count, s.Hud.HeroDetail.RecruitButtons.Count, "every hero can be recruited");
Assert.IsTrue(s.Hud.HeroDetail.RecruitButtons.ContainsKey("held_sylvara"), "Sylvara can be recruited");
s.Click(s.Hud.HeroDetail.RecruitButtons["held_sylvara"]);
yield return HudSession.Frames(2);
s.Sync();
Assert.AreEqual("held_sylvara", s.Me.Draft.Hero?.HeroId, "the recruit button buys Sylvara");
s.Hud.OpenHero(LuneHeroDetail.TabUltimate);
yield return HudSession.Frames(2);
s.Sync();
Assert.AreEqual(4, s.Hud.HeroDetail.RuleCards.Count, "four trigger rules");
Assert.AreEqual(2, s.Hud.HeroDetail.SkinCards.Count, "standard look and Blutmond");
Assert.IsTrue(s.Hud.HeroDetail.RuleCards["gruppe"].On, "default rule Gruppe is marked");
s.Click(s.Hud.HeroDetail.RuleCards["zweite_reihe"]);
yield return HudSession.Frames(2);
s.Sync();
Assert.AreEqual("zweite_reihe", s.Me.Draft.Hero.Ultimate, "a rule card sets the rule");
s.Click(s.Hud.HeroDetail.SkinCards["blutmond"]);
yield return HudSession.Frames(2);
s.Sync();
Assert.AreEqual("blutmond", s.Me.Draft.Hero.Skin, "a skin card sets the skin");
Assert.IsTrue(HudSession.Visible(s.Hud.HeroCard.CommandSlot), "the hero card shows the ultimate");
StringAssert.Contains("ZWEITE REIHE", s.Hud.HeroCard.CommandSlot.Text, "the command slot names the rule");
s.Hud.CloseModal();
s.Game.Key(KeyCode.Space);
yield return HudSession.Frames(2);
LuneUnit hero = Hero(s);
Assert.IsNotNull(hero, "Sylvara fights");
Assert.AreEqual("blutmond", hero.Def.Skin);
yield return HudSession.Frames(3);
LuneUnitView view = ViewOf(hero);
Assert.IsNotNull(view, "Sylvara has a view");
Animator animator = view.GetComponentInChildren<Animator>();
Assert.IsNotNull(animator, "skinned figure");
Assert.IsTrue(animator.HasState(0, Animator.StringToHash("leap")) && animator.HasState(0, Animator.StringToHash("ultimate")), "leap and ultimate clips");
string[] materials = view.GetComponentsInChildren<Renderer>().SelectMany(r => r.sharedMaterials).Where(m => m != null).Select(m => m.name).Distinct().ToArray();
Assert.Contains("AI_Sylvara_Blutmond", materials, "the Blutmond material is dressed: " + string.Join(", ", materials));
Assert.Contains("AI_SylvaraSichel_Blutmond", materials, "both sickles in Blutmond");
yield return Until(s, () => hero.UltimateSerial > 0 || !hero.Alive);
Assert.IsTrue(hero.UltimateSerial > 0 || !hero.Alive, "the ultimate fires (or Sylvara fell first)");
if (hero.UltimateSerial > 0)
StringAssert.Contains("GENUTZT", s.Hud.HeroCard.CommandSlot.Text, "the card reports the fired ultimate");
s.Close();
}
[UnityTest, Timeout(900000), Explicit("Bildwerkzeug: nur gezielt per -testFilter")]
public IEnumerator SylvaraBilder()
{
string evidence = Environment.GetEnvironmentVariable("LUNE_EVIDENCE");
string folder = "docs/port/screenshots/" + (string.IsNullOrEmpty(evidence) ? "h1/spiel" : evidence) + "/";
var s = new HudSession();
yield return s.Open(1920, 1080, seed: 4, startRound: 6, extraGold: 1500);
yield return s.Starter();
s.Leave();
s.Hud.OpenHero();
yield return new WaitForSecondsRealtime(.6f);
yield return s.Shot(folder + "01-heldenwahl.png");
Send(s, Command.HeroBuy("held_sylvara"));
s.Hud.OpenHero(LuneHeroDetail.TabValues);
yield return new WaitForSecondsRealtime(.6f);
yield return s.Shot(folder + "02-heldenfenster.png");
s.Hud.OpenHero(LuneHeroDetail.TabUltimate);
yield return new WaitForSecondsRealtime(.8f);
yield return s.Shot(folder + "03-ultimate-und-skin.png");
s.Hud.CloseModal();
yield return new WaitForSecondsRealtime(.3f);
LuneUnit waiting = s.View.Preview?.Units.FirstOrDefault(u => u.Kind == "hero" && u.OwnerSlot == HudSession.Human);
Assert.IsNotNull(waiting, "Sylvara in the planning preview");
s.Rig.LookAt(waiting.Position, 9f, true);
yield return new WaitForSecondsRealtime(.6f);
yield return s.Shot(folder + "04-aufstellung.png");
s.Game.Key(KeyCode.Space);
yield return HudSession.Frames(2);
LuneUnit hero = Hero(s);
yield return Until(s, () => hero.LeapSerial > 0 || !hero.Alive);
s.Driver.Paused = true;
s.Rig.LookAt(hero.Position, 11f, true);
yield return new WaitForSecondsRealtime(.3f);
yield return s.Shot(folder + "05-mondsprung.png");
s.Driver.Paused = false;
yield return Until(s, () => hero.UltimateSerial > 0 || !hero.Alive);
s.Driver.Paused = true;
s.Rig.LookAt(hero.Position, 11f, true);
yield return new WaitForSecondsRealtime(.2f);
yield return s.Shot(folder + "06-mondsicheltanz.png");
yield return new WaitForSecondsRealtime(.6f);
yield return s.Shot(folder + "07-mondsicheltanz-wirbel.png");
s.Rig.LookAt(hero.Position, 20f, true);
yield return new WaitForSecondsRealtime(.4f);
yield return s.Shot(folder + "08-kampf-lane.png");
s.Driver.Paused = false;
yield return s.FinishCombat();
// Space is blocked for a moment after a combat (no accidental skip of the planning).
float waited = 0f;
while (s.Hud.ReadyBlocked() && waited < 5f)
{
waited += Time.unscaledDeltaTime;
yield return null;
}
Send(s, Command.HeroSkin("blutmond"));
s.Hud.OpenHero(LuneHeroDetail.TabUltimate);
yield return new WaitForSecondsRealtime(.8f);
yield return s.Shot(folder + "09-skin-blutmond-fenster.png");
s.Hud.CloseModal();
int round = s.Match.RoundNumber;
s.Game.Key(KeyCode.Space);
yield return HudSession.Frames(2);
Assert.AreEqual(LuneMatchRunner.Stage.Combat, s.Runner.Current, "combat of round " + round);
hero = Hero(s);
yield return s.Fight(9.0);
s.Driver.Paused = true;
s.Rig.LookAt(hero.Position, 9f, true);
yield return new WaitForSecondsRealtime(.5f);
yield return s.Shot(folder + "10-skin-blutmond-kampf.png");
s.Close();
}
}
}