using System; using System.Linq; using Ashfall.Core; using Ashfall.Runtime; using Unity.Pipeline.Commands; using UnityEditor; using UnityEngine; namespace Ashfall.Editor { public static class PipelineCommands { [CliCommand("ashfall_setup", "Configure the Ashfall URP 2D prototype and startup scene.", Tags = new[] { "authoring" })] public static string Setup() { ProjectSetup.Configure(); return "Ashfall configured"; } [CliCommand("ashfall_build", "Build the Windows prototype.", Tags = new[] { "build" })] public static string Build() { ProjectSetup.BuildWindows(); return "Builds/Windows/AshfallFrontier.exe"; } [CliCommand("ashfall_start", "Start a fresh offline prototype while in Play Mode; archive existing saves first.", Tags = new[] { "editor/playmode" })] public static string Start(bool brood = true) { if (!EditorApplication.isPlaying) throw new InvalidOperationException("Enter Play Mode first."); var session = UnityEngine.Object.FindFirstObjectByType(); if (session == null) throw new InvalidOperationException("Game bootstrap is not ready yet."); session.StartFresh(brood ? Species.Brood : Species.Human, brood ? "蠕虫先锋" : "远征游骑兵"); return session.Status; } [CliCommand("ashfall_status", "Read prototype state without identity tokens or inventory mutations.", Tags = new[] { "observability" })] public static object Status() { var s = UnityEngine.Object.FindFirstObjectByType(); if (s == null) return new { running = false }; return new { running = s.Running, authority = s.IsAuthority, status = s.Status, tick = s.World?.tick, players = s.World?.players.Select(p => new { p.name, p.connected, p.species, p.broodForm, location = new { p.location.spaceId, p.location.floor, p.location.height, p.location.position.x, p.location.position.y }, p.stationId }).ToArray(), vehicles = s.World?.vehicles.Select(v => new { v.name, x = v.position.x, y = v.position.y, v.speed }).ToArray() }; } [CliCommand("ashfall_view_fixture", "Move the offline test character to a visual QA fixture (exterior, base, lab, transport).", Tags = new[] { "editor/playmode" })] public static string ViewFixture(string location = "exterior", int floor = 0) { var s = UnityEngine.Object.FindFirstObjectByType(); if (s?.LocalPlayer == null || !s.IsOffline) throw new InvalidOperationException("Requires a running offline prototype."); string space = location == "exterior" ? "world" : location == "transport" ? s.World.Vehicle("crawler").spaceId : location; if (s.World.Space(space)?.floors.Any(f => f.index == floor) != true) throw new ArgumentException("Fixture floor does not exist."); s.Command(new GameCommand { kind = CommandKind.LeaveStation }); s.LocalPlayer.location = WorldFactory.At(space, floor, space == "world" ? new V2(-3, -9) : new V2(0, -1)); s.LocalPlayer.transitionId = ""; s.LocalPlayer.portalReadyAt = s.World.time + 3; s.Simulation.CriticalChange?.Invoke(); return "Fixture ready: " + space + " " + floor; } } }