From 8b6c6235c2310a0b96a58e32165e34a91aaf0af8 Mon Sep 17 00:00:00 2001 From: fretuks Date: Mon, 6 Jul 2026 13:41:15 +0200 Subject: [PATCH] Add actual carts and shit Upgrade UI to Level 6 Balls --- Assets/Data/Cards/CardDatabase.asset | 21 + Assets/Data/Cards/Ubuntu/AskUbuntu.asset | 26 + .../Data/Cards/Ubuntu/DoReleaseUpgrade.asset | 26 + Assets/Data/Cards/Ubuntu/SnapInstall.asset | 26 + Assets/Data/Cards/Ubuntu/SudoAptInstall.asset | 26 + Assets/Data/Cards/Ubuntu/UbuntuProTrial.asset | 26 + .../Cards/Ubuntu/UnattendedUpgrades.asset | 26 + Assets/Scripts/Meta/PlayerCollection.cs | 13 + Assets/Scripts/Meta/SaveService.cs | 16 +- .../Scripts/UI/CollectionScreenController.cs | 149 +++++- Assets/Scripts/UI/FeaturedUnitPanel.cs | 30 +- Assets/Scripts/UI/MainMenuController.cs | 474 +++++++++++++++--- Assets/UI/CollectionScreen.uxml | 28 +- Assets/UI/GachaScreen.uxml | 18 +- Assets/UI/MainMenu.uss | 199 ++++++-- Assets/UI/MainMenu.uxml | 19 +- Assets/UI/SettingsScreen.uxml | 20 +- 17 files changed, 978 insertions(+), 165 deletions(-) create mode 100644 Assets/Data/Cards/CardDatabase.asset create mode 100644 Assets/Data/Cards/Ubuntu/AskUbuntu.asset create mode 100644 Assets/Data/Cards/Ubuntu/DoReleaseUpgrade.asset create mode 100644 Assets/Data/Cards/Ubuntu/SnapInstall.asset create mode 100644 Assets/Data/Cards/Ubuntu/SudoAptInstall.asset create mode 100644 Assets/Data/Cards/Ubuntu/UbuntuProTrial.asset create mode 100644 Assets/Data/Cards/Ubuntu/UnattendedUpgrades.asset diff --git a/Assets/Data/Cards/CardDatabase.asset b/Assets/Data/Cards/CardDatabase.asset new file mode 100644 index 0000000..14a5f4c --- /dev/null +++ b/Assets/Data/Cards/CardDatabase.asset @@ -0,0 +1,21 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 85f230365a0e4f28a4bfbdb0a15115a8, type: 3} + m_Name: CardDatabase + m_EditorClassIdentifier: + allCards: + - {fileID: 11400000, guid: 0a4f1d1d84564f3cad58b8863e941201, type: 2} + - {fileID: 11400000, guid: 14c5d40f866a4cb6b0a6316e01f42891, type: 2} + - {fileID: 11400000, guid: 2a0f50d541f046fc99c8fb6deef4f1aa, type: 2} + - {fileID: 11400000, guid: 3d57857f3f30419c8be4c44914c5abbe, type: 2} + - {fileID: 11400000, guid: 4cae271a0f4146c59aab74e4c9d6d0f8, type: 2} + - {fileID: 11400000, guid: 5fef058a72b54b4aa2b2dd8f4d08bfe5, type: 2} diff --git a/Assets/Data/Cards/Ubuntu/AskUbuntu.asset b/Assets/Data/Cards/Ubuntu/AskUbuntu.asset new file mode 100644 index 0000000..5b1d630 --- /dev/null +++ b/Assets/Data/Cards/Ubuntu/AskUbuntu.asset @@ -0,0 +1,26 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3} + m_Name: AskUbuntu + m_EditorClassIdentifier: + id: ubuntu_ask_ubuntu + displayName: ask ubuntu + description: "queue: draw 2 cards." + language: 3 + rarity: 0 + cycleCost: 0 + resolutionTrack: 1 + distroExclusive: 1 + isToken: 0 + designNotes: pure draw on resolve. + upgradeTarget: {fileID: 0} + effects: [] diff --git a/Assets/Data/Cards/Ubuntu/DoReleaseUpgrade.asset b/Assets/Data/Cards/Ubuntu/DoReleaseUpgrade.asset new file mode 100644 index 0000000..c0f8d78 --- /dev/null +++ b/Assets/Data/Cards/Ubuntu/DoReleaseUpgrade.asset @@ -0,0 +1,26 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3} + m_Name: DoReleaseUpgrade + m_EditorClassIdentifier: + id: ubuntu_do_release_upgrade + displayName: do-release-upgrade + description: upgrade 1-3 random cards in your hand this combat. + language: 4 + rarity: 1 + cycleCost: 2 + resolutionTrack: 0 + distroExclusive: 1 + isToken: 0 + designNotes: count rolled on resolution (JS variance). + upgradeTarget: {fileID: 0} + effects: [] diff --git a/Assets/Data/Cards/Ubuntu/SnapInstall.asset b/Assets/Data/Cards/Ubuntu/SnapInstall.asset new file mode 100644 index 0000000..0657442 --- /dev/null +++ b/Assets/Data/Cards/Ubuntu/SnapInstall.asset @@ -0,0 +1,26 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3} + m_Name: SnapInstall + m_EditorClassIdentifier: + id: ubuntu_snap_install + displayName: snap install + description: deal 6-14 damage. shuffle an ubuntu pro trial into your draw pile. + language: 4 + rarity: 0 + cycleCost: 0 + resolutionTrack: 0 + distroExclusive: 1 + isToken: 0 + designNotes: "JS variance roll at resolution; junk-token insertion; references token by id ubuntu_pro_trial." + upgradeTarget: {fileID: 0} + effects: [] diff --git a/Assets/Data/Cards/Ubuntu/SudoAptInstall.asset b/Assets/Data/Cards/Ubuntu/SudoAptInstall.asset new file mode 100644 index 0000000..883dab3 --- /dev/null +++ b/Assets/Data/Cards/Ubuntu/SudoAptInstall.asset @@ -0,0 +1,26 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3} + m_Name: SudoAptInstall + m_EditorClassIdentifier: + id: ubuntu_apt_install + displayName: sudo apt install + description: "queue: add a random common python card to your hand. it costs 0 this combat." + language: 3 + rarity: 0 + cycleCost: 1 + resolutionTrack: 1 + distroExclusive: 1 + isToken: 0 + designNotes: on-resolve card generation from the common Python pool. + upgradeTarget: {fileID: 0} + effects: [] diff --git a/Assets/Data/Cards/Ubuntu/UbuntuProTrial.asset b/Assets/Data/Cards/Ubuntu/UbuntuProTrial.asset new file mode 100644 index 0000000..285c4f5 --- /dev/null +++ b/Assets/Data/Cards/Ubuntu/UbuntuProTrial.asset @@ -0,0 +1,26 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3} + m_Name: UbuntuProTrial + m_EditorClassIdentifier: + id: ubuntu_pro_trial + displayName: ubuntu pro trial + description: unplayable. exhausts at end of combat. + language: 3 + rarity: 0 + cycleCost: 0 + resolutionTrack: 0 + distroExclusive: 0 + isToken: 1 + designNotes: "junk token; unplayable flag TBD in combat model." + upgradeTarget: {fileID: 0} + effects: [] diff --git a/Assets/Data/Cards/Ubuntu/UnattendedUpgrades.asset b/Assets/Data/Cards/Ubuntu/UnattendedUpgrades.asset new file mode 100644 index 0000000..d15d2be --- /dev/null +++ b/Assets/Data/Cards/Ubuntu/UnattendedUpgrades.asset @@ -0,0 +1,26 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3} + m_Name: UnattendedUpgrades + m_EditorClassIdentifier: + id: ubuntu_unattended_upgrades + displayName: unattended-upgrades + description: gain 4 shield now and at the end of your next 2 turns. + language: 3 + rarity: 0 + cycleCost: 1 + resolutionTrack: 1 + distroExclusive: 1 + isToken: 0 + designNotes: immediate shield + 2-turn delayed shield ticks. + upgradeTarget: {fileID: 0} + effects: [] diff --git a/Assets/Scripts/Meta/PlayerCollection.cs b/Assets/Scripts/Meta/PlayerCollection.cs index 61dee38..a39c10d 100644 --- a/Assets/Scripts/Meta/PlayerCollection.cs +++ b/Assets/Scripts/Meta/PlayerCollection.cs @@ -10,10 +10,12 @@ namespace KernelPanic.Meta public sealed class PlayerCollection { private readonly List ownedUnits = new(); + private int featuredIndex; // TODO: Populate owned units from SaveService during bootstrap. // TODO: Add newly unlocked units from GachaService rewards when pulls exist. public IReadOnlyList OwnedUnits => ownedUnits; + public DistroDefinition FeaturedUnit => ownedUnits.Count == 0 ? null : ownedUnits[Math.Clamp(featuredIndex, 0, ownedUnits.Count - 1)]; public event Action Changed; @@ -26,7 +28,18 @@ namespace KernelPanic.Meta // Persistence is wired by the owner so this domain class stays IO-free. ownedUnits.Add(unit); + featuredIndex = Math.Clamp(featuredIndex, 0, ownedUnits.Count - 1); Changed?.Invoke(); } + + public void SelectNextFeatured() + { + if (ownedUnits.Count < 2) + { + return; + } + + featuredIndex = (featuredIndex + 1) % ownedUnits.Count; + } } } diff --git a/Assets/Scripts/Meta/SaveService.cs b/Assets/Scripts/Meta/SaveService.cs index c902df1..3aa4ae2 100644 --- a/Assets/Scripts/Meta/SaveService.cs +++ b/Assets/Scripts/Meta/SaveService.cs @@ -60,7 +60,7 @@ namespace KernelPanic.Meta public bool starterChosen; public List ownedUnitIds = new(); public List bannerPoolIds = new(); - public List cardLoadouts = new(); + public LastRunLoadoutSaveEntry lastRunLoadout = new(); public static SaveData CreateDefault() { @@ -71,24 +71,20 @@ namespace KernelPanic.Meta { ownedUnitIds ??= new List(); bannerPoolIds ??= new List(); - cardLoadouts ??= new List(); - for (int i = 0; i < cardLoadouts.Count; i++) - { - cardLoadouts[i] ??= new CardLoadoutSaveEntry(); - cardLoadouts[i].EnsureLists(); - } + lastRunLoadout ??= new LastRunLoadoutSaveEntry(); + lastRunLoadout.EnsureLists(); } } [Serializable] - public sealed class CardLoadoutSaveEntry + public sealed class LastRunLoadoutSaveEntry { public string distroId; - public List equippedCardIds = new(); + public List cardIds = new(); public void EnsureLists() { - equippedCardIds ??= new List(); + cardIds ??= new List(); } } } diff --git a/Assets/Scripts/UI/CollectionScreenController.cs b/Assets/Scripts/UI/CollectionScreenController.cs index f3b4214..bf849b5 100644 --- a/Assets/Scripts/UI/CollectionScreenController.cs +++ b/Assets/Scripts/UI/CollectionScreenController.cs @@ -19,6 +19,7 @@ namespace KernelPanic.UI private VisualElement detail; private FontAsset monospaceFont; private IReadOnlyList units = Array.Empty(); + private IReadOnlyList cards = Array.Empty(); private int selectedIndex; public void Bind(VisualElement root, FontAsset artFont) @@ -28,7 +29,7 @@ namespace KernelPanic.UI detail = root.Q("CollectionDetail"); } - public void Refresh(IReadOnlyList ownedUnits) + public void RefreshUnits(IReadOnlyList ownedUnits) { units = ownedUnits ?? Array.Empty(); if (list == null || detail == null) @@ -73,6 +74,55 @@ namespace KernelPanic.UI SelectUnit(selectedIndex); } + public void RefreshCards(DistroDefinition featuredUnit) + { + cards = BuildCardEntries(featuredUnit); + if (list == null || detail == null) + { + return; + } + + rows.Clear(); + list.Clear(); + + if (cards.Count == 0) + { + detail.Clear(); + detail.Add(new Label("no cards installed") { name = "CollectionEmptyTitle" }); + detail.Add(new Label("featured distro cards appear here") { name = "CollectionEmptyHint" }); + return; + } + + selectedIndex = Mathf.Clamp(selectedIndex, 0, cards.Count - 1); + for (int i = 0; i < cards.Count; i++) + { + int index = i; + CardEntry entry = cards[i]; + VisualElement row = new(); + row.AddToClassList("collection-row"); + row.RegisterCallback(_ => SelectCard(index)); + row.RegisterCallback(_ => SelectCard(index)); + + Label name = new(GetCardDisplayName(entry.Card)); + name.AddToClassList("collection-row-name"); + + Label meta = new($"{DistroPresentation.DisplayName(entry.Owner)} / {FormatCardMeta(entry.Card)}"); + meta.AddToClassList("collection-row-languages"); + + row.Add(name); + row.Add(meta); + list.Add(row); + rows.Add(row); + } + + SelectCard(selectedIndex); + } + + public void Refresh(IReadOnlyList ownedUnits) + { + RefreshUnits(ownedUnits); + } + private void SelectUnit(int index) { if (units.Count == 0) @@ -89,10 +139,35 @@ namespace KernelPanic.UI RenderDetail(units[selectedIndex]); } + private void SelectCard(int index) + { + if (cards.Count == 0) + { + return; + } + + selectedIndex = Mathf.Clamp(index, 0, cards.Count - 1); + for (int i = 0; i < rows.Count; i++) + { + rows[i].EnableInClassList("selected", i == selectedIndex); + } + + RenderCardDetail(cards[selectedIndex]); + } + private void RenderDetail(DistroDefinition unit) { detail.Clear(); + Label name = new(DistroPresentation.DisplayName(unit)); + name.AddToClassList("collection-detail-name"); + name.style.color = new StyleColor(unit.AccentColor); + detail.Add(name); + + Label description = new(string.IsNullOrWhiteSpace(unit.Description) ? "--" : unit.Description); + description.AddToClassList("collection-detail-description"); + detail.Add(description); + VisualElement readout = new(); readout.AddToClassList("collection-detail-readout"); @@ -107,11 +182,6 @@ namespace KernelPanic.UI VisualElement details = new(); details.AddToClassList("collection-detail-values"); - Label name = new(DistroPresentation.DisplayName(unit)); - name.AddToClassList("collection-detail-name"); - name.style.color = new StyleColor(unit.AccentColor); - details.Add(name); - details.Add(BuildDetailLine("lang", DistroPresentation.FormatLanguages(unit))); details.Add(BuildDetailLine("passive", string.IsNullOrWhiteSpace(unit.PassiveName) ? "--" : unit.PassiveName)); details.Add(BuildDetailLine("uptime", unit.BaseUptime.ToString())); @@ -120,10 +190,26 @@ namespace KernelPanic.UI readout.Add(details); detail.Add(readout); + } - Label description = new(string.IsNullOrWhiteSpace(unit.Description) ? "--" : unit.Description); + private void RenderCardDetail(CardEntry entry) + { + detail.Clear(); + + CardDefinition card = entry.Card; + Label name = new(GetCardDisplayName(card)); + name.AddToClassList("collection-detail-name"); + detail.Add(name); + + Label description = new(card == null || string.IsNullOrWhiteSpace(card.Description) ? "--" : card.Description); description.AddToClassList("collection-detail-description"); detail.Add(description); + + detail.Add(BuildDetailLine("owner", DistroPresentation.DisplayName(entry.Owner))); + detail.Add(BuildDetailLine("lang", card == null ? "--" : card.Language.ToString())); + detail.Add(BuildDetailLine("rarity", card == null ? "--" : card.Rarity.ToString())); + detail.Add(BuildDetailLine("cost", card == null ? "--" : card.CycleCost.ToString())); + detail.Add(BuildDetailLine("type", card != null && card.IsToken ? "token" : "loadout")); } private static VisualElement BuildDetailLine(string key, string value) @@ -140,5 +226,54 @@ namespace KernelPanic.UI row.Add(valueLabel); return row; } + + private static IReadOnlyList BuildCardEntries(DistroDefinition featuredUnit) + { + List entries = new(); + if (featuredUnit == null) + { + return entries; + } + + for (int cardIndex = 0; cardIndex < featuredUnit.ExclusiveCards.Count; cardIndex++) + { + CardDefinition card = featuredUnit.ExclusiveCards[cardIndex]; + if (card == null) + { + continue; + } + + entries.Add(new CardEntry(featuredUnit, card)); + } + + return entries; + } + + private static string GetCardDisplayName(CardDefinition card) + { + if (card == null) + { + return "--"; + } + + return string.IsNullOrWhiteSpace(card.DisplayName) ? card.Id : card.DisplayName; + } + + private static string FormatCardMeta(CardDefinition card) + { + return card == null ? "--" : $"{card.Language} / {card.CycleCost}c"; + } + + private readonly struct CardEntry + { + public CardEntry(DistroDefinition owner, CardDefinition card) + { + Owner = owner; + Card = card; + } + + public DistroDefinition Owner { get; } + public CardDefinition Card { get; } + } } } diff --git a/Assets/Scripts/UI/FeaturedUnitPanel.cs b/Assets/Scripts/UI/FeaturedUnitPanel.cs index b194212..6b874c2 100644 --- a/Assets/Scripts/UI/FeaturedUnitPanel.cs +++ b/Assets/Scripts/UI/FeaturedUnitPanel.cs @@ -55,12 +55,22 @@ namespace KernelPanic.UI } public void Refresh(IReadOnlyList ownedUnits) + { + Refresh(ownedUnits, null); + } + + public void Refresh(IReadOnlyList ownedUnits, DistroDefinition featuredUnit) { units = ownedUnits ?? Array.Empty(); - Refresh(); + Refresh(featuredUnit); } public void Refresh() + { + Refresh((DistroDefinition)null); + } + + private void Refresh(DistroDefinition featuredUnit) { if (units == null || units.Count == 0) { @@ -68,7 +78,7 @@ namespace KernelPanic.UI return; } - selectedIndex = Mathf.Clamp(selectedIndex, 0, units.Count - 1); + selectedIndex = ResolveSelectedIndex(featuredUnit); ShowUnit(units[selectedIndex]); } @@ -84,6 +94,22 @@ namespace KernelPanic.UI Refresh(); } + private int ResolveSelectedIndex(DistroDefinition featuredUnit) + { + if (featuredUnit != null) + { + for (int i = 0; i < units.Count; i++) + { + if (units[i] == featuredUnit) + { + return i; + } + } + } + + return Mathf.Clamp(selectedIndex, 0, units.Count - 1); + } + private void ShowEmptyState() { populatedState.AddToClassList("hidden"); diff --git a/Assets/Scripts/UI/MainMenuController.cs b/Assets/Scripts/UI/MainMenuController.cs index 19227b2..461026f 100644 --- a/Assets/Scripts/UI/MainMenuController.cs +++ b/Assets/Scripts/UI/MainMenuController.cs @@ -43,6 +43,8 @@ namespace KernelPanic.UI [SerializeField] private StarterSelectionController starterSelection = new(); private readonly List commandEntries = new(); + private readonly List packageRows = new(); + private readonly List loadoutRows = new(); private UIDocument document; private VisualElement root; private VisualElement shellRoot; @@ -54,6 +56,8 @@ namespace KernelPanic.UI private VisualElement settingsPanel; private VisualElement eventBanner; private VisualElement backgroundLogLayer; + private ScrollView runSetupList; + private VisualElement runSetupDetail; private Label appIdLabel; private Label entropyLabel; private Label pullTokensLabel; @@ -62,12 +66,12 @@ namespace KernelPanic.UI private Label bootIntroLogLabel; private Label motdBodyLabel; private VisualElement motdBlock; - private Button collectionBackButton; private Button collectionUnitsButton; private Button collectionCardsButton; - private Button runSetupBackButton; - private Button gachaBackButton; - private Button settingsBackButton; + private readonly ScreenFrameController runSetupFrame = new(); + private readonly ScreenFrameController collectionFrame = new(); + private readonly ScreenFrameController gachaFrame = new(); + private readonly ScreenFrameController settingsFrame = new(); private SaveService saveService; private SaveData saveData; private EntropyWallet wallet; @@ -77,12 +81,14 @@ namespace KernelPanic.UI private BackgroundLogRingBuffer backgroundLog; private IEventBannerSource eventBannerSource; private int selectedCommandIndex; + private int selectedPackageIndex; + private string runSetupNotice; + private bool collectionShowingCards; private float bootIntroElapsed; private int bootIntroCharacterCount; private bool cursorVisible; private bool suppressNextClick; private bool warnedUnresolvedSaveId; - private bool warnedInvalidLoadoutId; private string bootIntroCopy; private IVisualElementScheduledItem blinkSchedule; private IVisualElementScheduledItem bootIntroSchedule; @@ -106,6 +112,7 @@ namespace KernelPanic.UI RegisterCommandEntryCallbacks(); featuredUnitPanel.Bind(root, monospaceFont); collectionScreen.Bind(root, monospaceFont); + BindScreenFrames(); starterSelection.Bind(root, distroDatabase, HandleStarterConfirmed); LoadMetaState(); playerCollection.Changed += HandleMetaStateChanged; @@ -121,8 +128,8 @@ namespace KernelPanic.UI RefreshStaticText(); RefreshCurrencyReadouts(); RefreshEventBanner(); - featuredUnitPanel.Refresh(playerCollection.OwnedUnits); - collectionScreen.Refresh(playerCollection.OwnedUnits); + featuredUnitPanel.Refresh(playerCollection.OwnedUnits, playerCollection.FeaturedUnit); + collectionScreen.RefreshUnits(playerCollection.OwnedUnits); SelectCommand(0); ShowMainMenu(); StartAmbientSchedules(); @@ -151,6 +158,8 @@ namespace KernelPanic.UI eventBanner = root.Q("EventBanner"); motdBlock = root.Q("MotdBlock"); backgroundLogLayer = root.Q("BackgroundLogLayer"); + runSetupList = root.Q("RunSetupList"); + runSetupDetail = root.Q("RunSetupDetail"); backgroundLog = new BackgroundLogRingBuffer(backgroundLogLayer, BootLogCopy.Lines); appIdLabel = root.Q