refactor card systems
This commit is contained in:
@@ -23,4 +23,9 @@ MonoBehaviour:
|
|||||||
baseUptime: 60
|
baseUptime: 60
|
||||||
baseRam: 5
|
baseRam: 5
|
||||||
baseCyclesPerTurn: 3
|
baseCyclesPerTurn: 3
|
||||||
exclusiveCards: []
|
exclusiveCards:
|
||||||
|
- {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}
|
||||||
|
|||||||
@@ -306,4 +306,5 @@ MonoBehaviour:
|
|||||||
monospaceFont: {fileID: 0}
|
monospaceFont: {fileID: 0}
|
||||||
motdBody: unstable userspace detected; keep a rollback shell open.
|
motdBody: unstable userspace detected; keep a rollback shell open.
|
||||||
distroDatabase: {fileID: 11400000, guid: 4d88ca5446fa4d80b2fbd4b12697cb7c, type: 2}
|
distroDatabase: {fileID: 11400000, guid: 4d88ca5446fa4d80b2fbd4b12697cb7c, type: 2}
|
||||||
|
cardDatabase: {fileID: 11400000, guid: 6a8a9f37c98a4a7a9e67ab15d2d22208, type: 2}
|
||||||
featuredUnitPanel: {}
|
featuredUnitPanel: {}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ namespace KernelPanic.Data
|
|||||||
[SerializeField] private int cycleCost;
|
[SerializeField] private int cycleCost;
|
||||||
[SerializeField] private ResolutionTrack resolutionTrack;
|
[SerializeField] private ResolutionTrack resolutionTrack;
|
||||||
[SerializeField] private bool distroExclusive;
|
[SerializeField] private bool distroExclusive;
|
||||||
|
[SerializeField] private bool isToken;
|
||||||
|
[SerializeField, TextArea] private string designNotes;
|
||||||
[SerializeField] private CardDefinition upgradeTarget;
|
[SerializeField] private CardDefinition upgradeTarget;
|
||||||
[SerializeField] private List<CardEffectDefinition> effects = new();
|
[SerializeField] private List<CardEffectDefinition> effects = new();
|
||||||
|
|
||||||
@@ -28,6 +30,8 @@ namespace KernelPanic.Data
|
|||||||
public int CycleCost => cycleCost;
|
public int CycleCost => cycleCost;
|
||||||
public ResolutionTrack ResolutionTrack => resolutionTrack;
|
public ResolutionTrack ResolutionTrack => resolutionTrack;
|
||||||
public bool DistroExclusive => distroExclusive;
|
public bool DistroExclusive => distroExclusive;
|
||||||
|
public bool IsToken => isToken;
|
||||||
|
public string DesignNotes => designNotes;
|
||||||
public CardDefinition UpgradeTarget => upgradeTarget;
|
public CardDefinition UpgradeTarget => upgradeTarget;
|
||||||
public IReadOnlyList<CardEffectDefinition> Effects => effects;
|
public IReadOnlyList<CardEffectDefinition> Effects => effects;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ namespace KernelPanic.Meta
|
|||||||
public bool starterChosen;
|
public bool starterChosen;
|
||||||
public List<string> ownedUnitIds = new();
|
public List<string> ownedUnitIds = new();
|
||||||
public List<string> bannerPoolIds = new();
|
public List<string> bannerPoolIds = new();
|
||||||
|
public List<CardLoadoutSaveEntry> cardLoadouts = new();
|
||||||
|
|
||||||
public static SaveData CreateDefault()
|
public static SaveData CreateDefault()
|
||||||
{
|
{
|
||||||
@@ -70,6 +71,24 @@ namespace KernelPanic.Meta
|
|||||||
{
|
{
|
||||||
ownedUnitIds ??= new List<string>();
|
ownedUnitIds ??= new List<string>();
|
||||||
bannerPoolIds ??= new List<string>();
|
bannerPoolIds ??= new List<string>();
|
||||||
|
cardLoadouts ??= new List<CardLoadoutSaveEntry>();
|
||||||
|
for (int i = 0; i < cardLoadouts.Count; i++)
|
||||||
|
{
|
||||||
|
cardLoadouts[i] ??= new CardLoadoutSaveEntry();
|
||||||
|
cardLoadouts[i].EnsureLists();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public sealed class CardLoadoutSaveEntry
|
||||||
|
{
|
||||||
|
public string distroId;
|
||||||
|
public List<string> equippedCardIds = new();
|
||||||
|
|
||||||
|
public void EnsureLists()
|
||||||
|
{
|
||||||
|
equippedCardIds ??= new List<string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ namespace KernelPanic.UI
|
|||||||
[SerializeField] private FontAsset monospaceFont; // TODO: Assign a real monospace FontAsset when typography assets exist.
|
[SerializeField] private FontAsset monospaceFont; // TODO: Assign a real monospace FontAsset when typography assets exist.
|
||||||
[SerializeField] private string motdBody = "unstable userspace detected; keep a rollback shell open.";
|
[SerializeField] private string motdBody = "unstable userspace detected; keep a rollback shell open.";
|
||||||
[SerializeField] private DistroDatabase distroDatabase;
|
[SerializeField] private DistroDatabase distroDatabase;
|
||||||
|
[SerializeField] private CardDatabase cardDatabase;
|
||||||
[SerializeField] private FeaturedUnitPanel featuredUnitPanel = new();
|
[SerializeField] private FeaturedUnitPanel featuredUnitPanel = new();
|
||||||
|
|
||||||
private readonly List<CommandMenuEntry> commandEntries = new();
|
private readonly List<CommandMenuEntry> commandEntries = new();
|
||||||
@@ -36,12 +37,16 @@ namespace KernelPanic.UI
|
|||||||
private readonly List<Label> starterLanguages = new();
|
private readonly List<Label> starterLanguages = new();
|
||||||
private readonly List<Label> starterDescriptions = new();
|
private readonly List<Label> starterDescriptions = new();
|
||||||
private readonly List<VisualElement> collectionRows = new();
|
private readonly List<VisualElement> collectionRows = new();
|
||||||
|
private readonly List<VisualElement> cardRows = new();
|
||||||
|
private readonly List<VisualElement> runSetupRows = new();
|
||||||
|
private readonly List<VisualElement> packageRows = new();
|
||||||
private UIDocument document;
|
private UIDocument document;
|
||||||
private VisualElement root;
|
private VisualElement root;
|
||||||
private VisualElement shellRoot;
|
private VisualElement shellRoot;
|
||||||
private VisualElement bootIntroPanel;
|
private VisualElement bootIntroPanel;
|
||||||
private VisualElement mainMenuPanel;
|
private VisualElement mainMenuPanel;
|
||||||
private VisualElement collectionPanel;
|
private VisualElement collectionPanel;
|
||||||
|
private VisualElement runSetupPanel;
|
||||||
private VisualElement gachaPanel;
|
private VisualElement gachaPanel;
|
||||||
private VisualElement settingsPanel;
|
private VisualElement settingsPanel;
|
||||||
private VisualElement eventBanner;
|
private VisualElement eventBanner;
|
||||||
@@ -49,6 +54,8 @@ namespace KernelPanic.UI
|
|||||||
private VisualElement starterModal;
|
private VisualElement starterModal;
|
||||||
private VisualElement collectionList;
|
private VisualElement collectionList;
|
||||||
private VisualElement collectionDetail;
|
private VisualElement collectionDetail;
|
||||||
|
private VisualElement runSetupList;
|
||||||
|
private VisualElement runSetupDetail;
|
||||||
private Label appIdLabel;
|
private Label appIdLabel;
|
||||||
private Label entropyLabel;
|
private Label entropyLabel;
|
||||||
private Label pullTokensLabel;
|
private Label pullTokensLabel;
|
||||||
@@ -59,6 +66,9 @@ namespace KernelPanic.UI
|
|||||||
private Label starterConfirmLabel;
|
private Label starterConfirmLabel;
|
||||||
private VisualElement motdBlock;
|
private VisualElement motdBlock;
|
||||||
private Button collectionBackButton;
|
private Button collectionBackButton;
|
||||||
|
private Button collectionUnitsButton;
|
||||||
|
private Button collectionCardsButton;
|
||||||
|
private Button runSetupBackButton;
|
||||||
private Button gachaBackButton;
|
private Button gachaBackButton;
|
||||||
private Button settingsBackButton;
|
private Button settingsBackButton;
|
||||||
private SaveService saveService;
|
private SaveService saveService;
|
||||||
@@ -66,22 +76,29 @@ namespace KernelPanic.UI
|
|||||||
private EntropyWallet wallet;
|
private EntropyWallet wallet;
|
||||||
private GachaService gachaService;
|
private GachaService gachaService;
|
||||||
private PlayerCollection playerCollection;
|
private PlayerCollection playerCollection;
|
||||||
|
private CardLoadout cardLoadout;
|
||||||
private BackgroundLogRingBuffer backgroundLog;
|
private BackgroundLogRingBuffer backgroundLog;
|
||||||
private IEventBannerSource eventBannerSource;
|
private IEventBannerSource eventBannerSource;
|
||||||
private int selectedCommandIndex;
|
private int selectedCommandIndex;
|
||||||
private int selectedStarterIndex;
|
private int selectedStarterIndex;
|
||||||
private int selectedCollectionIndex;
|
private int selectedCollectionIndex;
|
||||||
|
private int selectedCardIndex;
|
||||||
|
private int selectedRunSetupIndex;
|
||||||
|
private int selectedPackageIndex;
|
||||||
private float bootIntroElapsed;
|
private float bootIntroElapsed;
|
||||||
private int bootIntroCharacterCount;
|
private int bootIntroCharacterCount;
|
||||||
private bool cursorVisible;
|
private bool cursorVisible;
|
||||||
private bool suppressNextClick;
|
private bool suppressNextClick;
|
||||||
private bool starterModalActive;
|
private bool starterModalActive;
|
||||||
private bool starterConfirming;
|
private bool starterConfirming;
|
||||||
|
private bool collectionShowingCards;
|
||||||
private bool warnedUnresolvedSaveId;
|
private bool warnedUnresolvedSaveId;
|
||||||
|
private bool warnedInvalidLoadoutId;
|
||||||
private string bootIntroCopy;
|
private string bootIntroCopy;
|
||||||
private IVisualElementScheduledItem blinkSchedule;
|
private IVisualElementScheduledItem blinkSchedule;
|
||||||
private IVisualElementScheduledItem bootIntroSchedule;
|
private IVisualElementScheduledItem bootIntroSchedule;
|
||||||
private IVisualElementScheduledItem starterCloseSchedule;
|
private IVisualElementScheduledItem starterCloseSchedule;
|
||||||
|
private IVisualElementScheduledItem packageNoticeSchedule;
|
||||||
|
|
||||||
public void Initialize(EntropyWallet initializedWallet)
|
public void Initialize(EntropyWallet initializedWallet)
|
||||||
{
|
{
|
||||||
@@ -95,6 +112,7 @@ namespace KernelPanic.UI
|
|||||||
saveService = new SaveService();
|
saveService = new SaveService();
|
||||||
gachaService = new GachaService();
|
gachaService = new GachaService();
|
||||||
playerCollection = new PlayerCollection(); // TODO: Replace with persistent player-collection service composition.
|
playerCollection = new PlayerCollection(); // TODO: Replace with persistent player-collection service composition.
|
||||||
|
cardLoadout = new CardLoadout(playerCollection.OwnedUnits);
|
||||||
Initialize(new EntropyWallet()); // TODO: Replace with persistent wallet service composition.
|
Initialize(new EntropyWallet()); // TODO: Replace with persistent wallet service composition.
|
||||||
BindElements();
|
BindElements();
|
||||||
BindCommandEntries();
|
BindCommandEntries();
|
||||||
@@ -130,6 +148,7 @@ namespace KernelPanic.UI
|
|||||||
backgroundLog?.Stop();
|
backgroundLog?.Stop();
|
||||||
bootIntroSchedule?.Pause();
|
bootIntroSchedule?.Pause();
|
||||||
starterCloseSchedule?.Pause();
|
starterCloseSchedule?.Pause();
|
||||||
|
packageNoticeSchedule?.Pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void BindElements()
|
private void BindElements()
|
||||||
@@ -139,6 +158,7 @@ namespace KernelPanic.UI
|
|||||||
bootIntroPanel = root.Q<VisualElement>("BootIntroPanel");
|
bootIntroPanel = root.Q<VisualElement>("BootIntroPanel");
|
||||||
mainMenuPanel = root.Q<VisualElement>("MainMenuPanel");
|
mainMenuPanel = root.Q<VisualElement>("MainMenuPanel");
|
||||||
collectionPanel = root.Q<VisualElement>("CollectionPanel");
|
collectionPanel = root.Q<VisualElement>("CollectionPanel");
|
||||||
|
runSetupPanel = root.Q<VisualElement>("RunSetupPanel");
|
||||||
gachaPanel = root.Q<VisualElement>("GachaPanel");
|
gachaPanel = root.Q<VisualElement>("GachaPanel");
|
||||||
settingsPanel = root.Q<VisualElement>("SettingsPanel");
|
settingsPanel = root.Q<VisualElement>("SettingsPanel");
|
||||||
eventBanner = root.Q<VisualElement>("EventBanner");
|
eventBanner = root.Q<VisualElement>("EventBanner");
|
||||||
@@ -148,6 +168,8 @@ namespace KernelPanic.UI
|
|||||||
starterModal = root.Q<VisualElement>("StarterModal");
|
starterModal = root.Q<VisualElement>("StarterModal");
|
||||||
collectionList = root.Q<VisualElement>("CollectionList");
|
collectionList = root.Q<VisualElement>("CollectionList");
|
||||||
collectionDetail = root.Q<VisualElement>("CollectionDetail");
|
collectionDetail = root.Q<VisualElement>("CollectionDetail");
|
||||||
|
runSetupList = root.Q<VisualElement>("RunSetupList");
|
||||||
|
runSetupDetail = root.Q<VisualElement>("RunSetupDetail");
|
||||||
|
|
||||||
appIdLabel = root.Q<Label>("AppIdLabel");
|
appIdLabel = root.Q<Label>("AppIdLabel");
|
||||||
entropyLabel = root.Q<Label>("EntropyLabel");
|
entropyLabel = root.Q<Label>("EntropyLabel");
|
||||||
@@ -167,6 +189,9 @@ namespace KernelPanic.UI
|
|||||||
}
|
}
|
||||||
|
|
||||||
collectionBackButton = root.Q<Button>("CollectionBackButton");
|
collectionBackButton = root.Q<Button>("CollectionBackButton");
|
||||||
|
collectionUnitsButton = root.Q<Button>("CollectionUnitsButton");
|
||||||
|
collectionCardsButton = root.Q<Button>("CollectionCardsButton");
|
||||||
|
runSetupBackButton = root.Q<Button>("RunSetupBackButton");
|
||||||
gachaBackButton = root.Q<Button>("GachaBackButton");
|
gachaBackButton = root.Q<Button>("GachaBackButton");
|
||||||
settingsBackButton = root.Q<Button>("SettingsBackButton");
|
settingsBackButton = root.Q<Button>("SettingsBackButton");
|
||||||
}
|
}
|
||||||
@@ -196,6 +221,9 @@ namespace KernelPanic.UI
|
|||||||
root.RegisterCallback<KeyDownEvent>(HandleKeyDown);
|
root.RegisterCallback<KeyDownEvent>(HandleKeyDown);
|
||||||
root.RegisterCallback<PointerDownEvent>(HandlePointerDown);
|
root.RegisterCallback<PointerDownEvent>(HandlePointerDown);
|
||||||
collectionBackButton.clicked += ShowMainMenu;
|
collectionBackButton.clicked += ShowMainMenu;
|
||||||
|
collectionUnitsButton.clicked += ShowCollectionUnits;
|
||||||
|
collectionCardsButton.clicked += ShowCollectionCards;
|
||||||
|
runSetupBackButton.clicked += ShowMainMenu;
|
||||||
gachaBackButton.clicked += ShowMainMenu;
|
gachaBackButton.clicked += ShowMainMenu;
|
||||||
settingsBackButton.clicked += ShowMainMenu;
|
settingsBackButton.clicked += ShowMainMenu;
|
||||||
}
|
}
|
||||||
@@ -205,6 +233,9 @@ namespace KernelPanic.UI
|
|||||||
root.UnregisterCallback<KeyDownEvent>(HandleKeyDown);
|
root.UnregisterCallback<KeyDownEvent>(HandleKeyDown);
|
||||||
root.UnregisterCallback<PointerDownEvent>(HandlePointerDown);
|
root.UnregisterCallback<PointerDownEvent>(HandlePointerDown);
|
||||||
collectionBackButton.clicked -= ShowMainMenu;
|
collectionBackButton.clicked -= ShowMainMenu;
|
||||||
|
collectionUnitsButton.clicked -= ShowCollectionUnits;
|
||||||
|
collectionCardsButton.clicked -= ShowCollectionCards;
|
||||||
|
runSetupBackButton.clicked -= ShowMainMenu;
|
||||||
gachaBackButton.clicked -= ShowMainMenu;
|
gachaBackButton.clicked -= ShowMainMenu;
|
||||||
settingsBackButton.clicked -= ShowMainMenu;
|
settingsBackButton.clicked -= ShowMainMenu;
|
||||||
}
|
}
|
||||||
@@ -231,6 +262,29 @@ namespace KernelPanic.UI
|
|||||||
gachaService.AddToBannerPool(unit);
|
gachaService.AddToBannerPool(unit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < saveData.cardLoadouts.Count; i++)
|
||||||
|
{
|
||||||
|
CardLoadoutSaveEntry entry = saveData.cardLoadouts[i];
|
||||||
|
entry.EnsureLists();
|
||||||
|
List<string> resolvedIds = new();
|
||||||
|
for (int cardIndex = 0; cardIndex < entry.equippedCardIds.Count; cardIndex++)
|
||||||
|
{
|
||||||
|
string resolvedId = ResolveSavedCardId(entry.equippedCardIds[cardIndex]);
|
||||||
|
if (!string.IsNullOrWhiteSpace(resolvedId))
|
||||||
|
{
|
||||||
|
resolvedIds.Add(resolvedId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cardLoadout.TryLoad(entry.distroId, resolvedIds, out bool skippedInvalid) || skippedInvalid)
|
||||||
|
{
|
||||||
|
WarnInvalidLoadoutId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureLoadoutsForOwnedUnits();
|
||||||
|
SaveCurrentState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private DistroDefinition ResolveSavedDistro(string id)
|
private DistroDefinition ResolveSavedDistro(string id)
|
||||||
@@ -245,11 +299,49 @@ namespace KernelPanic.UI
|
|||||||
return unit;
|
return unit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string ResolveSavedCardId(string id)
|
||||||
|
{
|
||||||
|
if (cardDatabase == null)
|
||||||
|
{
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
CardDefinition card = cardDatabase.FindById(id);
|
||||||
|
if (card == null)
|
||||||
|
{
|
||||||
|
WarnInvalidLoadoutId();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return card.Id;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WarnInvalidLoadoutId()
|
||||||
|
{
|
||||||
|
if (warnedInvalidLoadoutId)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
warnedInvalidLoadoutId = true;
|
||||||
|
Debug.LogWarning("Save references an invalid card loadout id; restoring a valid default loadout.");
|
||||||
|
}
|
||||||
|
|
||||||
private void HandleMetaStateChanged()
|
private void HandleMetaStateChanged()
|
||||||
{
|
{
|
||||||
|
EnsureLoadoutsForOwnedUnits();
|
||||||
SaveCurrentState();
|
SaveCurrentState();
|
||||||
featuredUnitPanel.Refresh(playerCollection.OwnedUnits);
|
featuredUnitPanel.Refresh(playerCollection.OwnedUnits);
|
||||||
RefreshCollection();
|
RefreshCollection();
|
||||||
|
RefreshRunSetup();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EnsureLoadoutsForOwnedUnits()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < playerCollection.OwnedUnits.Count; i++)
|
||||||
|
{
|
||||||
|
cardLoadout.EnsureDefaultLoadout(playerCollection.OwnedUnits[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveCurrentState()
|
private void SaveCurrentState()
|
||||||
@@ -277,6 +369,8 @@ namespace KernelPanic.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cardLoadout.WriteTo(saveData.cardLoadouts);
|
||||||
|
|
||||||
saveService.Save(saveData);
|
saveService.Save(saveData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,8 +439,22 @@ namespace KernelPanic.UI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (collectionShowingCards)
|
||||||
|
{
|
||||||
|
RefreshCollectionCards();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshCollectionUnits();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshCollectionUnits()
|
||||||
|
{
|
||||||
collectionRows.Clear();
|
collectionRows.Clear();
|
||||||
collectionList.Clear();
|
collectionList.Clear();
|
||||||
|
collectionDetail.Clear();
|
||||||
|
collectionUnitsButton?.AddToClassList(SelectedClassName);
|
||||||
|
collectionCardsButton?.RemoveFromClassList(SelectedClassName);
|
||||||
|
|
||||||
IReadOnlyList<DistroDefinition> units = playerCollection.OwnedUnits;
|
IReadOnlyList<DistroDefinition> units = playerCollection.OwnedUnits;
|
||||||
if (units.Count == 0)
|
if (units.Count == 0)
|
||||||
@@ -383,6 +491,58 @@ namespace KernelPanic.UI
|
|||||||
SelectCollectionUnit(selectedCollectionIndex);
|
SelectCollectionUnit(selectedCollectionIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RefreshCollectionCards()
|
||||||
|
{
|
||||||
|
cardRows.Clear();
|
||||||
|
collectionList.Clear();
|
||||||
|
collectionDetail.Clear();
|
||||||
|
collectionUnitsButton?.RemoveFromClassList(SelectedClassName);
|
||||||
|
collectionCardsButton?.AddToClassList(SelectedClassName);
|
||||||
|
|
||||||
|
IReadOnlyList<CardDefinition> cards = cardDatabase == null ? Array.Empty<CardDefinition>() : cardDatabase.AllCards;
|
||||||
|
if (cards.Count == 0)
|
||||||
|
{
|
||||||
|
collectionDetail.Add(new Label("no cards indexed") { name = "CollectionEmptyTitle" });
|
||||||
|
collectionDetail.Add(new Label("assign a CardDatabase to browse card rules here") { name = "CollectionEmptyHint" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < cards.Count; i++)
|
||||||
|
{
|
||||||
|
CardDefinition card = cards[i];
|
||||||
|
if (card == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = cardRows.Count;
|
||||||
|
VisualElement row = new();
|
||||||
|
row.AddToClassList("collection-row");
|
||||||
|
row.RegisterCallback<PointerEnterEvent>(_ => SelectCollectionCard(index));
|
||||||
|
row.RegisterCallback<ClickEvent>(_ => SelectCollectionCard(index));
|
||||||
|
|
||||||
|
Label name = new(DisplayName(card));
|
||||||
|
name.AddToClassList("collection-row-name");
|
||||||
|
|
||||||
|
Label meta = new($"{card.Language} {card.CycleCost}c");
|
||||||
|
meta.AddToClassList("collection-row-languages");
|
||||||
|
|
||||||
|
row.Add(name);
|
||||||
|
row.Add(meta);
|
||||||
|
collectionList.Add(row);
|
||||||
|
cardRows.Add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cardRows.Count == 0)
|
||||||
|
{
|
||||||
|
collectionDetail.Add(new Label("no cards indexed") { name = "CollectionEmptyTitle" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedCardIndex = Mathf.Clamp(selectedCardIndex, 0, cardRows.Count - 1);
|
||||||
|
SelectCollectionCard(selectedCardIndex);
|
||||||
|
}
|
||||||
|
|
||||||
private void SelectCollectionUnit(int index)
|
private void SelectCollectionUnit(int index)
|
||||||
{
|
{
|
||||||
IReadOnlyList<DistroDefinition> units = playerCollection.OwnedUnits;
|
IReadOnlyList<DistroDefinition> units = playerCollection.OwnedUnits;
|
||||||
@@ -400,9 +560,27 @@ namespace KernelPanic.UI
|
|||||||
RenderCollectionDetail(units[selectedCollectionIndex]);
|
RenderCollectionDetail(units[selectedCollectionIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SelectCollectionCard(int index)
|
||||||
|
{
|
||||||
|
if (cardRows.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedCardIndex = Mathf.Clamp(index, 0, cardRows.Count - 1);
|
||||||
|
for (int i = 0; i < cardRows.Count; i++)
|
||||||
|
{
|
||||||
|
cardRows[i].EnableInClassList(SelectedClassName, i == selectedCardIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderCardDetail(GetVisibleCard(selectedCardIndex));
|
||||||
|
}
|
||||||
|
|
||||||
private void RenderCollectionDetail(DistroDefinition unit)
|
private void RenderCollectionDetail(DistroDefinition unit)
|
||||||
{
|
{
|
||||||
collectionDetail.Clear();
|
collectionDetail.Clear();
|
||||||
|
packageRows.Clear();
|
||||||
|
selectedPackageIndex = 0;
|
||||||
|
|
||||||
// TODO: Unify this readout with FeaturedUnitPanel when unit presentation grows beyond labels.
|
// TODO: Unify this readout with FeaturedUnitPanel when unit presentation grows beyond labels.
|
||||||
VisualElement readout = new();
|
VisualElement readout = new();
|
||||||
@@ -438,6 +616,298 @@ namespace KernelPanic.UI
|
|||||||
collectionDetail.Add(description);
|
collectionDetail.Add(description);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void RenderCardDetail(CardDefinition card)
|
||||||
|
{
|
||||||
|
collectionDetail.Clear();
|
||||||
|
if (card == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Label name = new(DisplayName(card));
|
||||||
|
name.AddToClassList("collection-detail-name");
|
||||||
|
collectionDetail.Add(name);
|
||||||
|
|
||||||
|
collectionDetail.Add(BuildDetailLine("language", card.Language.ToString()));
|
||||||
|
collectionDetail.Add(BuildDetailLine("rarity", card.Rarity.ToString()));
|
||||||
|
collectionDetail.Add(BuildDetailLine("cost", $"{card.CycleCost} cycles"));
|
||||||
|
collectionDetail.Add(BuildDetailLine("track", card.ResolutionTrack.ToString()));
|
||||||
|
collectionDetail.Add(BuildDetailLine("type", card.DistroExclusive ? "distro exclusive" : "standard"));
|
||||||
|
|
||||||
|
Label description = new(string.IsNullOrWhiteSpace(card.Description) ? "--" : card.Description);
|
||||||
|
description.AddToClassList("collection-detail-description");
|
||||||
|
collectionDetail.Add(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshRunSetup()
|
||||||
|
{
|
||||||
|
if (runSetupList == null || runSetupDetail == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
runSetupRows.Clear();
|
||||||
|
runSetupList.Clear();
|
||||||
|
runSetupDetail.Clear();
|
||||||
|
|
||||||
|
IReadOnlyList<DistroDefinition> units = playerCollection.OwnedUnits;
|
||||||
|
if (units.Count == 0)
|
||||||
|
{
|
||||||
|
runSetupDetail.Add(new Label("no units installed") { name = "RunSetupEmptyTitle" });
|
||||||
|
runSetupDetail.Add(new Label("run: curl gacha.sh | sh") { name = "RunSetupEmptyHint" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedRunSetupIndex = Mathf.Clamp(selectedRunSetupIndex, 0, units.Count - 1);
|
||||||
|
for (int i = 0; i < units.Count; i++)
|
||||||
|
{
|
||||||
|
int index = i;
|
||||||
|
DistroDefinition unit = units[i];
|
||||||
|
VisualElement row = new();
|
||||||
|
row.AddToClassList("collection-row");
|
||||||
|
row.RegisterCallback<PointerEnterEvent>(_ => SelectRunSetupUnit(index));
|
||||||
|
row.RegisterCallback<ClickEvent>(_ => SelectRunSetupUnit(index));
|
||||||
|
|
||||||
|
Label name = new(DisplayName(unit));
|
||||||
|
name.AddToClassList("collection-row-name");
|
||||||
|
name.style.color = new StyleColor(unit.AccentColor);
|
||||||
|
|
||||||
|
Label languages = new(FormatLanguages(unit));
|
||||||
|
languages.AddToClassList("collection-row-languages");
|
||||||
|
|
||||||
|
row.Add(name);
|
||||||
|
row.Add(languages);
|
||||||
|
runSetupList.Add(row);
|
||||||
|
runSetupRows.Add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectRunSetupUnit(selectedRunSetupIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectRunSetupUnit(int index)
|
||||||
|
{
|
||||||
|
IReadOnlyList<DistroDefinition> units = playerCollection.OwnedUnits;
|
||||||
|
if (units.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedRunSetupIndex = Mathf.Clamp(index, 0, units.Count - 1);
|
||||||
|
for (int i = 0; i < runSetupRows.Count; i++)
|
||||||
|
{
|
||||||
|
runSetupRows[i].EnableInClassList(SelectedClassName, i == selectedRunSetupIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderRunSetupDetail(units[selectedRunSetupIndex]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenderRunSetupDetail(DistroDefinition unit)
|
||||||
|
{
|
||||||
|
runSetupDetail.Clear();
|
||||||
|
packageRows.Clear();
|
||||||
|
selectedPackageIndex = 0;
|
||||||
|
|
||||||
|
Label name = new(DisplayName(unit));
|
||||||
|
name.AddToClassList("collection-detail-name");
|
||||||
|
name.style.color = new StyleColor(unit.AccentColor);
|
||||||
|
runSetupDetail.Add(name);
|
||||||
|
runSetupDetail.Add(BuildDetailLine("lang", FormatLanguages(unit)));
|
||||||
|
runSetupDetail.Add(BuildDetailLine("loadout", $"pick {CardLoadout.MaxEquippedCards} cards"));
|
||||||
|
BuildPackageList(unit, runSetupDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BuildPackageList(DistroDefinition unit, VisualElement parent)
|
||||||
|
{
|
||||||
|
VisualElement packageSection = new();
|
||||||
|
packageSection.AddToClassList("package-list");
|
||||||
|
|
||||||
|
Label header = new("dpkg -l (pick 4)");
|
||||||
|
header.AddToClassList("package-header");
|
||||||
|
packageSection.Add(header);
|
||||||
|
|
||||||
|
Label notice = new();
|
||||||
|
notice.name = "PackageNotice";
|
||||||
|
notice.AddToClassList("package-notice");
|
||||||
|
notice.AddToClassList(HiddenClassName);
|
||||||
|
packageSection.Add(notice);
|
||||||
|
|
||||||
|
if (unit.ExclusiveCards.Count == 0)
|
||||||
|
{
|
||||||
|
Label empty = new("no distro packages installed");
|
||||||
|
empty.AddToClassList("package-empty");
|
||||||
|
packageSection.Add(empty);
|
||||||
|
parent.Add(packageSection);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IReadOnlyList<string> equippedIds = cardLoadout.GetEquippedCardIds(unit.Id);
|
||||||
|
for (int i = 0; i < unit.ExclusiveCards.Count; i++)
|
||||||
|
{
|
||||||
|
CardDefinition card = unit.ExclusiveCards[i];
|
||||||
|
if (card == null || card.IsToken)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = packageRows.Count;
|
||||||
|
VisualElement row = BuildPackageRow(unit, card, equippedIds, index);
|
||||||
|
packageRows.Add(row);
|
||||||
|
packageSection.Add(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
parent.Add(packageSection);
|
||||||
|
RefreshPackageSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
private VisualElement BuildPackageRow(DistroDefinition unit, CardDefinition card, IReadOnlyList<string> equippedIds, int index)
|
||||||
|
{
|
||||||
|
bool equipped = ContainsId(equippedIds, card.Id);
|
||||||
|
bool loadoutFull = equippedIds.Count >= CardLoadout.MaxEquippedCards;
|
||||||
|
|
||||||
|
VisualElement row = new();
|
||||||
|
row.AddToClassList("package-row");
|
||||||
|
row.EnableInClassList("equipped", equipped);
|
||||||
|
row.EnableInClassList("dimmed", !equipped && loadoutFull);
|
||||||
|
row.RegisterCallback<PointerEnterEvent>(_ =>
|
||||||
|
{
|
||||||
|
selectedPackageIndex = index;
|
||||||
|
RefreshPackageSelection();
|
||||||
|
});
|
||||||
|
row.RegisterCallback<ClickEvent>(_ => TogglePackage(unit, card));
|
||||||
|
|
||||||
|
VisualElement summary = new();
|
||||||
|
summary.AddToClassList("package-summary");
|
||||||
|
|
||||||
|
Label marker = new(equipped ? "[x]" : "[ ]");
|
||||||
|
marker.AddToClassList("package-marker");
|
||||||
|
marker.style.color = new StyleColor(equipped ? unit.AccentColor : Color.gray);
|
||||||
|
|
||||||
|
Label name = new(DisplayName(card));
|
||||||
|
name.AddToClassList("package-name");
|
||||||
|
|
||||||
|
Label meta = new($"{card.Language} {card.CycleCost}c");
|
||||||
|
meta.AddToClassList("package-meta");
|
||||||
|
|
||||||
|
summary.Add(marker);
|
||||||
|
summary.Add(name);
|
||||||
|
summary.Add(meta);
|
||||||
|
|
||||||
|
Label cardDescription = new(string.IsNullOrWhiteSpace(card.Description) ? "--" : card.Description);
|
||||||
|
cardDescription.AddToClassList("package-description");
|
||||||
|
|
||||||
|
row.Add(summary);
|
||||||
|
row.Add(cardDescription);
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RefreshPackageSelection()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < packageRows.Count; i++)
|
||||||
|
{
|
||||||
|
packageRows[i].EnableInClassList(SelectedClassName, i == selectedPackageIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ToggleSelectedPackage()
|
||||||
|
{
|
||||||
|
IReadOnlyList<DistroDefinition> units = playerCollection.OwnedUnits;
|
||||||
|
if (units.Count == 0 || selectedRunSetupIndex >= units.Count)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DistroDefinition unit = units[selectedRunSetupIndex];
|
||||||
|
CardDefinition card = GetVisibleExclusiveCard(unit, selectedPackageIndex);
|
||||||
|
if (card != null)
|
||||||
|
{
|
||||||
|
TogglePackage(unit, card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TogglePackage(DistroDefinition unit, CardDefinition card)
|
||||||
|
{
|
||||||
|
IReadOnlyList<string> equippedIds = cardLoadout.GetEquippedCardIds(unit.Id);
|
||||||
|
bool changed = ContainsId(equippedIds, card.Id)
|
||||||
|
? cardLoadout.TryUnequip(unit.Id, card.Id, out CardLoadoutFailureReason reason)
|
||||||
|
: cardLoadout.TryEquip(unit.Id, card.Id, out reason);
|
||||||
|
|
||||||
|
if (!changed)
|
||||||
|
{
|
||||||
|
ShowPackageNotice(reason);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SaveCurrentState();
|
||||||
|
RenderRunSetupDetail(unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowPackageNotice(CardLoadoutFailureReason reason)
|
||||||
|
{
|
||||||
|
Label notice = runSetupDetail.Q<Label>("PackageNotice");
|
||||||
|
if (notice == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
notice.text = reason == CardLoadoutFailureReason.Full
|
||||||
|
? "dpkg: dependency limit reached (unequip a package first)"
|
||||||
|
: $"dpkg: package toggle failed ({reason})";
|
||||||
|
notice.RemoveFromClassList(HiddenClassName);
|
||||||
|
|
||||||
|
packageNoticeSchedule?.Pause();
|
||||||
|
if (UIPreferences.ReducedMotion)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
packageNoticeSchedule = root.schedule.Execute(() => notice.AddToClassList(HiddenClassName)).StartingIn(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CardDefinition GetVisibleExclusiveCard(DistroDefinition unit, int visibleIndex)
|
||||||
|
{
|
||||||
|
int currentIndex = 0;
|
||||||
|
for (int i = 0; i < unit.ExclusiveCards.Count; i++)
|
||||||
|
{
|
||||||
|
CardDefinition card = unit.ExclusiveCards[i];
|
||||||
|
if (card == null || card.IsToken)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentIndex == visibleIndex)
|
||||||
|
{
|
||||||
|
return card;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private CardDefinition GetVisibleCard(int visibleIndex)
|
||||||
|
{
|
||||||
|
IReadOnlyList<CardDefinition> cards = cardDatabase == null ? Array.Empty<CardDefinition>() : cardDatabase.AllCards;
|
||||||
|
int currentIndex = 0;
|
||||||
|
for (int i = 0; i < cards.Count; i++)
|
||||||
|
{
|
||||||
|
CardDefinition card = cards[i];
|
||||||
|
if (card == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentIndex == visibleIndex)
|
||||||
|
{
|
||||||
|
return card;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static VisualElement BuildDetailLine(string key, string value)
|
private static VisualElement BuildDetailLine(string key, string value)
|
||||||
{
|
{
|
||||||
VisualElement row = new();
|
VisualElement row = new();
|
||||||
@@ -458,6 +928,24 @@ namespace KernelPanic.UI
|
|||||||
return string.IsNullOrWhiteSpace(unit.DisplayName) ? unit.name : unit.DisplayName;
|
return string.IsNullOrWhiteSpace(unit.DisplayName) ? unit.name : unit.DisplayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string DisplayName(CardDefinition card)
|
||||||
|
{
|
||||||
|
return string.IsNullOrWhiteSpace(card.DisplayName) ? card.name : card.DisplayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool ContainsId(IReadOnlyList<string> ids, string id)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ids.Count; i++)
|
||||||
|
{
|
||||||
|
if (string.Equals(ids[i], id, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static string FormatLanguages(DistroDefinition unit)
|
private static string FormatLanguages(DistroDefinition unit)
|
||||||
{
|
{
|
||||||
return $"{unit.PrimaryLanguage} / {unit.SecondaryLanguage}";
|
return $"{unit.PrimaryLanguage} / {unit.SecondaryLanguage}";
|
||||||
@@ -555,6 +1043,30 @@ namespace KernelPanic.UI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsRunSetupVisible())
|
||||||
|
{
|
||||||
|
if (evt.keyCode == KeyCode.UpArrow)
|
||||||
|
{
|
||||||
|
SelectPackage(selectedPackageIndex - 1);
|
||||||
|
evt.StopPropagation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (evt.keyCode == KeyCode.DownArrow)
|
||||||
|
{
|
||||||
|
SelectPackage(selectedPackageIndex + 1);
|
||||||
|
evt.StopPropagation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.KeypadEnter)
|
||||||
|
{
|
||||||
|
ToggleSelectedPackage();
|
||||||
|
evt.StopPropagation();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (evt.keyCode == KeyCode.UpArrow)
|
if (evt.keyCode == KeyCode.UpArrow)
|
||||||
{
|
{
|
||||||
SelectCommand(selectedCommandIndex - 1);
|
SelectCommand(selectedCommandIndex - 1);
|
||||||
@@ -592,6 +1104,22 @@ namespace KernelPanic.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool IsRunSetupVisible()
|
||||||
|
{
|
||||||
|
return runSetupPanel != null && !runSetupPanel.ClassListContains(HiddenClassName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SelectPackage(int index)
|
||||||
|
{
|
||||||
|
if (packageRows.Count == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedPackageIndex = (index + packageRows.Count) % packageRows.Count;
|
||||||
|
RefreshPackageSelection();
|
||||||
|
}
|
||||||
|
|
||||||
private void HandlePointerDown(PointerDownEvent evt)
|
private void HandlePointerDown(PointerDownEvent evt)
|
||||||
{
|
{
|
||||||
root.Focus();
|
root.Focus();
|
||||||
@@ -813,7 +1341,8 @@ namespace KernelPanic.UI
|
|||||||
|
|
||||||
private void HandleStartRunClicked()
|
private void HandleStartRunClicked()
|
||||||
{
|
{
|
||||||
SceneLoader.LoadGame();
|
RefreshRunSetup();
|
||||||
|
ShowPanel(runSetupPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleQuitClicked()
|
private void HandleQuitClicked()
|
||||||
@@ -833,10 +1362,23 @@ namespace KernelPanic.UI
|
|||||||
|
|
||||||
private void ShowCollection()
|
private void ShowCollection()
|
||||||
{
|
{
|
||||||
|
collectionShowingCards = false;
|
||||||
RefreshCollection();
|
RefreshCollection();
|
||||||
ShowPanel(collectionPanel);
|
ShowPanel(collectionPanel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ShowCollectionUnits()
|
||||||
|
{
|
||||||
|
collectionShowingCards = false;
|
||||||
|
RefreshCollection();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowCollectionCards()
|
||||||
|
{
|
||||||
|
collectionShowingCards = true;
|
||||||
|
RefreshCollection();
|
||||||
|
}
|
||||||
|
|
||||||
private void ShowGacha()
|
private void ShowGacha()
|
||||||
{
|
{
|
||||||
ShowPanel(gachaPanel);
|
ShowPanel(gachaPanel);
|
||||||
@@ -852,6 +1394,7 @@ namespace KernelPanic.UI
|
|||||||
{
|
{
|
||||||
mainMenuPanel.EnableInClassList(HiddenClassName, mainMenuPanel != activePanel);
|
mainMenuPanel.EnableInClassList(HiddenClassName, mainMenuPanel != activePanel);
|
||||||
collectionPanel.EnableInClassList(HiddenClassName, collectionPanel != activePanel);
|
collectionPanel.EnableInClassList(HiddenClassName, collectionPanel != activePanel);
|
||||||
|
runSetupPanel.EnableInClassList(HiddenClassName, runSetupPanel != activePanel);
|
||||||
gachaPanel.EnableInClassList(HiddenClassName, gachaPanel != activePanel);
|
gachaPanel.EnableInClassList(HiddenClassName, gachaPanel != activePanel);
|
||||||
settingsPanel.EnableInClassList(HiddenClassName, settingsPanel != activePanel);
|
settingsPanel.EnableInClassList(HiddenClassName, settingsPanel != activePanel);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
|
<ui:UXML xmlns:ui="UnityEngine.UIElements" xmlns:uie="UnityEditor.UIElements" editor-extension-mode="False">
|
||||||
<ui:VisualElement name="CollectionPanel" class="sub-panel hidden">
|
<ui:VisualElement name="CollectionPanel" class="sub-panel hidden">
|
||||||
<ui:Label text="COLLECTION" class="screen-title" />
|
<ui:Label text="COLLECTION" class="screen-title" />
|
||||||
|
<ui:VisualElement class="collection-actions">
|
||||||
|
<ui:Button name="CollectionUnitsButton" text="units" class="terminal-button collection-action-button" />
|
||||||
|
<ui:Button name="CollectionCardsButton" text="cards" class="terminal-button collection-action-button" />
|
||||||
|
</ui:VisualElement>
|
||||||
<ui:VisualElement name="CollectionContent" class="collection-shell">
|
<ui:VisualElement name="CollectionContent" class="collection-shell">
|
||||||
<ui:ScrollView name="CollectionList" class="collection-list" />
|
<ui:ScrollView name="CollectionList" class="collection-list" />
|
||||||
<ui:VisualElement name="CollectionDetail" class="collection-detail" />
|
<ui:VisualElement name="CollectionDetail" class="collection-detail" />
|
||||||
|
|||||||
@@ -481,6 +481,31 @@ Button {
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.collection-actions {
|
||||||
|
width: 760px;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collection-action-button {
|
||||||
|
width: 110px;
|
||||||
|
height: 34px;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collection-action-button.selected {
|
||||||
|
background-color: var(--kp-primary);
|
||||||
|
color: var(--kp-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.run-setup-hint {
|
||||||
|
width: 760px;
|
||||||
|
margin-top: -12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
.collection-list {
|
.collection-list {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
margin-right: 16px;
|
margin-right: 16px;
|
||||||
@@ -552,6 +577,82 @@ Button {
|
|||||||
margin-top: 14px;
|
margin-top: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.package-list {
|
||||||
|
margin-top: 18px;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-header {
|
||||||
|
color: var(--kp-muted);
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-notice {
|
||||||
|
color: var(--kp-amber);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
white-space: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-empty {
|
||||||
|
color: var(--kp-muted);
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-row {
|
||||||
|
min-width: 0;
|
||||||
|
padding: 7px 10px;
|
||||||
|
margin-top: 4px;
|
||||||
|
border-left-width: 2px;
|
||||||
|
border-left-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-row.selected,
|
||||||
|
.package-row.equipped {
|
||||||
|
border-left-color: var(--kp-primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-row.selected {
|
||||||
|
background-color: var(--kp-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-row.dimmed {
|
||||||
|
opacity: 0.45;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-summary {
|
||||||
|
min-width: 0;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-marker {
|
||||||
|
width: 34px;
|
||||||
|
min-width: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-name {
|
||||||
|
flex-grow: 1;
|
||||||
|
min-width: 0;
|
||||||
|
color: var(--kp-primary);
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
-unity-text-overflow-position: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-meta {
|
||||||
|
min-width: 96px;
|
||||||
|
color: var(--kp-muted);
|
||||||
|
-unity-text-align: upper-right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.package-description {
|
||||||
|
min-width: 0;
|
||||||
|
color: var(--kp-muted);
|
||||||
|
white-space: normal;
|
||||||
|
margin-left: 34px;
|
||||||
|
margin-top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
.modal-overlay {
|
.modal-overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
|
|||||||
@@ -124,6 +124,15 @@
|
|||||||
</ui:VisualElement>
|
</ui:VisualElement>
|
||||||
|
|
||||||
<ui:Instance template="CollectionScreen" />
|
<ui:Instance template="CollectionScreen" />
|
||||||
|
<ui:VisualElement name="RunSetupPanel" class="sub-panel hidden">
|
||||||
|
<ui:Label text="NEW RUN" class="screen-title" />
|
||||||
|
<ui:Label text="choose 4 distro cards before booting a run" class="collection-detail-muted run-setup-hint" />
|
||||||
|
<ui:VisualElement name="RunSetupContent" class="collection-shell">
|
||||||
|
<ui:ScrollView name="RunSetupList" class="collection-list" />
|
||||||
|
<ui:VisualElement name="RunSetupDetail" class="collection-detail" />
|
||||||
|
</ui:VisualElement>
|
||||||
|
<ui:Button name="RunSetupBackButton" text="Back" class="terminal-button back-button" />
|
||||||
|
</ui:VisualElement>
|
||||||
<ui:Instance template="GachaScreen" />
|
<ui:Instance template="GachaScreen" />
|
||||||
<ui:Instance template="SettingsScreen" />
|
<ui:Instance template="SettingsScreen" />
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user