Add real-time lighting and shadows, training courses and targets, and animated salvage crates. Include bilingual assets and curated verification results.
158 lines
6.0 KiB
C#
158 lines
6.0 KiB
C#
using System;
|
|
using System.IO;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEngine.InputSystem;
|
|
using UnityEngine.InputSystem.LowLevel;
|
|
|
|
namespace Ironspore.Editor
|
|
{
|
|
public static class RecoverySmoke
|
|
{
|
|
static Keyboard keyboard;
|
|
static float began;
|
|
static int step;
|
|
static ProfileStore testStore;
|
|
static Result result;
|
|
static string folder;
|
|
public static string Begin(string outputFolder = "Docs/QA/Prototype")
|
|
{
|
|
folder = outputFolder;
|
|
var game = GameSession.Active;
|
|
if (!EditorApplication.isPlaying || !game)
|
|
throw new Exception("Play mode required");
|
|
if (game.InField)
|
|
game.EndSortie(true);
|
|
game.SelectedChassis = 2;
|
|
game.StartTrial();
|
|
game.Store.Commit(s => { s.alloy = 0; s.cells = 0; s.blueprints.Clear(); s.unlocked.Clear(); return true; });
|
|
testStore = game.Store;
|
|
result = new Result();
|
|
step = 0;
|
|
began = Time.realtimeSinceStartup;
|
|
keyboard = InputSystem.AddDevice<Keyboard>("RecoverySmokeKeyboard");
|
|
Application.runInBackground = true;
|
|
EditorWindow.GetWindow(Type.GetType("UnityEditor.GameView,UnityEditor")).Focus();
|
|
EditorApplication.update += Tick;
|
|
return "Recovery playback running for approximately 30 seconds.";
|
|
}
|
|
static void Teleport(Vector3 position)
|
|
{
|
|
var pilot = GameSession.Active.Pilot;
|
|
var controller = pilot.GetComponent<CharacterController>();
|
|
controller.enabled = false;
|
|
pilot.transform.position = position;
|
|
controller.enabled = true;
|
|
}
|
|
static void Tick()
|
|
{
|
|
try
|
|
{
|
|
Advance();
|
|
}
|
|
catch (Exception ex) { result.error = ex.ToString(); Finish(); }
|
|
}
|
|
static void Advance()
|
|
{
|
|
var game = GameSession.Active;
|
|
float t = Time.realtimeSinceStartup - began;
|
|
var state = new KeyboardState();
|
|
if (t >= 1 && step == 0)
|
|
{
|
|
Teleport(new Vector3(-8, .1f, -8.3f));
|
|
step++;
|
|
}
|
|
if (t >= 1.2f && t < 1.35f)
|
|
state.Press(Key.E);
|
|
if (t >= 2 && step == 1)
|
|
{
|
|
Teleport(new Vector3(9, .1f, -2.3f));
|
|
step++;
|
|
}
|
|
if (t >= 2.2f && t < 2.35f)
|
|
state.Press(Key.E);
|
|
if (t >= 3 && step == 2)
|
|
{
|
|
result.search = game.Run.cargo.Count == 2;
|
|
if (!result.search)
|
|
throw new Exception("Two real crate interactions did not produce two stacks.");
|
|
game.SelectedCargo.Add(game.Run.cargo[0].uid);
|
|
game.CloseMenu();
|
|
step++;
|
|
}
|
|
if (t >= 3.5f && t < 9.5f)
|
|
state.Press(Key.G);
|
|
if (t >= 4.3f && step == 3)
|
|
{
|
|
game.Pilot.Damage(5);
|
|
step++;
|
|
}
|
|
if (t >= 4.6f && step == 4)
|
|
{
|
|
result.interruption = game.CargoProgress < .5f && !game.Run.podUsed && game.Run.cargo.Count == 2;
|
|
foreach (var enemy in UnityEngine.Object.FindObjectsByType<EnemyUnit>())
|
|
enemy.Damage(10000);
|
|
step++;
|
|
}
|
|
if (t >= 9.5f && step == 5)
|
|
{
|
|
result.shipped = game.Run.podUsed && game.Store.Data.blueprints.Count == 1 && game.Run.cargo.Count == 1;
|
|
game.CompleteObjective();
|
|
game.NextZone(0);
|
|
result.crossZone = game.Run.podUsed && game.Run.cargo.Count == 1;
|
|
step++;
|
|
}
|
|
if (t >= 10.5f && step == 6)
|
|
{
|
|
game.Pilot.Damage(10000);
|
|
step++;
|
|
}
|
|
if (t >= 11.5f && step == 7)
|
|
{
|
|
result.loss = testStore.Data.blueprints.Count == 1 && testStore.Data.cells == 0 && testStore.Data.run.cargo.Count == 0 && !testStore.Data.run.active;
|
|
game.StartTrial();
|
|
testStore = game.Store;
|
|
game.Store.Commit(s => { s.cells = 0; return true; });
|
|
foreach (var enemy in UnityEngine.Object.FindObjectsByType<EnemyUnit>())
|
|
enemy.Damage(10000);
|
|
game.Store.AddCargo("cells", 3, "extraction_sample");
|
|
Teleport(new Vector3(-19, .1f, -8));
|
|
game.World.CallExtraction();
|
|
step++;
|
|
}
|
|
if (t >= 27.5f && step == 8)
|
|
{
|
|
result.arrivalDoesNotBank = game.World.TransportReady && game.Run.active && game.Store.Data.cells == 0;
|
|
step++;
|
|
}
|
|
if (t >= 28 && t < 28.2f)
|
|
state.Press(Key.E);
|
|
if (t >= 29 && step == 9)
|
|
{
|
|
result.boarding = testStore.Data.cells == 3 && !testStore.Data.run.active;
|
|
result.passed = result.search && result.interruption && result.shipped && result.crossZone && result.loss && result.arrivalDoesNotBank && result.boarding;
|
|
Finish();
|
|
return;
|
|
}
|
|
InputSystem.QueueStateEvent(keyboard, state);
|
|
if (t > 35)
|
|
throw new Exception("Recovery playback timeout");
|
|
}
|
|
static void Finish()
|
|
{
|
|
EditorApplication.update -= Tick;
|
|
if (keyboard != null && keyboard.added)
|
|
InputSystem.RemoveDevice(keyboard);
|
|
keyboard = null;
|
|
Directory.CreateDirectory(folder + "/TestResults");
|
|
File.WriteAllText(folder + "/TestResults/RecoveryPlayback.json", JsonUtility.ToJson(result, true));
|
|
}
|
|
[Serializable]
|
|
sealed class Result
|
|
{
|
|
public bool passed, search, interruption, shipped, crossZone, loss, arrivalDoesNotBank, boarding;
|
|
public string error;
|
|
}
|
|
}
|
|
}
|