2026-11-12 12:28:40 +08:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.InputSystem;
|
|
|
|
|
|
|
|
|
|
namespace Ironspore
|
|
|
|
|
{
|
|
|
|
|
public sealed class GameSession : MonoBehaviour
|
|
|
|
|
{
|
|
|
|
|
public static GameSession Active
|
|
|
|
|
{
|
|
|
|
|
get; private set;
|
|
|
|
|
}
|
|
|
|
|
public ChassisDefinition[] chassis;
|
|
|
|
|
public EquipmentDefinition[] equipment;
|
|
|
|
|
public GameObject mechModel;
|
|
|
|
|
public InputActionAsset inputTemplate;
|
|
|
|
|
public UnityEngine.UIElements.StyleSheet uiStyle;
|
|
|
|
|
public UnityEngine.UIElements.PanelSettings uiPanel;
|
|
|
|
|
public LocalizationCatalog localization;
|
2026-11-12 18:03:04 +08:00
|
|
|
public WorldLightingProfile lightingProfile;
|
2026-11-12 12:28:40 +08:00
|
|
|
public bool startInRange;
|
|
|
|
|
public ProfileStore Store
|
|
|
|
|
{
|
|
|
|
|
get; private set;
|
|
|
|
|
}
|
|
|
|
|
ProfileStore mainStore;
|
|
|
|
|
public RunRecord Run => Store.Data.run;
|
|
|
|
|
public MechPilot Pilot
|
|
|
|
|
{
|
|
|
|
|
get; private set;
|
|
|
|
|
}
|
|
|
|
|
public WarzoneDirector World
|
|
|
|
|
{
|
|
|
|
|
get; private set;
|
|
|
|
|
}
|
|
|
|
|
public GameHud Hud
|
|
|
|
|
{
|
|
|
|
|
get; private set;
|
|
|
|
|
}
|
|
|
|
|
public InputActionAsset Input
|
|
|
|
|
{
|
|
|
|
|
get; private set;
|
|
|
|
|
}
|
2026-11-12 18:01:54 +08:00
|
|
|
public SettingsService Settings { get; private set; }
|
2026-11-12 12:28:40 +08:00
|
|
|
public readonly List<string> SelectedCargo = new List<string>();
|
|
|
|
|
public bool MenuOpen { get; private set; } = true;
|
|
|
|
|
public bool Paused
|
|
|
|
|
{
|
|
|
|
|
get; private set;
|
|
|
|
|
}
|
|
|
|
|
public bool Trial
|
|
|
|
|
{
|
|
|
|
|
get; private set;
|
|
|
|
|
}
|
|
|
|
|
public int SelectedChassis = 1;
|
2026-11-12 18:02:26 +08:00
|
|
|
public readonly string[] SelectedInstances = new string[4];
|
2026-11-12 12:28:40 +08:00
|
|
|
public int[] InitialEquipment = { 0, 0, 0, 0 };
|
|
|
|
|
LocalizedMessage noticeMessage;
|
|
|
|
|
public string Notice => noticeMessage?.ToString() ?? "";
|
|
|
|
|
public float CargoProgress
|
|
|
|
|
{
|
|
|
|
|
get; private set;
|
|
|
|
|
}
|
|
|
|
|
public bool InField
|
|
|
|
|
{
|
|
|
|
|
get; private set;
|
|
|
|
|
}
|
|
|
|
|
LocalizedMessage reportMessage = GameLocalization.Message("report.ready");
|
|
|
|
|
public string Report => reportMessage.ToString();
|
|
|
|
|
float noticeUntil;
|
|
|
|
|
float autosaveTimer;
|
|
|
|
|
int cargoDamageFrame = -1;
|
|
|
|
|
bool ending;
|
|
|
|
|
|
|
|
|
|
void Awake()
|
|
|
|
|
{
|
|
|
|
|
Active = this;
|
|
|
|
|
GameLocalization.Initialize(localization);
|
2026-11-12 18:03:04 +08:00
|
|
|
Application.targetFrameRate = 60;
|
2026-11-12 18:02:26 +08:00
|
|
|
mainStore = new ProfileStore(ProfileStore.SavePath(false));
|
2026-11-12 12:28:40 +08:00
|
|
|
Store = mainStore;
|
|
|
|
|
Input = Instantiate(inputTemplate);
|
2026-11-12 18:01:54 +08:00
|
|
|
var defaults = SettingsService.RuntimeDefaults();
|
|
|
|
|
Settings = new SettingsService(new SettingsStore(Path.Combine(GameDataPaths.DirectoryPath, "settings.json"), defaults), Input, defaults);
|
2026-11-12 12:28:40 +08:00
|
|
|
Input.Enable();
|
|
|
|
|
World = gameObject.AddComponent<WarzoneDirector>();
|
|
|
|
|
Hud = gameObject.AddComponent<GameHud>();
|
|
|
|
|
Hud.Initialize(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Start()
|
|
|
|
|
{
|
|
|
|
|
World.BuildHangar();
|
|
|
|
|
Hud.ShowHangar();
|
|
|
|
|
SetMenu(true);
|
2026-11-12 18:02:26 +08:00
|
|
|
if (Run.active && (Run.destructionPending || Run.armor <= 0))
|
|
|
|
|
EndSortie(true);
|
2026-11-12 12:28:40 +08:00
|
|
|
if (startInRange)
|
|
|
|
|
StartTrial();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public EquipmentDefinition Part(int slot, int index)
|
|
|
|
|
{
|
2026-11-12 18:02:26 +08:00
|
|
|
string id = InventoryGrid.EquipmentId(slot, index);
|
|
|
|
|
return Array.Find(equipment, x => x.id == id);
|
2026-11-12 12:28:40 +08:00
|
|
|
}
|
|
|
|
|
public int PartCount(int slot) => Array.FindAll(equipment, x => x.slot == slot).Length;
|
|
|
|
|
public bool Fits(int frame, int[] parts)
|
|
|
|
|
{
|
|
|
|
|
float mass = 0, power = 0;
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
var p = Part(i, parts[i]);
|
2026-11-12 18:02:26 +08:00
|
|
|
if (parts[i] == -1) continue;
|
|
|
|
|
if (!p) return false;
|
2026-11-12 12:28:40 +08:00
|
|
|
mass += p.mass;
|
|
|
|
|
power += p.power;
|
|
|
|
|
}
|
|
|
|
|
return mass <= chassis[frame].massCapacity && power <= chassis[frame].powerCapacity;
|
|
|
|
|
}
|
|
|
|
|
public bool StartingPartsUnlocked()
|
|
|
|
|
{
|
2026-11-12 18:02:26 +08:00
|
|
|
for (int slot = 0; slot < 4; slot++)
|
|
|
|
|
{
|
|
|
|
|
if (InitialEquipment[slot] == 0 && SelectedInstances[slot] == null) continue;
|
|
|
|
|
string id = InventoryGrid.EquipmentId(slot, InitialEquipment[slot]);
|
|
|
|
|
if (!mainStore.Data.warehouse.Exists(i => i.itemId == id && (SelectedInstances[slot] == null || i.uid == SelectedInstances[slot]))) return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
2026-11-12 12:28:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void BeginSortie()
|
|
|
|
|
{
|
|
|
|
|
if (Store.Data.run.active)
|
|
|
|
|
{
|
|
|
|
|
Notify("notice.unfinished");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!Fits(SelectedChassis, InitialEquipment))
|
|
|
|
|
{
|
|
|
|
|
Notify("notice.budget");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (!StartingPartsUnlocked())
|
|
|
|
|
{
|
|
|
|
|
Notify("notice.researchFirst");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
Trial = false;
|
|
|
|
|
Store = mainStore;
|
2026-11-12 18:02:26 +08:00
|
|
|
if (!Store.Begin(SelectedChassis, InitialEquipment, chassis[SelectedChassis].armor, Environment.TickCount, selected: SelectedInstances))
|
2026-11-12 12:28:40 +08:00
|
|
|
{
|
|
|
|
|
NotifySaveFailure();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
EnterField();
|
|
|
|
|
}
|
|
|
|
|
public void StartTrial()
|
|
|
|
|
{
|
2026-11-12 18:02:26 +08:00
|
|
|
var range = new ProfileStore(ProfileStore.SavePath(true));
|
|
|
|
|
if ((range.Data.run.active && !range.Finish(true)) ||
|
|
|
|
|
!range.Begin(SelectedChassis, InitialEquipment, chassis[SelectedChassis].armor, 1739, trial: true))
|
|
|
|
|
{
|
|
|
|
|
Notify("notice.saveFailed");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-11-12 12:28:40 +08:00
|
|
|
Trial = true;
|
2026-11-12 18:02:26 +08:00
|
|
|
Store = range;
|
2026-11-12 12:28:40 +08:00
|
|
|
EnterField();
|
|
|
|
|
}
|
|
|
|
|
public void Resume()
|
|
|
|
|
{
|
|
|
|
|
Trial = false;
|
|
|
|
|
Store = mainStore;
|
2026-11-12 18:02:26 +08:00
|
|
|
if (Run.active && (Run.destructionPending || Run.armor <= 0)) EndSortie(true);
|
|
|
|
|
else if (Run.active) EnterField();
|
2026-11-12 12:28:40 +08:00
|
|
|
}
|
|
|
|
|
void EnterField()
|
|
|
|
|
{
|
|
|
|
|
ending = false;
|
|
|
|
|
InField = true;
|
|
|
|
|
SelectedCargo.Clear();
|
|
|
|
|
CargoProgress = 0;
|
|
|
|
|
World.BuildWarzone();
|
|
|
|
|
Pilot = World.Player;
|
|
|
|
|
SetMenu(false);
|
|
|
|
|
Hud.ShowField();
|
2026-11-12 18:01:54 +08:00
|
|
|
if (Trial)
|
|
|
|
|
Notify("notice.range", Settings.Bindings.Display("View"), Settings.Bindings.Display("Interact"));
|
|
|
|
|
else
|
|
|
|
|
Notify("notice.enter");
|
2026-11-12 12:28:40 +08:00
|
|
|
}
|
|
|
|
|
public void SetMenu(bool open)
|
|
|
|
|
{
|
|
|
|
|
MenuOpen = open;
|
|
|
|
|
Cursor.lockState = open ? CursorLockMode.None : CursorLockMode.Locked;
|
|
|
|
|
Cursor.visible = open;
|
|
|
|
|
if (Pilot)
|
|
|
|
|
Pilot.RequireFreshTrigger();
|
|
|
|
|
if (open)
|
|
|
|
|
CargoProgress = 0;
|
|
|
|
|
}
|
|
|
|
|
public void CloseMenu()
|
|
|
|
|
{
|
|
|
|
|
Paused = false;
|
|
|
|
|
Time.timeScale = 1;
|
|
|
|
|
if (InField)
|
|
|
|
|
{
|
|
|
|
|
SetMenu(false);
|
|
|
|
|
Hud.ShowField();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void Notify(string key, params object[] args)
|
|
|
|
|
{
|
|
|
|
|
noticeMessage = GameLocalization.Message(key, args);
|
|
|
|
|
noticeUntil = Time.unscaledTime + 5;
|
|
|
|
|
Hud.RefreshHangarNotice();
|
|
|
|
|
}
|
|
|
|
|
void NotifySaveFailure(string fallbackKey = "notice.saveFailed")
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(Store.Error))
|
|
|
|
|
Debug.LogError("Save failed: " + Store.Error);
|
|
|
|
|
Notify(string.IsNullOrEmpty(Store.Error) ? fallbackKey : "notice.saveFailed");
|
|
|
|
|
}
|
|
|
|
|
public InputAction Action(string name) => Input.FindAction("Pilot/" + name, true);
|
|
|
|
|
|
|
|
|
|
void Update()
|
|
|
|
|
{
|
|
|
|
|
if (Time.unscaledTime > noticeUntil)
|
|
|
|
|
noticeMessage = null;
|
|
|
|
|
if (!InField || !Pilot || ending)
|
|
|
|
|
return;
|
2026-11-12 18:02:26 +08:00
|
|
|
if (Pilot.Health <= 0 || Run.destructionPending)
|
|
|
|
|
{
|
|
|
|
|
EndSortie(true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-11-12 18:23:59 +08:00
|
|
|
if (Hud && (Hud.SettingsOpen || Hud.MenuInputConsumedThisFrame))
|
|
|
|
|
return;
|
2026-11-12 12:28:40 +08:00
|
|
|
if (Action("Pause").WasPressedThisFrame())
|
|
|
|
|
{
|
|
|
|
|
if (MenuOpen)
|
|
|
|
|
CloseMenu();
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Paused = true;
|
|
|
|
|
Time.timeScale = 0;
|
|
|
|
|
SetMenu(true);
|
|
|
|
|
Hud.ShowPause();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (Paused)
|
|
|
|
|
return;
|
|
|
|
|
Run.elapsed += Time.deltaTime;
|
|
|
|
|
if (Action("Inventory").WasPressedThisFrame())
|
|
|
|
|
{
|
|
|
|
|
if (MenuOpen)
|
|
|
|
|
CloseMenu();
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
SetMenu(true);
|
|
|
|
|
Hud.ShowCargo();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!MenuOpen && Action("Interact").WasPressedThisFrame() && World.Focused)
|
|
|
|
|
World.Focused.Activate();
|
|
|
|
|
TickCargo();
|
|
|
|
|
autosaveTimer += Time.deltaTime;
|
|
|
|
|
if (autosaveTimer >= 10)
|
|
|
|
|
{
|
|
|
|
|
SnapshotVitals();
|
|
|
|
|
Store.Commit(s => true);
|
|
|
|
|
autosaveTimer = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void TickCargo()
|
|
|
|
|
{
|
|
|
|
|
bool uninterrupted = Pilot.LastDamageFrame == cargoDamageFrame;
|
|
|
|
|
cargoDamageFrame = Pilot.LastDamageFrame;
|
|
|
|
|
bool preparing = !MenuOpen && !Run.podUsed && SelectedCargo.Count > 0 && Action("Cargo").IsPressed() && Pilot.Grounded && Action("Move").ReadValue<Vector2>().sqrMagnitude < .01f && Pilot.HorizontalSpeed < .2f && uninterrupted;
|
|
|
|
|
if (!preparing)
|
|
|
|
|
{
|
|
|
|
|
CargoProgress = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
CargoProgress += Time.deltaTime;
|
|
|
|
|
if (CargoProgress < 3)
|
|
|
|
|
return;
|
|
|
|
|
SnapshotVitals();
|
|
|
|
|
if (Store.SendCargo(SelectedCargo))
|
|
|
|
|
{
|
|
|
|
|
World.LaunchPod(Pilot.transform.position);
|
|
|
|
|
Notify("notice.podSecured");
|
|
|
|
|
GameAudio.Cue(720, .3f);
|
|
|
|
|
SelectedCargo.Clear();
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
NotifySaveFailure("notice.cargoUnavailable");
|
|
|
|
|
CargoProgress = 0;
|
|
|
|
|
}
|
|
|
|
|
public void ToggleCargo(string uid)
|
|
|
|
|
{
|
|
|
|
|
if (SelectedCargo.Contains(uid))
|
|
|
|
|
SelectedCargo.Remove(uid);
|
|
|
|
|
else
|
2026-11-12 18:02:26 +08:00
|
|
|
{
|
|
|
|
|
var next = new List<string>(SelectedCargo) { uid };
|
|
|
|
|
if (Store.CanSendCargo(next)) SelectedCargo.Add(uid);
|
|
|
|
|
else Notify("notice.twoSlots");
|
|
|
|
|
}
|
2026-11-12 12:28:40 +08:00
|
|
|
Hud.ShowCargo();
|
|
|
|
|
}
|
|
|
|
|
public void SnapshotVitals()
|
|
|
|
|
{
|
|
|
|
|
if (!Pilot)
|
|
|
|
|
return;
|
|
|
|
|
Run.armor = Mathf.Max(0, Pilot.Health);
|
|
|
|
|
Run.energy = Pilot.Energy;
|
|
|
|
|
}
|
|
|
|
|
public void Search(WorldInteractable target)
|
|
|
|
|
{
|
2026-11-12 18:02:26 +08:00
|
|
|
int index = target.offersPart ? Mathf.Clamp(target.partIndex, 0, PartCount(target.partSlot) - 1) : -1;
|
|
|
|
|
string offered = target.offersPart ? Part(target.partSlot, index).id : null;
|
|
|
|
|
if (!Store.AddCargo(target.itemId, target.amount, target.key, offered))
|
2026-11-12 12:28:40 +08:00
|
|
|
{
|
|
|
|
|
NotifySaveFailure("notice.holdFull");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
target.collected = true;
|
|
|
|
|
target.RefreshLabel();
|
|
|
|
|
Notify("notice.recovered", GameLocalization.Message("item." + target.itemId), target.amount);
|
|
|
|
|
GameAudio.Cue(520, .12f);
|
|
|
|
|
if (target.offersPart)
|
|
|
|
|
{
|
|
|
|
|
SetMenu(true);
|
2026-11-12 18:02:26 +08:00
|
|
|
Hud.ShowPart(target.partSlot, index);
|
2026-11-12 12:28:40 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void Install(int slot, int index)
|
|
|
|
|
{
|
2026-11-12 18:02:26 +08:00
|
|
|
var item = Run.cargo.FindLast(i => i.itemId == InventoryGrid.EquipmentId(slot, index));
|
|
|
|
|
if (item == null || !InstallItem(item, Hold.Cargo)) return;
|
2026-11-12 12:28:40 +08:00
|
|
|
CloseMenu();
|
2026-11-12 18:02:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public bool InstallItem(CargoStack item, Hold from)
|
|
|
|
|
{
|
|
|
|
|
if (!Store.InstallItem(item.uid, from, parts => Fits(Run.chassis, parts)))
|
|
|
|
|
{
|
|
|
|
|
NotifySaveFailure("notice.installFailed");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
SelectedCargo.Remove(item.uid);
|
|
|
|
|
Pilot.ApplyLoadout();
|
|
|
|
|
Notify("notice.refit", GameLocalization.Message("equipment." + item.itemId + ".name"));
|
|
|
|
|
return true;
|
2026-11-12 12:28:40 +08:00
|
|
|
}
|
|
|
|
|
public void CompleteObjective()
|
|
|
|
|
{
|
|
|
|
|
if (Run.objectiveDone)
|
|
|
|
|
return;
|
|
|
|
|
Store.Commit(s => { s.run.objectiveDone = true; return true; });
|
|
|
|
|
Notify("notice.routeOpen");
|
|
|
|
|
GameAudio.Cue(850, .2f);
|
|
|
|
|
}
|
|
|
|
|
public void CompleteTerminal()
|
|
|
|
|
{
|
|
|
|
|
if (!Store.CompleteRoute())
|
|
|
|
|
return;
|
|
|
|
|
Notify("notice.complete");
|
|
|
|
|
GameAudio.Cue(1100, .4f);
|
|
|
|
|
}
|
|
|
|
|
public void OpenRoutes()
|
|
|
|
|
{
|
|
|
|
|
if (!Run.objectiveDone)
|
|
|
|
|
{
|
|
|
|
|
Notify("notice.objectiveFirst");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (Trial)
|
|
|
|
|
{
|
|
|
|
|
Notify("notice.rangeComplete");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (Run.stage >= 4)
|
|
|
|
|
{
|
|
|
|
|
Notify("notice.extract");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
SetMenu(true);
|
|
|
|
|
Hud.ShowRoutes();
|
|
|
|
|
}
|
|
|
|
|
public void NextZone(int option)
|
|
|
|
|
{
|
|
|
|
|
SnapshotVitals();
|
|
|
|
|
bool ok = Store.Commit(s =>
|
|
|
|
|
{
|
|
|
|
|
if (s.run.stage == 1)
|
|
|
|
|
s.run.branch = option;
|
|
|
|
|
s.run.stage++;
|
|
|
|
|
s.run.biome = option;
|
|
|
|
|
s.run.objectiveDone = false;
|
|
|
|
|
s.run.upgrades++;
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
if (ok)
|
|
|
|
|
EnterField();
|
|
|
|
|
else
|
|
|
|
|
NotifySaveFailure();
|
|
|
|
|
}
|
|
|
|
|
public void Unlock(string id)
|
|
|
|
|
{
|
|
|
|
|
bool ok = Store.Commit(s =>
|
|
|
|
|
{
|
|
|
|
|
if (!s.blueprints.Contains(id) || s.unlocked.Contains(id) || s.alloy < 2 || s.cells < 1)
|
|
|
|
|
return false;
|
|
|
|
|
s.alloy -= 2;
|
|
|
|
|
s.cells--;
|
|
|
|
|
s.unlocked.Add(id);
|
|
|
|
|
return true;
|
|
|
|
|
});
|
|
|
|
|
Notify(ok ? "notice.researched" : "notice.researchCost");
|
|
|
|
|
Hud.ShowHangar();
|
|
|
|
|
}
|
|
|
|
|
public void EndSortie(bool destroyed)
|
|
|
|
|
{
|
|
|
|
|
if (ending)
|
|
|
|
|
return;
|
|
|
|
|
SnapshotVitals();
|
|
|
|
|
bool complete = Run.routeCompleted;
|
2026-11-12 18:02:26 +08:00
|
|
|
int lost = Run.cargo.Count + Run.installed.Count;
|
|
|
|
|
int protectedCount = Run.safeCase.FindAll(i => !i.borrowed).Count;
|
2026-11-12 12:28:40 +08:00
|
|
|
if (!Store.Finish(destroyed))
|
|
|
|
|
{
|
|
|
|
|
NotifySaveFailure();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ending = true;
|
2026-11-12 18:02:26 +08:00
|
|
|
reportMessage = GameLocalization.Message(Trial ? "report.range" : destroyed ? "report.destroyed" : complete ? "report.complete" : "report.extracted", lost, protectedCount);
|
2026-11-12 12:28:40 +08:00
|
|
|
InField = false;
|
2026-11-12 18:02:26 +08:00
|
|
|
Paused = false;
|
|
|
|
|
Time.timeScale = 1;
|
|
|
|
|
Array.Clear(SelectedInstances, 0, SelectedInstances.Length);
|
2026-11-12 12:28:40 +08:00
|
|
|
Trial = false;
|
|
|
|
|
Store = mainStore;
|
|
|
|
|
Pilot = null;
|
|
|
|
|
World.BuildHangar();
|
|
|
|
|
SetMenu(true);
|
|
|
|
|
Hud.ShowHangar();
|
|
|
|
|
}
|
|
|
|
|
void OnApplicationFocus(bool focus)
|
|
|
|
|
{
|
2026-11-12 18:01:54 +08:00
|
|
|
if (!focus && Hud && Hud.SettingsOpen)
|
|
|
|
|
{
|
|
|
|
|
Hud.CancelSettingsInput();
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-11-12 12:28:40 +08:00
|
|
|
if (!focus && InField && Hud)
|
|
|
|
|
{
|
|
|
|
|
Paused = true;
|
|
|
|
|
Time.timeScale = 0;
|
|
|
|
|
SetMenu(true);
|
|
|
|
|
Hud.ShowPause();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void OnApplicationQuit()
|
|
|
|
|
{
|
|
|
|
|
if (InField && Pilot)
|
|
|
|
|
{
|
|
|
|
|
SnapshotVitals();
|
|
|
|
|
Store.Commit(s => true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void OnDestroy()
|
|
|
|
|
{
|
2026-11-12 18:01:54 +08:00
|
|
|
Settings?.Dispose();
|
2026-11-12 12:28:40 +08:00
|
|
|
if (Input)
|
|
|
|
|
Destroy(Input);
|
|
|
|
|
Time.timeScale = 1;
|
|
|
|
|
if (Active == this)
|
|
|
|
|
Active = null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|