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<GameSession>();
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<GameSession>();
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<GameSession>();
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;
}
}
}
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<GameSession>();
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<GameSession>();
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<GameSession>();
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;
}
}
}