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
{
///
/// U5.5 overall check of a whole Glutpakt army in the real game: the human seat buys all ten
/// Glutpakt troops (the upgrades as their base troop, then upgraded) and hires the hero
/// Funkenlanze in round 3; the camera shows the formation close and at lane distance, the fight
/// close, at lane distance and from above the map. Like HudViewsTests, commands go straight to
/// the match followed by the preview rebuild. A capture tool, not part of the suite:
/// -testFilter "Luneraria.UI.Tests.ArmyViewsTests"; LUNE_EVIDENCE names the folder below
/// docs/port/screenshots (default u5.5-heer).
///
[Explicit("Bildwerkzeug: nur gezielt per -testFilter")]
public sealed class ArmyViewsTests
{
static readonly string[] Bunds = { "wurzelbund", "glutpakt", "glutpakt", "wurzelbund", "wurzelbund", "glutpakt" };
static readonly string[] Troops = { "g01", "g02", "g03", "g04", "g05", "g06", "g07", "g08", "g09", "g10" };
string _folder;
IEnumerator Shot(HudSession s, string label)
{
yield return s.Shot(_folder + label + ".png");
}
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 Vec2 Centre(System.Collections.Generic.IEnumerable units)
{
var list = units.ToList();
Assert.IsNotEmpty(list, "own figures on the field");
double x = list.Average(u => u.Position.X), y = list.Average(u => u.Position.Y);
return new Vec2(x, y);
}
[UnityTest, Timeout(900000)]
public IEnumerator Glutpakt()
{
string evidence = Environment.GetEnvironmentVariable("LUNE_EVIDENCE");
_folder = "docs/port/screenshots/" + (string.IsNullOrEmpty(evidence) ? "u5.5-heer" : evidence) + "/";
var s = new HudSession();
yield return s.Open(1920, 1080, seed: 4, bunds: Bunds);
s.Match.RoundNumber = 3;
s.Me.Draft.Gold = 100000;
foreach (string troop in Troops)
{
string baseId = ContentData.Units.Keys.FirstOrDefault(id => DataCatalog.UpgradeOf(id) == troop);
Send(s, Command.Buy(baseId ?? troop, s.Me.Lane));
if (baseId != null)
Send(s, Command.Upgrade(s.Me.Draft.Roster.Last().Uid));
}
Send(s, Command.HeroBuy("held_funkenlanze"));
s.Me.Draft.Gold = 400;
s.Sync();
yield return new WaitForSecondsRealtime(.5f);
Assert.AreEqual(Troops.Length, s.Me.Draft.Roster.Count(e => Troops.Contains(e.TypeId)), "all ten Glutpakt troops");
Vec2 formation = Centre(s.View.Preview.Units.Where(u => u.Team == s.Me.Team && (Troops.Contains(u.Def.Id) || u.Kind == "hero")));
s.Rig.LookAt(formation, 14f, true);
yield return new WaitForSecondsRealtime(.5f);
yield return Shot(s, "01-aufstellung-nah");
s.Rig.LookAt(formation, 22f, true);
yield return new WaitForSecondsRealtime(.5f);
yield return Shot(s, "02-aufstellung-lane");
s.Game.Key(KeyCode.Space);
yield return HudSession.Frames(1);
Assert.AreEqual(LuneMatchRunner.Stage.Combat, s.Runner.Current, "combat of round 3");
yield return s.Fight(9.0);
s.Driver.Paused = true;
// The front of the own army (as in FigureViewsTests): the troop furthest along the lane.
Vec2 front = s.Match.Combat.Units.Where(u => u.Alive && u.Team == s.Me.Team && Troops.Contains(u.Def.Id))
.OrderByDescending(u => u.Progress).First().Position;
s.Rig.LookAt(front, 14f, true);
yield return new WaitForSecondsRealtime(.5f);
yield return Shot(s, "03-kampf-nah");
s.Rig.LookAt(front, 22f, true);
yield return new WaitForSecondsRealtime(.5f);
yield return Shot(s, "04-kampf-lane");
s.Rig.LookAt(front, 40f, true);
yield return new WaitForSecondsRealtime(.5f);
yield return Shot(s, "05-kampf-weit");
s.Close();
}
}
}