Make multiple UX improvements in distro -> packages
This commit is contained in:
+61
-47
@@ -12,7 +12,9 @@
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="4222a6b8-add3-4f43-9c42-fd6bb5a76169" name="Changes" comment="">
|
||||
<change beforePath="$PROJECT_DIR$/.idea/.idea.linuxdistrosbuttheyarebreedable/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.linuxdistrosbuttheyarebreedable/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Run/RunManager.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Run/RunManager.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/UI/CollectionScreenController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/CollectionScreenController.cs" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/Assets/UI/MainMenu.uss" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/UI/MainMenu.uss" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -63,7 +65,10 @@
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Packages/CinnamonPackage.asset" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Packages/Make.asset" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Packages/SELinuxPackage.asset" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Packages/Sshd.asset" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Packages/Syslog.asset" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Packages/TimeshiftPackage.asset" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Packages/Vim.asset" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Packages/Wget.asset" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Passives/AptUpdate.asset" root0="FORCE_HIGHLIGHTING" />
|
||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Passives/BleedingEdge.asset" root0="FORCE_HIGHLIGHTING" />
|
||||
@@ -85,23 +90,23 @@
|
||||
<component name="MetaFilesCheckinStateConfiguration" checkMetaFiles="true" />
|
||||
<component name="NextEditCompletionFeaturesState">
|
||||
<decayedCancelled>
|
||||
<entry key="MS100" value="1.0000000091420684" />
|
||||
<entry key="MS500" value="1.0441151946756255" />
|
||||
<entry key="S2" value="2.6382509587349663" />
|
||||
<entry key="S5" value="6.4101924935144785" />
|
||||
<entry key="S10" value="10.713628057461193" />
|
||||
<entry key="S30" value="17.176849076864066" />
|
||||
<entry key="S60" value="19.771607581824814" />
|
||||
<entry key="M2" value="21.29576182445417" />
|
||||
<entry key="M5" value="22.295494182618757" />
|
||||
<entry key="M10" value="22.81448190885531" />
|
||||
<entry key="M15" value="24.09566128719646" />
|
||||
<entry key="M30" value="34.68797233141319" />
|
||||
<entry key="H1" value="97.44073884169883" />
|
||||
<entry key="H2" value="364.5207442228668" />
|
||||
<entry key="H4" value="873.7732173113925" />
|
||||
<entry key="D1" value="2984.8513999759525" />
|
||||
<entry key="W1" value="4680.673363994208" />
|
||||
<entry key="MS100" value="1.303475344688572" />
|
||||
<entry key="MS500" value="5.3926656022419355" />
|
||||
<entry key="S2" value="20.294425547037598" />
|
||||
<entry key="S5" value="46.02472779650448" />
|
||||
<entry key="S10" value="75.10224826080193" />
|
||||
<entry key="S30" value="116.756386597024" />
|
||||
<entry key="S60" value="132.70480982869236" />
|
||||
<entry key="M2" value="141.9955165492664" />
|
||||
<entry key="M5" value="157.16923502238322" />
|
||||
<entry key="M10" value="192.65306177401038" />
|
||||
<entry key="M15" value="222.3537750260655" />
|
||||
<entry key="M30" value="272.70669556712824" />
|
||||
<entry key="H1" value="314.3552276126616" />
|
||||
<entry key="H2" value="408.28563599020407" />
|
||||
<entry key="H4" value="741.98755653759" />
|
||||
<entry key="D1" value="2977.3514394521176" />
|
||||
<entry key="W1" value="4961.511940764881" />
|
||||
</decayedCancelled>
|
||||
<decayedSelected>
|
||||
<entry key="MS100" value="0.0" />
|
||||
@@ -111,35 +116,35 @@
|
||||
<entry key="S10" value="0.0" />
|
||||
<entry key="S30" value="0.0" />
|
||||
<entry key="S60" value="0.0" />
|
||||
<entry key="M2" value="1.8064028449327028E-281" />
|
||||
<entry key="M5" value="5.0434282114119077E-113" />
|
||||
<entry key="M10" value="7.101709802161887E-57" />
|
||||
<entry key="M15" value="3.6946668261839877E-38" />
|
||||
<entry key="M30" value="1.922152233062087E-19" />
|
||||
<entry key="H1" value="4.3885451429904854E-10" />
|
||||
<entry key="H2" value="2.2075675211666528E-5" />
|
||||
<entry key="H4" value="0.0064228401094546346" />
|
||||
<entry key="D1" value="1.2824600455938682" />
|
||||
<entry key="W1" value="3.3954284700737616" />
|
||||
<entry key="M2" value="3.0E-323" />
|
||||
<entry key="M5" value="9.244545133631687E-130" />
|
||||
<entry key="M10" value="3.0404843583929786E-65" />
|
||||
<entry key="M15" value="9.74156013306164E-44" />
|
||||
<entry key="M30" value="3.121148251945742E-22" />
|
||||
<entry key="H1" value="1.7684137325623194E-11" />
|
||||
<entry key="H2" value="4.431447925314597E-6" />
|
||||
<entry key="H4" value="0.0028776829122893056" />
|
||||
<entry key="D1" value="1.1218371428837055" />
|
||||
<entry key="W1" value="3.3311376701614477" />
|
||||
</decayedSelected>
|
||||
<decayedShown>
|
||||
<entry key="MS100" value="3.677094450878252E-7" />
|
||||
<entry key="MS500" value="0.09520385707309299" />
|
||||
<entry key="S2" value="2.109440495603316" />
|
||||
<entry key="S5" value="6.132967162270056" />
|
||||
<entry key="S10" value="10.54895965976181" />
|
||||
<entry key="S30" value="17.11109977886081" />
|
||||
<entry key="S60" value="19.73679418591952" />
|
||||
<entry key="M2" value="21.277810332230633" />
|
||||
<entry key="M5" value="22.28817422032284" />
|
||||
<entry key="M10" value="22.810795720477756" />
|
||||
<entry key="M15" value="24.093188404100633" />
|
||||
<entry key="M30" value="34.68668997617844" />
|
||||
<entry key="H1" value="97.43998942892169" />
|
||||
<entry key="H2" value="364.5201803453728" />
|
||||
<entry key="H4" value="873.7791451545606" />
|
||||
<entry key="D1" value="2986.1335377085343" />
|
||||
<entry key="W1" value="4684.068708897457" />
|
||||
<entry key="MS100" value="1.2566545459762934" />
|
||||
<entry key="MS500" value="5.351173370423456" />
|
||||
<entry key="S2" value="20.255413709804333" />
|
||||
<entry key="S5" value="45.988601609033005" />
|
||||
<entry key="S10" value="75.07245405372439" />
|
||||
<entry key="S30" value="116.74083732450484" />
|
||||
<entry key="S60" value="132.69595850502105" />
|
||||
<entry key="M2" value="141.99077691444745" />
|
||||
<entry key="M5" value="157.16712437698786" />
|
||||
<entry key="M10" value="192.65174658978927" />
|
||||
<entry key="M15" value="222.35275187576812" />
|
||||
<entry key="M30" value="272.7060572994754" />
|
||||
<entry key="H1" value="314.3548323813724" />
|
||||
<entry key="H2" value="408.2853250098047" />
|
||||
<entry key="H4" value="741.9901088328525" />
|
||||
<entry key="D1" value="2978.472976582466" />
|
||||
<entry key="W1" value="4964.842993847027" />
|
||||
</decayedShown>
|
||||
</component>
|
||||
<component name="ProjectColorInfo">{
|
||||
@@ -231,7 +236,7 @@
|
||||
<workItem from="1783410502976" duration="23430000" />
|
||||
<workItem from="1783507489679" duration="5909000" />
|
||||
<workItem from="1783519887449" duration="6425000" />
|
||||
<workItem from="1783578446731" duration="5754000" />
|
||||
<workItem from="1783578446731" duration="14988000" />
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="implement main screen">
|
||||
<option name="closed" value="true" />
|
||||
@@ -433,7 +438,15 @@
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1783585107215</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="26" />
|
||||
<task id="LOCAL-00026" summary="restructure packages (it looks shit)">
|
||||
<option name="closed" value="true" />
|
||||
<created>1783585689781</created>
|
||||
<option name="number" value="00026" />
|
||||
<option name="presentableId" value="LOCAL-00026" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1783585689781</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="27" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
@@ -473,7 +486,8 @@
|
||||
<MESSAGE value="Implement Java and Rust cards alongside some smaller changes" />
|
||||
<MESSAGE value="make small changes to design. Implement crits." />
|
||||
<MESSAGE value="Implement many UX improvements, packages and their assets and a UI overhaul in collection" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="Implement many UX improvements, packages and their assets and a UI overhaul in collection" />
|
||||
<MESSAGE value="restructure packages (it looks shit)" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="restructure packages (it looks shit)" />
|
||||
</component>
|
||||
<component name="XDebuggerManager">
|
||||
<breakpoint-manager>
|
||||
|
||||
@@ -191,35 +191,50 @@ namespace KernelPanic.Run
|
||||
return Mathf.Max(1, (CurrentConfig?.Distro?.BaseCyclesPerTurn ?? 1) + maxCyclesBonus + packageMaxCyclesBonus);
|
||||
}
|
||||
|
||||
private void ApplyKernelPackageBonuses(RunConfig config)
|
||||
public static PackageStatImpact CalculatePackageStatImpact(DistroDefinition distro, IReadOnlyList<PackageInstance> packages)
|
||||
{
|
||||
if (config?.EquippedPackages == null)
|
||||
PackageStatImpact impact = new(
|
||||
Mathf.Max(1, distro == null ? 1 : distro.BaseUptime),
|
||||
Mathf.Max(1, distro == null ? 1 : distro.BaseRam),
|
||||
Mathf.Max(1, distro == null ? 1 : distro.BaseCyclesPerTurn));
|
||||
if (packages == null)
|
||||
{
|
||||
return;
|
||||
return impact;
|
||||
}
|
||||
|
||||
for (int i = 0; i < config.EquippedPackages.Count; i++)
|
||||
for (int i = 0; i < packages.Count; i++)
|
||||
{
|
||||
PackageInstance package = config.EquippedPackages[i];
|
||||
PackageInstance package = packages[i];
|
||||
if (package?.Definition == null || package.Definition.Slot != PackageSlot.Kernel)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
PackageEffectData effect = package.EffectFor(config.Distro?.Id);
|
||||
PackageEffectData effect = package.EffectFor(distro?.Id);
|
||||
int amount = Mathf.Max(0, effect.Amount);
|
||||
switch (effect.Kind)
|
||||
{
|
||||
case PackageEffectKind.MaxUptime:
|
||||
packageMaxUptimeBonus += Mathf.Max(0, effect.Amount);
|
||||
impact.AddUptime(amount, package.Definition);
|
||||
break;
|
||||
case PackageEffectKind.MaxCycles:
|
||||
packageMaxCyclesBonus += Mathf.Max(0, effect.Amount);
|
||||
impact.AddCycles(amount, package.Definition);
|
||||
break;
|
||||
case PackageEffectKind.MaxRam:
|
||||
packageRamBonus += Mathf.Max(0, effect.Amount);
|
||||
impact.AddRam(amount, package.Definition);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return impact;
|
||||
}
|
||||
|
||||
private void ApplyKernelPackageBonuses(RunConfig config)
|
||||
{
|
||||
PackageStatImpact impact = CalculatePackageStatImpact(config?.Distro, config?.EquippedPackages);
|
||||
packageMaxUptimeBonus = impact.UptimeBonus;
|
||||
packageMaxCyclesBonus = impact.CyclesBonus;
|
||||
packageRamBonus = impact.RamBonus;
|
||||
}
|
||||
|
||||
public bool TrySettleRunRewards(out int bandwidth, out int entropy)
|
||||
@@ -507,4 +522,79 @@ namespace KernelPanic.Run
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct PackageStatImpact
|
||||
{
|
||||
private readonly List<string> uptimeSources;
|
||||
private readonly List<string> ramSources;
|
||||
private readonly List<string> cyclesSources;
|
||||
|
||||
public PackageStatImpact(int baseUptime, int baseRam, int baseCycles)
|
||||
{
|
||||
BaseUptime = baseUptime;
|
||||
BaseRam = baseRam;
|
||||
BaseCycles = baseCycles;
|
||||
UptimeBonus = 0;
|
||||
RamBonus = 0;
|
||||
CyclesBonus = 0;
|
||||
uptimeSources = new List<string>();
|
||||
ramSources = new List<string>();
|
||||
cyclesSources = new List<string>();
|
||||
}
|
||||
|
||||
public int BaseUptime { get; }
|
||||
public int BaseRam { get; }
|
||||
public int BaseCycles { get; }
|
||||
public int UptimeBonus { get; private set; }
|
||||
public int RamBonus { get; private set; }
|
||||
public int CyclesBonus { get; private set; }
|
||||
public int FinalUptime => Mathf.Max(1, BaseUptime + UptimeBonus);
|
||||
public int FinalRam => Mathf.Max(1, BaseRam + RamBonus);
|
||||
public int FinalCycles => Mathf.Max(1, BaseCycles + CyclesBonus);
|
||||
public IReadOnlyList<string> UptimeSources => uptimeSources;
|
||||
public IReadOnlyList<string> RamSources => ramSources;
|
||||
public IReadOnlyList<string> CyclesSources => cyclesSources;
|
||||
|
||||
public void AddUptime(int amount, PackageDefinition source)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
UptimeBonus += amount;
|
||||
AddSource(source, uptimeSources);
|
||||
}
|
||||
|
||||
public void AddRam(int amount, PackageDefinition source)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
RamBonus += amount;
|
||||
AddSource(source, ramSources);
|
||||
}
|
||||
|
||||
public void AddCycles(int amount, PackageDefinition source)
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CyclesBonus += amount;
|
||||
AddSource(source, cyclesSources);
|
||||
}
|
||||
|
||||
private static void AddSource(PackageDefinition source, List<string> sources)
|
||||
{
|
||||
string name = source == null ? null : string.IsNullOrWhiteSpace(source.DisplayName) ? source.Id : source.DisplayName;
|
||||
if (!string.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
sources.Add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using KernelPanic.Core;
|
||||
using KernelPanic.Data;
|
||||
using KernelPanic.Meta;
|
||||
using KernelPanic.Run;
|
||||
using UnityEngine;
|
||||
using UnityEngine.TextCore.Text;
|
||||
using UnityEngine.UIElements;
|
||||
@@ -20,6 +21,9 @@ namespace KernelPanic.UI
|
||||
private VisualElement _list;
|
||||
private ScrollView _detailScroll;
|
||||
private VisualElement _detail;
|
||||
private VisualElement _root;
|
||||
private VisualElement _packageEquipOverlay;
|
||||
private VisualElement _packageEquipDialog;
|
||||
private FontAsset _monospaceFont;
|
||||
private LanguageDeckDatabase _languageDeckDatabase;
|
||||
private CardDatabase _cardDatabase;
|
||||
@@ -40,11 +44,14 @@ namespace KernelPanic.UI
|
||||
private UnitDetailTab _unitDetailTab = UnitDetailTab.Overview;
|
||||
private PackageSlot? _packagePickerSlot;
|
||||
private bool _unitDetailReturnsToOverview = true;
|
||||
private DistroDefinition _equipWindowUnit;
|
||||
private PackageSlot _equipWindowSlot;
|
||||
private int _selectedUnitIndex;
|
||||
private int _selectedLanguageIndex;
|
||||
private int _selectedCardIndex;
|
||||
private string _emptyCardMessage = "no cards installed";
|
||||
private string _pendingScrapPackageId;
|
||||
private string _packageSlotNotice;
|
||||
private IReadOnlyList<OwnedPackageInstance> _packageInventory = Array.Empty<OwnedPackageInstance>();
|
||||
private int _selectedPackageInventoryIndex;
|
||||
private PackageSlot? _packageInventoryFilter;
|
||||
@@ -54,6 +61,7 @@ namespace KernelPanic.UI
|
||||
public void Bind(VisualElement root, FontAsset artFont, LanguageDeckDatabase deckDatabase, CardDatabase cardsDatabase, PlayerCollection collection, Func<DistroDefinition, int> getMergesBalance = null, Func<DistroDefinition, VersionUpgradeResult> tryUpgradeUnit = null, PackageDatabase packageDatabase = null, PackageLoadout packageLoadout = null, Action packageLoadoutChanged = null, Func<SaveData> getSaveData = null, Func<OwnedPackageInstance, PackageUpgradeResult> tryUpgradePackage = null, Func<OwnedPackageInstance, PackageScrapResult> tryScrapPackage = null)
|
||||
{
|
||||
_monospaceFont = artFont;
|
||||
_root = root;
|
||||
_languageDeckDatabase = deckDatabase;
|
||||
_cardDatabase = cardsDatabase;
|
||||
_playerCollection = collection;
|
||||
@@ -68,6 +76,7 @@ namespace KernelPanic.UI
|
||||
_list = root.Q<VisualElement>("CollectionList");
|
||||
_detailScroll = root.Q<ScrollView>("CollectionDetail");
|
||||
_detail = _detailScroll?.contentContainer;
|
||||
EnsurePackageEquipOverlay();
|
||||
}
|
||||
|
||||
public bool IsCardSubview => _mode == CollectionMode.CardSubview;
|
||||
@@ -85,6 +94,7 @@ namespace KernelPanic.UI
|
||||
|
||||
public void ShowUnits()
|
||||
{
|
||||
ClosePackageEquipWindow();
|
||||
_mode = CollectionMode.Units;
|
||||
CurrentTitle = "$ ls ~/collection";
|
||||
CurrentHint = "[esc] back [left/right] tabs [tab] tabs [arrows] navigate [enter] select";
|
||||
@@ -94,6 +104,7 @@ namespace KernelPanic.UI
|
||||
|
||||
public void ShowLanguages()
|
||||
{
|
||||
ClosePackageEquipWindow();
|
||||
_mode = CollectionMode.Languages;
|
||||
CurrentTitle = "$ ls ~/collection/languages";
|
||||
CurrentHint = "[esc] back [left/right] tabs [tab] tabs [arrows] navigate [enter] select";
|
||||
@@ -103,6 +114,7 @@ namespace KernelPanic.UI
|
||||
|
||||
public void ShowPackages()
|
||||
{
|
||||
ClosePackageEquipWindow();
|
||||
_mode = CollectionMode.Packages;
|
||||
_pendingScrapPackageId = null;
|
||||
CurrentTitle = "$ ls ~/packages";
|
||||
@@ -113,9 +125,16 @@ namespace KernelPanic.UI
|
||||
|
||||
public bool BackFromSubview()
|
||||
{
|
||||
if (_packageEquipOverlay != null && !_packageEquipOverlay.ClassListContains("hidden"))
|
||||
{
|
||||
ClosePackageEquipWindow();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_mode == CollectionMode.UnitDetail)
|
||||
{
|
||||
_packagePickerSlot = null;
|
||||
_packageSlotNotice = null;
|
||||
if (_unitDetailReturnsToOverview)
|
||||
{
|
||||
ShowUnits();
|
||||
@@ -201,8 +220,7 @@ namespace KernelPanic.UI
|
||||
break;
|
||||
case UnitDetailTab.Packages:
|
||||
_packagePickerSlot ??= PackageSlot.Kernel;
|
||||
RenderUnitDetail(unit);
|
||||
ViewChanged?.Invoke();
|
||||
OpenPackageEquipWindow(unit, _packagePickerSlot.Value);
|
||||
break;
|
||||
case UnitDetailTab.Cards:
|
||||
OpenUnitCards(unit);
|
||||
@@ -221,6 +239,7 @@ namespace KernelPanic.UI
|
||||
int count = Enum.GetValues(typeof(UnitDetailTab)).Length;
|
||||
_unitDetailTab = (UnitDetailTab)(((int)_unitDetailTab + delta + count) % count);
|
||||
_packagePickerSlot = null;
|
||||
_packageSlotNotice = null;
|
||||
RenderUnitDetail(_units[_selectedUnitIndex]);
|
||||
ViewChanged?.Invoke();
|
||||
}
|
||||
@@ -778,6 +797,7 @@ namespace KernelPanic.UI
|
||||
{
|
||||
_unitDetailTab = UnitDetailTab.Overview;
|
||||
_packagePickerSlot = null;
|
||||
_packageSlotNotice = null;
|
||||
}
|
||||
|
||||
_unitDetailReturnsToOverview = returnToOverview;
|
||||
@@ -872,6 +892,7 @@ namespace KernelPanic.UI
|
||||
{
|
||||
_unitDetailTab = tab;
|
||||
_packagePickerSlot = null;
|
||||
_packageSlotNotice = null;
|
||||
RenderUnitDetail(unit);
|
||||
ViewChanged?.Invoke();
|
||||
})
|
||||
@@ -944,27 +965,22 @@ namespace KernelPanic.UI
|
||||
Label title = new("packages");
|
||||
title.AddToClassList("detail-section-title");
|
||||
target.Add(title);
|
||||
SaveData saveData = _getSaveData?.Invoke();
|
||||
int cache = Math.Max(0, saveData?.cacheBalance ?? 0);
|
||||
int bandwidth = Math.Max(0, saveData?.bandwidthBalance ?? 0);
|
||||
_packagePickerSlot ??= PackageSlot.Kernel;
|
||||
|
||||
VisualElement layout = new();
|
||||
layout.AddToClassList("packages-master-detail");
|
||||
layout.AddToClassList("packages-summary-layout");
|
||||
|
||||
VisualElement slots = new();
|
||||
slots.AddToClassList("packages-slot-list");
|
||||
slots.Add(BuildDetailLine("wallet", $"Cache={cache} Bandwidth={bandwidth}"));
|
||||
AddPackageSlotSummaryRow(slots, unit, PackageSlot.Kernel);
|
||||
AddPackageSlotSummaryRow(slots, unit, PackageSlot.Runtime);
|
||||
AddPackageSlotSummaryRow(slots, unit, PackageSlot.Daemon);
|
||||
layout.Add(slots);
|
||||
|
||||
VisualElement detail = new();
|
||||
detail.AddToClassList("packages-detail-panel");
|
||||
AddSelectedPackageSlotActions(detail, unit, _packagePickerSlot.Value, cache, bandwidth);
|
||||
AddPackagePicker(detail, unit, _packagePickerSlot.Value);
|
||||
layout.Add(detail);
|
||||
VisualElement impact = new();
|
||||
impact.AddToClassList("packages-impact-panel");
|
||||
AddPackageStatImpactPanel(impact, unit);
|
||||
layout.Add(impact);
|
||||
target.Add(layout);
|
||||
}
|
||||
|
||||
@@ -978,9 +994,20 @@ namespace KernelPanic.UI
|
||||
row.RegisterCallback<ClickEvent>(_ =>
|
||||
{
|
||||
_packagePickerSlot = slot;
|
||||
RenderUnitDetail(unit);
|
||||
ViewChanged?.Invoke();
|
||||
_packageSlotNotice = null;
|
||||
OpenPackageEquipWindow(unit, slot);
|
||||
});
|
||||
row.RegisterCallback<KeyDownEvent>(evt =>
|
||||
{
|
||||
if (evt.keyCode == KeyCode.Return || evt.keyCode == KeyCode.KeypadEnter)
|
||||
{
|
||||
_packagePickerSlot = slot;
|
||||
_packageSlotNotice = null;
|
||||
OpenPackageEquipWindow(unit, slot);
|
||||
evt.StopPropagation();
|
||||
}
|
||||
});
|
||||
row.focusable = true;
|
||||
|
||||
Label slotLabel = new(slot.ToString().ToUpperInvariant());
|
||||
slotLabel.AddToClassList("package-slot-label");
|
||||
@@ -1011,9 +1038,100 @@ namespace KernelPanic.UI
|
||||
Label effect = new(equipped == null ? string.Empty : OneLineEffect(equipped, owned?.UpgradeLevel ?? 0, unit.Id));
|
||||
effect.AddToClassList("package-slot-effect");
|
||||
row.Add(effect);
|
||||
|
||||
Label action = new("[enter] equip");
|
||||
action.AddToClassList("package-slot-action");
|
||||
row.Add(action);
|
||||
target.Add(row);
|
||||
}
|
||||
|
||||
private void AddPackageStatImpactPanel(VisualElement target, DistroDefinition unit)
|
||||
{
|
||||
Label title = new("stat impact");
|
||||
title.AddToClassList("detail-section-title");
|
||||
target.Add(title);
|
||||
|
||||
IReadOnlyList<PackageInstance> packages = _packageLoadout.GetEquippedPackageInstances(unit.Id);
|
||||
PackageStatImpact impact = RunManager.CalculatePackageStatImpact(unit, packages);
|
||||
target.Add(BuildStatImpactLine("Uptime", impact.BaseUptime, impact.FinalUptime, impact.UptimeBonus, impact.UptimeSources));
|
||||
target.Add(BuildStatImpactLine("RAM", impact.BaseRam, impact.FinalRam, impact.RamBonus, impact.RamSources));
|
||||
target.Add(BuildStatImpactLine("Cycles", impact.BaseCycles, impact.FinalCycles, impact.CyclesBonus, impact.CyclesSources));
|
||||
|
||||
VisualElement active = new();
|
||||
active.AddToClassList("packages-active-effects");
|
||||
Label activeTitle = new("active effects");
|
||||
activeTitle.AddToClassList("detail-section-title");
|
||||
active.Add(activeTitle);
|
||||
|
||||
int count = 0;
|
||||
AddActivePackageEffect(active, unit, PackageSlot.Kernel, ref count);
|
||||
AddActivePackageEffect(active, unit, PackageSlot.Runtime, ref count);
|
||||
AddActivePackageEffect(active, unit, PackageSlot.Daemon, ref count);
|
||||
if (count == 0)
|
||||
{
|
||||
Label empty = new("none");
|
||||
empty.AddToClassList("collection-detail-muted");
|
||||
active.Add(empty);
|
||||
}
|
||||
|
||||
target.Add(active);
|
||||
}
|
||||
|
||||
private VisualElement BuildStatImpactLine(string label, int before, int after, int delta, IReadOnlyList<string> sources)
|
||||
{
|
||||
VisualElement row = new();
|
||||
row.AddToClassList("package-stat-line");
|
||||
Label key = new(label);
|
||||
key.AddToClassList("package-stat-key");
|
||||
Label values = new($"{before} -> {after}");
|
||||
values.AddToClassList("package-stat-value");
|
||||
Label bonus = new(delta > 0 ? $"(+{delta}{FormatSources(sources)})" : string.Empty);
|
||||
bonus.AddToClassList("package-stat-bonus");
|
||||
row.Add(key);
|
||||
row.Add(values);
|
||||
row.Add(bonus);
|
||||
return row;
|
||||
}
|
||||
|
||||
private void AddActivePackageEffect(VisualElement target, DistroDefinition unit, PackageSlot slot, ref int count)
|
||||
{
|
||||
PackageDefinition package = _packageLoadout.GetEquippedPackage(unit.Id, slot);
|
||||
OwnedPackageInstance owned = package == null ? null : _playerCollection.GetOwnedPackage(package.Id);
|
||||
if (package == null || owned == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
PackageEffectData effect = package.EffectFor(unit.Id);
|
||||
if (package.Slot == PackageSlot.Kernel && IsStatPackageEffect(effect.Kind))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
string summary = OneLineEffect(package, owned.UpgradeLevel, unit.Id);
|
||||
if (string.IsNullOrWhiteSpace(summary))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Label line = new($"{PackageName(package)}: {summary}");
|
||||
line.AddToClassList("package-active-effect");
|
||||
target.Add(line);
|
||||
count++;
|
||||
}
|
||||
|
||||
private static bool IsStatPackageEffect(PackageEffectKind kind)
|
||||
{
|
||||
return kind == PackageEffectKind.MaxUptime
|
||||
|| kind == PackageEffectKind.MaxRam
|
||||
|| kind == PackageEffectKind.MaxCycles;
|
||||
}
|
||||
|
||||
private static string FormatSources(IReadOnlyList<string> sources)
|
||||
{
|
||||
return sources == null || sources.Count == 0 ? string.Empty : $", {string.Join(", ", sources)}";
|
||||
}
|
||||
|
||||
private void AddSelectedPackageSlotActions(VisualElement target, DistroDefinition unit, PackageSlot slot, int cache, int bandwidth)
|
||||
{
|
||||
PackageDefinition equipped = _packageLoadout.GetEquippedPackage(unit.Id, slot);
|
||||
@@ -1021,6 +1139,13 @@ namespace KernelPanic.UI
|
||||
Label title = new($"{slot.ToString().ToLowerInvariant()} actions");
|
||||
title.AddToClassList("detail-section-title");
|
||||
target.Add(title);
|
||||
if (!string.IsNullOrWhiteSpace(_packageSlotNotice))
|
||||
{
|
||||
Label notice = new(_packageSlotNotice);
|
||||
notice.AddToClassList("package-notice");
|
||||
notice.AddToClassList("package-slot-notice");
|
||||
target.Add(notice);
|
||||
}
|
||||
|
||||
if (owned == null || equipped == null)
|
||||
{
|
||||
@@ -1030,7 +1155,6 @@ namespace KernelPanic.UI
|
||||
}
|
||||
|
||||
target.Add(BuildDetailLine("level", $"Lv {owned.UpgradeLevel}/{PackageTuning.MaxPackageLevel}"));
|
||||
target.Add(BuildDetailLine("current", FormatPackageEffect(equipped, owned.UpgradeLevel, unit.Id)));
|
||||
|
||||
int nextLevel = owned.UpgradeLevel + 1;
|
||||
bool maxLevel = owned.UpgradeLevel >= PackageTuning.MaxPackageLevel;
|
||||
@@ -1038,10 +1162,10 @@ namespace KernelPanic.UI
|
||||
int bandwidthCost = maxLevel ? 0 : PackageTuning.GetUpgradeBandwidthCost(nextLevel, equipped.Rarity);
|
||||
bool canUpgrade = !maxLevel && cache >= cacheCost && bandwidth >= bandwidthCost && _tryUpgradePackage != null;
|
||||
string upgradeState = maxLevel ? "max level" : cache < cacheCost ? "insufficient cache" : bandwidth < bandwidthCost ? "insufficient bandwidth" : "ready";
|
||||
string nextPreview = maxLevel
|
||||
? "max level reached"
|
||||
: $"{FormatPackageEffect(equipped, owned.UpgradeLevel, unit.Id)} -> {FormatPackageEffect(equipped, nextLevel, unit.Id)}";
|
||||
target.Add(BuildDetailLine("next", nextPreview));
|
||||
string currentEffect = FormatPackageEffect(equipped, owned.UpgradeLevel, unit.Id);
|
||||
string nextPreview = maxLevel ? "max level reached" : $"{currentEffect} -> {FormatPackageEffect(equipped, nextLevel, unit.Id)}";
|
||||
target.Add(BuildPackagePreviewLine("current", currentEffect));
|
||||
target.Add(BuildPackagePreviewLine("next", nextPreview));
|
||||
target.Add(BuildCompactUpgradeCommand($"> make upgrade (Cache {cacheCost} / Bandwidth {bandwidthCost})", upgradeState, canUpgrade, () => UpgradePackage(owned)));
|
||||
}
|
||||
|
||||
@@ -1061,8 +1185,10 @@ namespace KernelPanic.UI
|
||||
}
|
||||
|
||||
bool isEquipped = equipped != null && string.Equals(equipped.Id, package.Id, StringComparison.OrdinalIgnoreCase);
|
||||
int packageLevel = _playerCollection.GetOwnedPackage(package.Id)?.UpgradeLevel ?? 0;
|
||||
VisualElement row = new();
|
||||
row.AddToClassList("package-row");
|
||||
row.AddToClassList("package-picker-row");
|
||||
row.EnableInClassList("equipped", isEquipped);
|
||||
row.EnableInClassList($"rarity-{package.Rarity}", true);
|
||||
row.RegisterCallback<ClickEvent>(_ => TogglePackage(unit, slot, package, isEquipped));
|
||||
@@ -1073,33 +1199,25 @@ namespace KernelPanic.UI
|
||||
marker.AddToClassList("package-marker");
|
||||
Label name = new(PackageName(package));
|
||||
name.AddToClassList("package-name");
|
||||
Label meta = new($"{package.Rarity}* / {package.Slot}");
|
||||
Label effect = new(OneLineEffect(package, packageLevel, unit.Id));
|
||||
effect.AddToClassList("package-picker-effect");
|
||||
Label meta = new(package.IsIntendedFor(unit.Id) ? $"{package.Rarity}* on" : $"{package.Rarity}*");
|
||||
meta.AddToClassList("package-meta");
|
||||
summary.Add(marker);
|
||||
summary.Add(name);
|
||||
summary.Add(effect);
|
||||
summary.Add(meta);
|
||||
row.Add(summary);
|
||||
|
||||
Label description = new(package.Description);
|
||||
description.AddToClassList("package-description");
|
||||
row.Add(description);
|
||||
|
||||
if (package.IsIntendedFor(unit.Id))
|
||||
{
|
||||
Label intended = new("on-distro");
|
||||
intended.AddToClassList("package-notice");
|
||||
row.Add(intended);
|
||||
}
|
||||
|
||||
target.Add(row);
|
||||
}
|
||||
}
|
||||
|
||||
private void TogglePackage(DistroDefinition unit, PackageSlot slot, PackageDefinition package, bool isEquipped)
|
||||
private bool TogglePackage(DistroDefinition unit, PackageSlot slot, PackageDefinition package, bool isEquipped)
|
||||
{
|
||||
if (unit == null || package == null || _packageLoadout == null)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
PackageLoadoutFailureReason reason;
|
||||
@@ -1109,14 +1227,240 @@ namespace KernelPanic.UI
|
||||
|
||||
if (changed)
|
||||
{
|
||||
_packageSlotNotice = null;
|
||||
_packageLoadoutChanged?.Invoke();
|
||||
}
|
||||
|
||||
RenderUnitDetail(unit);
|
||||
if (!changed)
|
||||
{
|
||||
_detail.Add(BuildDetailLine("package", FormatPackageFailure(reason)));
|
||||
_packageSlotNotice = FormatPackageFailure(reason);
|
||||
}
|
||||
|
||||
RenderUnitDetail(unit);
|
||||
return changed;
|
||||
}
|
||||
|
||||
private void EnsurePackageEquipOverlay()
|
||||
{
|
||||
if (_root == null || _packageEquipOverlay != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_packageEquipOverlay = new VisualElement();
|
||||
_packageEquipOverlay.AddToClassList("modal-overlay");
|
||||
_packageEquipOverlay.AddToClassList("package-equip-overlay");
|
||||
_packageEquipOverlay.AddToClassList("hidden");
|
||||
_packageEquipDialog = new VisualElement();
|
||||
_packageEquipDialog.AddToClassList("package-equip-dialog");
|
||||
_packageEquipOverlay.Add(_packageEquipDialog);
|
||||
_root.Add(_packageEquipOverlay);
|
||||
}
|
||||
|
||||
private void OpenPackageEquipWindow(DistroDefinition unit, PackageSlot slot)
|
||||
{
|
||||
if (unit == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
EnsurePackageEquipOverlay();
|
||||
_equipWindowUnit = unit;
|
||||
_equipWindowSlot = slot;
|
||||
_packageSlotNotice = null;
|
||||
RenderPackageEquipWindow();
|
||||
_packageEquipOverlay.RemoveFromClassList("hidden");
|
||||
_packageEquipOverlay.AddToClassList("modal-open");
|
||||
}
|
||||
|
||||
private void ClosePackageEquipWindow()
|
||||
{
|
||||
_packageEquipOverlay?.RemoveFromClassList("modal-open");
|
||||
_packageEquipOverlay?.AddToClassList("hidden");
|
||||
_equipWindowUnit = null;
|
||||
_packageSlotNotice = null;
|
||||
}
|
||||
|
||||
private void RenderPackageEquipWindow()
|
||||
{
|
||||
if (_packageEquipDialog == null || _equipWindowUnit == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_packageEquipDialog.Clear();
|
||||
PackageDefinition equipped = _packageLoadout.GetEquippedPackage(_equipWindowUnit.Id, _equipWindowSlot);
|
||||
|
||||
VisualElement header = new();
|
||||
header.AddToClassList("package-equip-header");
|
||||
Label title = new($"equip: {_equipWindowSlot.ToString().ToLowerInvariant()} - {DistroPresentation.DisplayName(_equipWindowUnit)}");
|
||||
title.AddToClassList("collection-detail-name");
|
||||
title.style.color = new StyleColor(_equipWindowUnit.AccentColor);
|
||||
header.Add(title);
|
||||
Button close = new(ClosePackageEquipWindow) { text = "x", focusable = false };
|
||||
close.AddToClassList("modal-close-button");
|
||||
header.Add(close);
|
||||
_packageEquipDialog.Add(header);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(_packageSlotNotice))
|
||||
{
|
||||
Label notice = new(_packageSlotNotice);
|
||||
notice.AddToClassList("package-notice");
|
||||
_packageEquipDialog.Add(notice);
|
||||
}
|
||||
|
||||
string equippedName = equipped == null ? "empty" : PackageName(equipped);
|
||||
_packageEquipDialog.Add(BuildDetailLine("current", equippedName));
|
||||
if (equipped != null)
|
||||
{
|
||||
_packageEquipDialog.Add(BuildCompactUpgradeCommand("> unlink current", "unequip", true, () => UnequipPackageFromWindow(_equipWindowUnit, _equipWindowSlot)));
|
||||
}
|
||||
|
||||
ScrollView list = new(ScrollViewMode.Vertical);
|
||||
list.AddToClassList("package-equip-list");
|
||||
int count = 0;
|
||||
for (int i = 0; i < _playerCollection.OwnedPackageInstances.Count; i++)
|
||||
{
|
||||
OwnedPackageInstance owned = _playerCollection.OwnedPackageInstances[i];
|
||||
PackageDefinition package = owned?.Definition;
|
||||
if (package == null || package.Slot != _equipWindowSlot)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
list.Add(BuildEquipWindowPackageRow(owned, equipped));
|
||||
count++;
|
||||
}
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
Label empty = new($"no owned {_equipWindowSlot.ToString().ToLowerInvariant()} packages");
|
||||
empty.AddToClassList("package-empty");
|
||||
list.Add(empty);
|
||||
}
|
||||
|
||||
_packageEquipDialog.Add(list);
|
||||
_packageEquipDialog.Add(BuildCompactUpgradeCommand("> cancel", "back", true, ClosePackageEquipWindow));
|
||||
}
|
||||
|
||||
private VisualElement BuildEquipWindowPackageRow(OwnedPackageInstance owned, PackageDefinition equipped)
|
||||
{
|
||||
PackageDefinition package = owned.Definition;
|
||||
bool isEquippedHere = equipped != null && string.Equals(equipped.Id, package.Id, StringComparison.OrdinalIgnoreCase);
|
||||
VisualElement row = new();
|
||||
row.AddToClassList("package-row");
|
||||
row.AddToClassList("package-equip-row");
|
||||
row.EnableInClassList("equipped", isEquippedHere);
|
||||
row.EnableInClassList($"rarity-{package.Rarity}", true);
|
||||
row.EnableInClassList("on-distro", package.IsIntendedFor(_equipWindowUnit.Id));
|
||||
row.RegisterCallback<ClickEvent>(_ => EquipPackageFromWindow(_equipWindowUnit, _equipWindowSlot, package, isEquippedHere));
|
||||
|
||||
VisualElement summary = new();
|
||||
summary.AddToClassList("package-summary");
|
||||
Label marker = new(isEquippedHere ? "[x]" : "[ ]");
|
||||
marker.AddToClassList("package-marker");
|
||||
Label name = new(PackageName(package));
|
||||
name.AddToClassList("package-name");
|
||||
Label meta = new($"{RarityPresentation.ForStars(package.Rarity).Badge} Lv {owned.UpgradeLevel}/{PackageTuning.MaxPackageLevel}");
|
||||
meta.AddToClassList("package-meta");
|
||||
summary.Add(marker);
|
||||
summary.Add(name);
|
||||
summary.Add(meta);
|
||||
row.Add(summary);
|
||||
|
||||
Label effect = new(FormatPackageEffect(package, owned.UpgradeLevel, _equipWindowUnit.Id));
|
||||
effect.AddToClassList("package-description");
|
||||
row.Add(effect);
|
||||
|
||||
VisualElement tags = new();
|
||||
tags.AddToClassList("package-equip-tags");
|
||||
string equippedOn = FindEquippedDistroName(package.Id);
|
||||
if (!string.IsNullOrWhiteSpace(equippedOn))
|
||||
{
|
||||
Label equippedTag = new($"equipped on {equippedOn}");
|
||||
equippedTag.AddToClassList("package-notice");
|
||||
tags.Add(equippedTag);
|
||||
}
|
||||
|
||||
if (package.IsIntendedFor(_equipWindowUnit.Id))
|
||||
{
|
||||
Label intended = new("on-distro");
|
||||
intended.AddToClassList("package-notice");
|
||||
tags.Add(intended);
|
||||
}
|
||||
|
||||
if (tags.childCount > 0)
|
||||
{
|
||||
row.Add(tags);
|
||||
}
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
private void EquipPackageFromWindow(DistroDefinition unit, PackageSlot slot, PackageDefinition package, bool isEquipped)
|
||||
{
|
||||
if (isEquipped)
|
||||
{
|
||||
UnequipPackageFromWindow(unit, slot);
|
||||
return;
|
||||
}
|
||||
|
||||
if (EquipOrSwapPackage(unit, slot, package))
|
||||
{
|
||||
ClosePackageEquipWindow();
|
||||
RenderUnitDetail(unit);
|
||||
ViewChanged?.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
RenderPackageEquipWindow();
|
||||
}
|
||||
|
||||
private bool EquipOrSwapPackage(DistroDefinition unit, PackageSlot slot, PackageDefinition package)
|
||||
{
|
||||
if (unit == null || package == null || _packageLoadout == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PackageDefinition currentlyEquipped = _packageLoadout.GetEquippedPackage(unit.Id, slot);
|
||||
if (currentlyEquipped != null && !string.Equals(currentlyEquipped.Id, package.Id, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
if (!_packageLoadout.TryUnequip(unit.Id, slot, out PackageLoadoutFailureReason unequipReason))
|
||||
{
|
||||
_packageSlotNotice = FormatPackageFailure(unequipReason);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_packageLoadout.TryEquip(unit.Id, slot, package.Id, out PackageLoadoutFailureReason equipReason))
|
||||
{
|
||||
_packageSlotNotice = FormatPackageFailure(equipReason);
|
||||
return false;
|
||||
}
|
||||
|
||||
_packageSlotNotice = null;
|
||||
_packageLoadoutChanged?.Invoke();
|
||||
return true;
|
||||
}
|
||||
|
||||
private void UnequipPackageFromWindow(DistroDefinition unit, PackageSlot slot)
|
||||
{
|
||||
PackageDefinition equipped = _packageLoadout.GetEquippedPackage(unit.Id, slot);
|
||||
if (equipped == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (TogglePackage(unit, slot, equipped, true))
|
||||
{
|
||||
ClosePackageEquipWindow();
|
||||
RenderUnitDetail(unit);
|
||||
ViewChanged?.Invoke();
|
||||
return;
|
||||
}
|
||||
|
||||
RenderPackageEquipWindow();
|
||||
}
|
||||
|
||||
private void AddVersionUpgradePanel(VisualElement target, DistroDefinition unit)
|
||||
@@ -1406,6 +1750,21 @@ namespace KernelPanic.UI
|
||||
return row;
|
||||
}
|
||||
|
||||
private static VisualElement BuildPackagePreviewLine(string key, string value)
|
||||
{
|
||||
VisualElement row = new();
|
||||
row.AddToClassList("package-preview-line");
|
||||
|
||||
Label keyLabel = new(key);
|
||||
keyLabel.AddToClassList("package-preview-key");
|
||||
Label valueLabel = new(value);
|
||||
valueLabel.AddToClassList("package-preview-value");
|
||||
|
||||
row.Add(keyLabel);
|
||||
row.Add(valueLabel);
|
||||
return row;
|
||||
}
|
||||
|
||||
private VisualElement BuildSubviewCommand(string command, string description, bool enabled, Action action, string disabledDescription)
|
||||
{
|
||||
VisualElement row = new();
|
||||
@@ -1688,7 +2047,7 @@ namespace KernelPanic.UI
|
||||
{
|
||||
PackageLoadoutFailureReason.WrongSlot => "wrong slot",
|
||||
PackageLoadoutFailureReason.NotOwned => "package not owned",
|
||||
PackageLoadoutFailureReason.SlotOccupied => "slot occupied",
|
||||
PackageLoadoutFailureReason.SlotOccupied => "slot occupied: unequip current package first",
|
||||
PackageLoadoutFailureReason.NotEquipped => "package not equipped",
|
||||
_ => "package change failed"
|
||||
};
|
||||
|
||||
+203
-5
@@ -1166,21 +1166,26 @@ Button {
|
||||
border-top-color: var(--kp-border);
|
||||
}
|
||||
|
||||
.packages-master-detail {
|
||||
.packages-master-detail,
|
||||
.packages-summary-layout {
|
||||
flex-grow: 1;
|
||||
min-height: 0;
|
||||
flex-direction: row;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.packages-slot-list {
|
||||
width: 46%;
|
||||
width: 47%;
|
||||
min-width: 0;
|
||||
margin-right: 14px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.packages-detail-panel {
|
||||
.packages-detail-panel,
|
||||
.packages-impact-panel {
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
max-width: 53%;
|
||||
padding: 10px;
|
||||
border-left-width: 1px;
|
||||
border-right-width: 1px;
|
||||
@@ -1193,6 +1198,44 @@ Button {
|
||||
background-color: var(--kp-bg-solid);
|
||||
}
|
||||
|
||||
.packages-active-effects {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.package-stat-line {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
min-height: 24px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.package-stat-key {
|
||||
width: 82px;
|
||||
min-width: 82px;
|
||||
color: var(--kp-muted);
|
||||
}
|
||||
|
||||
.package-stat-value {
|
||||
width: 98px;
|
||||
min-width: 98px;
|
||||
color: var(--kp-primary);
|
||||
}
|
||||
|
||||
.package-stat-bonus {
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
color: var(--kp-amber);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.package-active-effect {
|
||||
color: var(--kp-muted);
|
||||
white-space: normal;
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.package-slot-row {
|
||||
min-height: 42px;
|
||||
flex-direction: row;
|
||||
@@ -1202,6 +1245,7 @@ Button {
|
||||
border-left-width: 2px;
|
||||
border-left-color: transparent;
|
||||
background-color: var(--kp-bg-solid);
|
||||
overflow: hidden;
|
||||
transition-property: background-color, border-left-color;
|
||||
transition-duration: 120ms;
|
||||
}
|
||||
@@ -1249,12 +1293,41 @@ Button {
|
||||
.package-slot-effect {
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
max-width: 170px;
|
||||
color: var(--kp-muted);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.package-slot-action {
|
||||
width: 96px;
|
||||
min-width: 96px;
|
||||
color: var(--kp-primary);
|
||||
font-size: 12px;
|
||||
-unity-text-align: middle-right;
|
||||
}
|
||||
|
||||
.package-preview-line {
|
||||
flex-direction: row;
|
||||
min-height: 24px;
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.package-preview-key {
|
||||
width: 64px;
|
||||
min-width: 64px;
|
||||
color: var(--kp-muted);
|
||||
}
|
||||
|
||||
.package-preview-value {
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
color: var(--kp-primary);
|
||||
white-space: normal;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.collection-row-languages,
|
||||
.collection-detail-muted {
|
||||
color: var(--kp-muted);
|
||||
@@ -1355,6 +1428,60 @@ Button {
|
||||
opacity: 0.45;
|
||||
}
|
||||
|
||||
.packages-detail-panel .package-row {
|
||||
padding: 4px 8px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.package-picker-row {
|
||||
min-height: 28px;
|
||||
max-height: 28px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.package-picker-row .package-summary {
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.package-picker-row .package-name {
|
||||
width: 150px;
|
||||
min-width: 92px;
|
||||
flex-grow: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.package-picker-effect {
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
color: var(--kp-muted);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.package-picker-row .package-meta {
|
||||
width: 58px;
|
||||
min-width: 58px;
|
||||
}
|
||||
|
||||
.package-picker-row .package-description {
|
||||
margin-left: 34px;
|
||||
margin-top: 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.package-picker-row .package-notice {
|
||||
margin-left: 34px;
|
||||
margin-bottom: 0;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.package-summary {
|
||||
min-width: 0;
|
||||
flex-direction: row;
|
||||
@@ -1489,14 +1616,16 @@ Button {
|
||||
}
|
||||
|
||||
.modal-overlay > .starter-dialog,
|
||||
.modal-overlay > .root-credit-dialog {
|
||||
.modal-overlay > .root-credit-dialog,
|
||||
.modal-overlay > .package-equip-dialog {
|
||||
scale: 0.94 0.94;
|
||||
transition-property: scale;
|
||||
transition-duration: 160ms;
|
||||
}
|
||||
|
||||
.modal-overlay.modal-open > .starter-dialog,
|
||||
.modal-overlay.modal-open > .root-credit-dialog {
|
||||
.modal-overlay.modal-open > .root-credit-dialog,
|
||||
.modal-overlay.modal-open > .package-equip-dialog {
|
||||
scale: 1 1;
|
||||
}
|
||||
|
||||
@@ -1531,6 +1660,74 @@ Button {
|
||||
background-color: var(--kp-bg-solid);
|
||||
}
|
||||
|
||||
.package-equip-dialog {
|
||||
position: relative;
|
||||
width: 78%;
|
||||
height: 74%;
|
||||
padding: 18px;
|
||||
border-left-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-top-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-color: var(--kp-primary);
|
||||
border-right-color: var(--kp-primary);
|
||||
border-top-color: var(--kp-primary);
|
||||
border-bottom-color: var(--kp-primary);
|
||||
background-color: var(--kp-bg-solid);
|
||||
}
|
||||
|
||||
.package-equip-header {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
flex-shrink: 0;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.package-equip-header .collection-detail-name {
|
||||
flex-grow: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.package-equip-list {
|
||||
flex-grow: 1;
|
||||
min-height: 0;
|
||||
margin-top: 8px;
|
||||
margin-bottom: 10px;
|
||||
border-left-width: 1px;
|
||||
border-right-width: 1px;
|
||||
border-top-width: 1px;
|
||||
border-bottom-width: 1px;
|
||||
border-left-color: var(--kp-border);
|
||||
border-right-color: var(--kp-border);
|
||||
border-top-color: var(--kp-border);
|
||||
border-bottom-color: var(--kp-border);
|
||||
}
|
||||
|
||||
.package-equip-row {
|
||||
padding: 8px 10px;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.package-equip-row.on-distro {
|
||||
background-color: var(--kp-hover);
|
||||
}
|
||||
|
||||
.package-equip-row .package-meta {
|
||||
width: 128px;
|
||||
min-width: 128px;
|
||||
}
|
||||
|
||||
.package-equip-tags {
|
||||
flex-direction: row;
|
||||
margin-left: 34px;
|
||||
}
|
||||
|
||||
.package-equip-tags .package-notice {
|
||||
margin-right: 12px;
|
||||
margin-bottom: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.modal-close-button {
|
||||
position: absolute;
|
||||
top: 14px;
|
||||
@@ -1803,6 +2000,7 @@ Button {
|
||||
.reduced-motion .modal-overlay,
|
||||
.reduced-motion .modal-overlay > .starter-dialog,
|
||||
.reduced-motion .modal-overlay > .root-credit-dialog,
|
||||
.reduced-motion .modal-overlay > .package-equip-dialog,
|
||||
.reduced-motion .command-row,
|
||||
.reduced-motion .gacha-banner-row,
|
||||
.reduced-motion .collection-tab,
|
||||
|
||||
Reference in New Issue
Block a user