2026-11-12 12:28:40 +08:00
|
|
|
using System;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
using UnityEngine.InputSystem;
|
|
|
|
|
using UnityEngine.UIElements;
|
|
|
|
|
|
|
|
|
|
namespace Ironspore
|
|
|
|
|
{
|
|
|
|
|
public sealed class GameHud : MonoBehaviour
|
|
|
|
|
{
|
|
|
|
|
GameSession game;
|
|
|
|
|
VisualElement root;
|
|
|
|
|
Label mission, prompt, status, notice, telemetry;
|
|
|
|
|
ProgressBar armor, energy, cargo;
|
|
|
|
|
VisualElement cross;
|
|
|
|
|
enum View
|
|
|
|
|
{
|
|
|
|
|
Hangar, Field, Cargo, Part, Routes, Pause
|
|
|
|
|
}
|
|
|
|
|
View view;
|
|
|
|
|
int partSlot, partIndex;
|
|
|
|
|
PanelSettings panelSettings;
|
|
|
|
|
VisualElement languageControl, languageMenu, languageDismiss;
|
|
|
|
|
Button languageButton;
|
|
|
|
|
int lastLanguageActivationFrame = -1;
|
|
|
|
|
int lastLanguageNavigationFrame = -1;
|
|
|
|
|
Label hangarNotice;
|
|
|
|
|
static string L(string key, params object[] args) => GameLocalization.Text(key, args);
|
|
|
|
|
public void Initialize(GameSession session)
|
|
|
|
|
{
|
|
|
|
|
game = session;
|
|
|
|
|
var document = gameObject.AddComponent<UIDocument>();
|
|
|
|
|
var settings = panelSettings = Instantiate(game.uiPanel);
|
|
|
|
|
settings.scaleMode = PanelScaleMode.ScaleWithScreenSize;
|
|
|
|
|
settings.referenceResolution = new Vector2Int(1920, 1080);
|
|
|
|
|
document.panelSettings = settings;
|
|
|
|
|
root = document.rootVisualElement;
|
|
|
|
|
root.styleSheets.Add(game.uiStyle);
|
|
|
|
|
root.pickingMode = PickingMode.Ignore;
|
|
|
|
|
root.style.unityFontDefinition = FontDefinition.FromSDFFont(game.localization.uiFont);
|
|
|
|
|
root.RegisterCallback<KeyDownEvent>(HandleLanguageKey, TrickleDown.TrickleDown);
|
|
|
|
|
GameLocalization.Changed += RefreshLocale;
|
|
|
|
|
}
|
|
|
|
|
void HandleLanguageKey(KeyDownEvent evt)
|
|
|
|
|
{
|
|
|
|
|
if (view != View.Hangar)
|
|
|
|
|
return;
|
|
|
|
|
if (languageMenu != null && evt.keyCode == KeyCode.Escape)
|
|
|
|
|
{
|
|
|
|
|
CloseLanguageMenu();
|
|
|
|
|
evt.StopImmediatePropagation();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (languageMenu != null && evt.keyCode == KeyCode.Tab)
|
|
|
|
|
{
|
|
|
|
|
MoveLanguageFocus(evt.shiftKey);
|
|
|
|
|
evt.StopImmediatePropagation();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (evt.keyCode != KeyCode.Return && evt.keyCode != KeyCode.KeypadEnter && evt.keyCode != KeyCode.Space)
|
|
|
|
|
return;
|
|
|
|
|
if (ActivateFocusedLanguage())
|
|
|
|
|
evt.StopImmediatePropagation();
|
|
|
|
|
}
|
|
|
|
|
void MoveLanguageFocus(bool reverse)
|
|
|
|
|
{
|
|
|
|
|
if (lastLanguageNavigationFrame == Time.frameCount)
|
|
|
|
|
return;
|
|
|
|
|
lastLanguageNavigationFrame = Time.frameCount;
|
|
|
|
|
var options = languageMenu.Query<Button>(className: "language-option").ToList();
|
|
|
|
|
int current = options.IndexOf(root.focusController.focusedElement as Button);
|
|
|
|
|
int next = (current + (reverse ? -1 : 1) + options.Count) % options.Count;
|
|
|
|
|
options[next].Focus();
|
|
|
|
|
}
|
|
|
|
|
bool ActivateFocusedLanguage()
|
|
|
|
|
{
|
|
|
|
|
var focused = root.focusController.focusedElement as Button;
|
|
|
|
|
if (focused == languageButton)
|
|
|
|
|
ToggleLanguageMenu(languageControl.parent);
|
|
|
|
|
else if (languageMenu != null && focused != null && focused.ClassListContains("language-option"))
|
|
|
|
|
ChooseLocale((string)focused.userData);
|
|
|
|
|
else
|
|
|
|
|
return false;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
VisualElement Element(VisualElement parent, string css)
|
|
|
|
|
{
|
|
|
|
|
var e = new VisualElement();
|
|
|
|
|
e.AddToClassList(css);
|
|
|
|
|
parent.Add(e);
|
|
|
|
|
return e;
|
|
|
|
|
}
|
|
|
|
|
Label Text(VisualElement parent, string text, string css = "body")
|
|
|
|
|
{
|
|
|
|
|
var l = new Label(text);
|
|
|
|
|
l.AddToClassList(css);
|
|
|
|
|
parent.Add(l);
|
|
|
|
|
return l;
|
|
|
|
|
}
|
|
|
|
|
Button Button(VisualElement parent, string text, Action action, string css = "button")
|
|
|
|
|
{
|
|
|
|
|
var b = new Button(action) { text = text };
|
|
|
|
|
foreach (string className in css.Split(' '))
|
|
|
|
|
b.AddToClassList(className);
|
|
|
|
|
parent.Add(b);
|
|
|
|
|
return b;
|
|
|
|
|
}
|
|
|
|
|
void Clear()
|
|
|
|
|
{
|
|
|
|
|
root.Clear();
|
|
|
|
|
mission = prompt = status = notice = telemetry = null;
|
|
|
|
|
armor = energy = cargo = null;
|
|
|
|
|
cross = null;
|
|
|
|
|
hangarNotice = null;
|
|
|
|
|
languageControl = languageMenu = languageDismiss = null;
|
|
|
|
|
languageButton = null;
|
|
|
|
|
}
|
|
|
|
|
void RefreshLocale()
|
|
|
|
|
{
|
|
|
|
|
switch (view)
|
|
|
|
|
{
|
|
|
|
|
case View.Hangar:
|
|
|
|
|
ShowHangar();
|
|
|
|
|
languageButton?.Focus();
|
|
|
|
|
break;
|
|
|
|
|
case View.Field:
|
|
|
|
|
ShowField();
|
|
|
|
|
break;
|
|
|
|
|
case View.Cargo:
|
|
|
|
|
ShowCargo();
|
|
|
|
|
break;
|
|
|
|
|
case View.Part:
|
|
|
|
|
ShowPart(partSlot, partIndex);
|
|
|
|
|
break;
|
|
|
|
|
case View.Routes:
|
|
|
|
|
ShowRoutes();
|
|
|
|
|
break;
|
|
|
|
|
case View.Pause:
|
|
|
|
|
ShowPause();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void AddLanguageControl(VisualElement page)
|
|
|
|
|
{
|
|
|
|
|
languageControl = Element(page, "language-control");
|
|
|
|
|
var locale = Array.Find(GameLocalization.Catalog.locales, x => x.code == GameLocalization.CurrentCode);
|
|
|
|
|
languageButton = Button(languageControl, L("ui.home.language", locale.nativeName), () => ToggleLanguageMenu(page), "language-button");
|
|
|
|
|
languageButton.name = "language-toggle";
|
|
|
|
|
languageButton.tooltip = L("ui.home.languageHelp");
|
|
|
|
|
}
|
|
|
|
|
void ToggleLanguageMenu(VisualElement page)
|
|
|
|
|
{
|
|
|
|
|
if (lastLanguageActivationFrame == Time.frameCount)
|
|
|
|
|
return;
|
|
|
|
|
lastLanguageActivationFrame = Time.frameCount;
|
|
|
|
|
if (languageMenu != null)
|
|
|
|
|
CloseLanguageMenu();
|
|
|
|
|
else
|
|
|
|
|
OpenLanguageMenu(page);
|
|
|
|
|
}
|
|
|
|
|
void ChooseLocale(string code)
|
|
|
|
|
{
|
|
|
|
|
if (lastLanguageActivationFrame == Time.frameCount)
|
|
|
|
|
return;
|
|
|
|
|
lastLanguageActivationFrame = Time.frameCount;
|
|
|
|
|
CloseLanguageMenu();
|
|
|
|
|
GameLocalization.SelectLocale(code);
|
|
|
|
|
}
|
|
|
|
|
void OpenLanguageMenu(VisualElement page)
|
|
|
|
|
{
|
|
|
|
|
languageDismiss = Element(page, "language-dismiss");
|
|
|
|
|
languageDismiss.RegisterCallback<PointerDownEvent>(evt => { CloseLanguageMenu(); evt.StopPropagation(); });
|
|
|
|
|
languageControl.BringToFront();
|
|
|
|
|
languageMenu = Element(languageControl, "language-menu");
|
|
|
|
|
languageMenu.name = "language-menu";
|
|
|
|
|
Text(languageMenu, L("ui.home.languageHelp"), "language-heading");
|
|
|
|
|
Button selected = null;
|
|
|
|
|
foreach (var locale in GameLocalization.Catalog.locales)
|
|
|
|
|
{
|
|
|
|
|
string code = locale.code;
|
|
|
|
|
bool current = code == GameLocalization.CurrentCode;
|
|
|
|
|
var option = Button(languageMenu, current ? L("ui.language.current", locale.nativeName) : locale.nativeName, () => ChooseLocale(code), current ? "language-option selected" : "language-option");
|
|
|
|
|
option.name = "locale-" + code;
|
|
|
|
|
option.userData = code;
|
|
|
|
|
if (current)
|
|
|
|
|
selected = option;
|
|
|
|
|
}
|
|
|
|
|
selected?.Focus();
|
|
|
|
|
}
|
|
|
|
|
public void CloseLanguageMenu()
|
|
|
|
|
{
|
|
|
|
|
languageMenu?.RemoveFromHierarchy();
|
|
|
|
|
languageDismiss?.RemoveFromHierarchy();
|
|
|
|
|
languageMenu = languageDismiss = null;
|
|
|
|
|
languageButton?.Focus();
|
|
|
|
|
}
|
|
|
|
|
public void RefreshHangarNotice()
|
|
|
|
|
{
|
|
|
|
|
if (hangarNotice != null)
|
|
|
|
|
{
|
|
|
|
|
hangarNotice.text = game.Notice;
|
|
|
|
|
hangarNotice.style.display = string.IsNullOrEmpty(game.Notice) ? DisplayStyle.None : DisplayStyle.Flex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
public void ShowHangar()
|
|
|
|
|
{
|
|
|
|
|
Clear();
|
|
|
|
|
view = View.Hangar;
|
|
|
|
|
var page = Element(root, "hangar");
|
|
|
|
|
var scroll = new ScrollView(ScrollViewMode.Vertical) { horizontalScrollerVisibility = ScrollerVisibility.Hidden };
|
|
|
|
|
scroll.AddToClassList("hangar-scroll");
|
|
|
|
|
page.Add(scroll);
|
|
|
|
|
var content = Element(scroll, "hangar-content");
|
|
|
|
|
Text(content, "IRONSPORE", "title");
|
|
|
|
|
Text(content, L("ui.home.subtitle"), "subtitle");
|
|
|
|
|
Text(content, game.Report, "body");
|
|
|
|
|
var frames = Element(content, "row");
|
|
|
|
|
for (int i = 0; i < game.chassis.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
int choice = i;
|
|
|
|
|
var frame = game.chassis[i];
|
|
|
|
|
Button(frames, frame.LocalizedName + "\n" + frame.LocalizedDescription, () => { game.SelectedChassis = choice; ShowHangar(); }, i == game.SelectedChassis ? "frame selected" : "frame");
|
|
|
|
|
}
|
|
|
|
|
Text(content, L("ui.home.loadout"), "section");
|
|
|
|
|
for (int slot = 0; slot < 4; slot++)
|
|
|
|
|
{
|
|
|
|
|
int s = slot;
|
|
|
|
|
var p = game.Part(s, game.InitialEquipment[s]);
|
|
|
|
|
Button(content, L("ui.home.part", L("ui.slot." + s), p.LocalizedName, p.mass, p.power), () => { game.InitialEquipment[s] = (game.InitialEquipment[s] + 1) % game.PartCount(s); ShowHangar(); }, "loadout");
|
|
|
|
|
}
|
|
|
|
|
float mass = 0, power = 0;
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
var p = game.Part(i, game.InitialEquipment[i]);
|
|
|
|
|
mass += p.mass;
|
|
|
|
|
power += p.power;
|
|
|
|
|
}
|
|
|
|
|
var selected = game.chassis[game.SelectedChassis];
|
|
|
|
|
Text(content, L("ui.home.budget", mass, selected.massCapacity, power, selected.powerCapacity), game.Fits(game.SelectedChassis, game.InitialEquipment) ? "budget" : "warning");
|
|
|
|
|
var controls = Element(content, "row");
|
|
|
|
|
var launch = Button(controls, L("ui.home.deploy"), game.BeginSortie, "primary");
|
|
|
|
|
launch.SetEnabled(game.Fits(game.SelectedChassis, game.InitialEquipment) && game.StartingPartsUnlocked() && !game.Store.Data.run.active);
|
|
|
|
|
if (!game.StartingPartsUnlocked())
|
|
|
|
|
Text(content, L("ui.home.locked"), "warning");
|
|
|
|
|
Button(controls, L("ui.home.range"), game.StartTrial);
|
|
|
|
|
if (game.Store.Data.run.active)
|
|
|
|
|
Button(controls, L("ui.home.resume"), game.Resume, "primary");
|
|
|
|
|
Text(content, L("ui.home.moveHint"), "hint");
|
|
|
|
|
Text(content, L("ui.home.fireHint"), "hint");
|
|
|
|
|
var save = game.Store.Data;
|
|
|
|
|
Text(content, L("ui.home.inventory"), "section");
|
|
|
|
|
Text(content, L("ui.home.stock", save.alloy, save.cells, save.blueprints.Count, save.extractions, save.completed), "budget");
|
|
|
|
|
foreach (string blueprint in save.blueprints)
|
|
|
|
|
{
|
|
|
|
|
string id = blueprint;
|
|
|
|
|
bool unlocked = save.unlocked.Contains(id);
|
|
|
|
|
var b = Button(content, L(unlocked ? "ui.home.researched" : "ui.home.research", GameLocalization.ItemName(id)), () => game.Unlock(id), "loadout");
|
|
|
|
|
b.SetEnabled(!unlocked);
|
|
|
|
|
}
|
|
|
|
|
hangarNotice = Text(content, game.Notice, "warning");
|
|
|
|
|
RefreshHangarNotice();
|
|
|
|
|
Button(content, L("ui.home.quit"), () => Application.Quit(), "quiet");
|
|
|
|
|
AddLanguageControl(page);
|
|
|
|
|
}
|
|
|
|
|
public void ShowField()
|
|
|
|
|
{
|
|
|
|
|
Clear();
|
|
|
|
|
view = View.Field;
|
|
|
|
|
var field = Element(root, "field");
|
|
|
|
|
field.pickingMode = PickingMode.Ignore;
|
|
|
|
|
var top = Element(field, "topbar");
|
|
|
|
|
Text(top, "IRONSPORE", "brand");
|
|
|
|
|
status = Text(top, "", "status");
|
|
|
|
|
var goal = Element(field, "mission");
|
|
|
|
|
Text(goal, L("ui.hud.operation"), "section");
|
|
|
|
|
mission = Text(goal, "", "mission-text");
|
|
|
|
|
telemetry = Text(field, "", "telemetry");
|
|
|
|
|
cross = Element(field, "crosshair");
|
|
|
|
|
cross.style.position = Position.Absolute;
|
|
|
|
|
cross.style.left = Length.Percent(50);
|
|
|
|
|
cross.style.top = Length.Percent(50);
|
|
|
|
|
cross.style.translate = new Translate(-20, -20);
|
|
|
|
|
cross.style.width = 40;
|
|
|
|
|
cross.style.height = 40;
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
var arm = Element(cross, "reticle-arm");
|
|
|
|
|
arm.style.position = Position.Absolute;
|
|
|
|
|
arm.style.backgroundColor = new Color(.64f, 1, .9f);
|
|
|
|
|
arm.style.left = i == 0 ? 0 : i == 1 ? 27 : 19;
|
|
|
|
|
arm.style.top = i == 2 ? 0 : i == 3 ? 27 : 19;
|
|
|
|
|
arm.style.width = i < 2 ? 13 : 2;
|
|
|
|
|
arm.style.height = i < 2 ? 2 : 13;
|
|
|
|
|
}
|
|
|
|
|
prompt = Text(field, "", "interact");
|
|
|
|
|
notice = Text(field, "", "notice");
|
|
|
|
|
var bottom = Element(field, "bottom");
|
|
|
|
|
armor = new ProgressBar { title = L("ui.hud.armor", 0), lowValue = 0, highValue = 100 };
|
|
|
|
|
armor.AddToClassList("armor");
|
|
|
|
|
bottom.Add(armor);
|
|
|
|
|
energy = new ProgressBar { title = L("ui.hud.energy", 0), lowValue = 0, highValue = 100 };
|
|
|
|
|
energy.AddToClassList("energy");
|
|
|
|
|
bottom.Add(energy);
|
|
|
|
|
cargo = new ProgressBar { title = L("ui.hud.podReady"), lowValue = 0, highValue = 3 };
|
|
|
|
|
cargo.AddToClassList("cargo-progress");
|
|
|
|
|
bottom.Add(cargo);
|
|
|
|
|
Text(bottom, L("ui.hud.hint"), "hint");
|
|
|
|
|
}
|
|
|
|
|
VisualElement Overlay(string heading, string body)
|
|
|
|
|
{
|
|
|
|
|
ShowField();
|
|
|
|
|
var shade = Element(root, "overlay");
|
|
|
|
|
var panel = Element(shade, "panel");
|
|
|
|
|
Text(panel, heading, "heading");
|
|
|
|
|
Text(panel, body, "body");
|
|
|
|
|
return panel;
|
|
|
|
|
}
|
|
|
|
|
public void ShowCargo()
|
|
|
|
|
{
|
|
|
|
|
var panel = Overlay(L("ui.cargo.title"), L(game.Run.podUsed ? "ui.cargo.used" : "ui.cargo.help"));
|
|
|
|
|
view = View.Cargo;
|
|
|
|
|
foreach (var stack in game.Run.cargo)
|
|
|
|
|
{
|
|
|
|
|
string uid = stack.uid;
|
|
|
|
|
var b = Button(panel, L("ui.cargo.stack", game.SelectedCargo.Contains(uid) ? L("ui.cargo.selected") : "[ ]", stack.Name, stack.count), () => game.ToggleCargo(uid), "loadout");
|
|
|
|
|
b.SetEnabled(!game.Run.podUsed);
|
|
|
|
|
}
|
|
|
|
|
Text(panel, L("ui.cargo.capacity", game.Run.cargo.Count, game.SelectedCargo.Count), "budget");
|
|
|
|
|
Button(panel, L("ui.return"), game.CloseMenu, "primary");
|
|
|
|
|
}
|
|
|
|
|
public void ShowPart(int slot, int index)
|
|
|
|
|
{
|
|
|
|
|
index = Mathf.Clamp(index, 0, game.PartCount(slot) - 1);
|
|
|
|
|
int partIndex = index;
|
|
|
|
|
this.partSlot = slot;
|
|
|
|
|
this.partIndex = index;
|
|
|
|
|
var old = game.Part(slot, game.Run.equipment[slot]);
|
|
|
|
|
var next = game.Part(slot, index);
|
|
|
|
|
var panel = Overlay(L("ui.refit.title"), L("ui.refit.help"));
|
|
|
|
|
view = View.Part;
|
|
|
|
|
Text(panel, L("ui.refit.equipped", old.LocalizedName, old.mass, old.power), "body");
|
|
|
|
|
Text(panel, L("ui.refit.recovered", next.LocalizedName, next.mass, next.power), "budget");
|
|
|
|
|
Button(panel, L("ui.refit.install"), () => game.Install(slot, partIndex), "primary");
|
|
|
|
|
Button(panel, L("ui.refit.keep"), game.CloseMenu);
|
|
|
|
|
}
|
|
|
|
|
public void ShowRoutes()
|
|
|
|
|
{
|
|
|
|
|
bool split = game.Run.stage == 1;
|
|
|
|
|
var panel = Overlay(L(split ? "ui.routes.split" : "ui.routes.title"), L(split ? "ui.routes.splitHelp" : "ui.routes.help"));
|
|
|
|
|
view = View.Routes;
|
|
|
|
|
Button(panel, L(split ? "ui.routes.boss" : "ui.routes.freight"), () => game.NextZone(0), "route");
|
|
|
|
|
Button(panel, L(split ? "ui.routes.escort" : "ui.routes.power"), () => game.NextZone(1), "route");
|
|
|
|
|
Button(panel, L("ui.routes.stay"), game.CloseMenu);
|
|
|
|
|
}
|
|
|
|
|
public void ShowPause()
|
|
|
|
|
{
|
|
|
|
|
var panel = Overlay(L("ui.pause.title"), L("ui.pause.help"));
|
|
|
|
|
view = View.Pause;
|
|
|
|
|
Button(panel, L("ui.pause.resume"), game.CloseMenu, "primary");
|
|
|
|
|
if (game.Trial)
|
|
|
|
|
Button(panel, L("ui.pause.range"), () => { game.CloseMenu(); game.EndSortie(true); });
|
|
|
|
|
Button(panel, L("ui.pause.quit"), () => Application.Quit());
|
|
|
|
|
}
|
|
|
|
|
void Update()
|
|
|
|
|
{
|
|
|
|
|
if (view == View.Hangar)
|
|
|
|
|
{
|
|
|
|
|
RefreshHangarNotice();
|
|
|
|
|
if (languageMenu != null && game.Action("Pause").WasPressedThisFrame())
|
|
|
|
|
CloseLanguageMenu();
|
|
|
|
|
// The project uses Input System without a uGUI EventSystem. Handle submit
|
|
|
|
|
// explicitly as well as UI Toolkit events; frame guards prevent double input.
|
|
|
|
|
var keys = Keyboard.current;
|
|
|
|
|
if (keys != null)
|
|
|
|
|
{
|
|
|
|
|
if (languageMenu != null && keys.tabKey.wasPressedThisFrame)
|
|
|
|
|
MoveLanguageFocus(keys.shiftKey.isPressed);
|
|
|
|
|
if (keys.enterKey.wasPressedThisFrame || keys.numpadEnterKey.wasPressedThisFrame || keys.spaceKey.wasPressedThisFrame)
|
|
|
|
|
ActivateFocusedLanguage();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!game.InField || !game.Pilot)
|
|
|
|
|
return;
|
|
|
|
|
var run = game.Run;
|
|
|
|
|
var p = game.Pilot;
|
|
|
|
|
if (status != null)
|
|
|
|
|
status.text = L("ui.hud.status", game.Trial ? L("ui.home.range") : L("ui.hud.zone", run.stage + 1), TimeSpan.FromSeconds(run.elapsed).ToString(@"mm\:ss"));
|
|
|
|
|
if (mission != null)
|
2026-11-12 18:03:04 +08:00
|
|
|
mission.text = game.World.Course ? game.World.Course.Instruction :
|
|
|
|
|
L(run.routeCompleted ? "ui.hud.complete" : run.stage == 4 && !game.Trial ? run.branch == 0 ? "ui.hud.boss" : "ui.hud.escort" : run.objectiveDone ? "ui.hud.routeOpen" : "ui.hud.objective");
|
2026-11-12 12:28:40 +08:00
|
|
|
if (armor != null)
|
|
|
|
|
{
|
|
|
|
|
armor.value = p.Health / game.chassis[run.chassis].armor * 100;
|
|
|
|
|
armor.title = L("ui.hud.armor", Mathf.CeilToInt(p.Health));
|
|
|
|
|
}
|
|
|
|
|
if (energy != null)
|
|
|
|
|
{
|
|
|
|
|
energy.value = p.Energy;
|
|
|
|
|
energy.title = p.Guard > 0 ? L("ui.hud.shield") : L("ui.hud.energy", Mathf.CeilToInt(p.Energy));
|
|
|
|
|
}
|
|
|
|
|
if (cargo != null)
|
|
|
|
|
{
|
|
|
|
|
cargo.value = game.CargoProgress;
|
|
|
|
|
cargo.title = L(run.podUsed ? "ui.hud.podUsed" : game.CargoProgress > 0 ? "ui.hud.podPreparing" : "ui.hud.podReady");
|
|
|
|
|
}
|
|
|
|
|
if (prompt != null)
|
|
|
|
|
{
|
|
|
|
|
prompt.text = game.World.Focused ? game.World.Focused.Prompt : "";
|
|
|
|
|
prompt.style.display = game.World.Focused ? DisplayStyle.Flex : DisplayStyle.None;
|
|
|
|
|
}
|
|
|
|
|
if (notice != null)
|
|
|
|
|
notice.text = game.Notice;
|
|
|
|
|
if (telemetry != null)
|
|
|
|
|
telemetry.text = L("ui.hud.telemetry", game.chassis[run.chassis].LocalizedName, L(p.FirstPerson ? "ui.hud.cockpit" : "ui.hud.shoulder"), game.Part(0, run.equipment[0]).LocalizedName, run.cargo.Count, game.World.ExtractionRemaining >= 0 ? game.World.TransportReady ? L("ui.hud.transportReady") : L("ui.hud.transportEta", Mathf.CeilToInt(game.World.ExtractionRemaining)) : L("ui.hud.extractionAvailable"));
|
|
|
|
|
if (cross != null)
|
|
|
|
|
cross.style.opacity = p.RecentHit ? 1 : .65f;
|
|
|
|
|
}
|
|
|
|
|
void OnDestroy()
|
|
|
|
|
{
|
|
|
|
|
GameLocalization.Changed -= RefreshLocale;
|
|
|
|
|
if (panelSettings)
|
|
|
|
|
Destroy(panelSettings);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|