Implement many UX improvements, packages and their assets and a UI overhaul in collection
This commit is contained in:
+170
-49
@@ -11,13 +11,117 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="4222a6b8-add3-4f43-9c42-fd6bb5a76169" name="Changes" comment="">
|
<list default="true" id="4222a6b8-add3-4f43-9c42-fd6bb5a76169" name="Changes" comment="">
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Apt.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Apt.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/AptFast.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/AptFast.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Auditd.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Auditd.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Ccache.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Ccache.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/CinnamonPackage.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/CinnamonPackage.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Coreutils.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Coreutils.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Cron.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Cron.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Curl.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Curl.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/DNF.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/DNF.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Dbus.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Dbus.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Docker.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Docker.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Ext4.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Ext4.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Firewalld.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Firewalld.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Git.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Git.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Glibc.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Glibc.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Htop.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Htop.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Less.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Less.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Logrotate.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Logrotate.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Lvm.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Lvm.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Make.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Make.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Nano.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Nano.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Nginx.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Nginx.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Ntp.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Ntp.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/OpenSSL.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/OpenSSL.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/PackageDatabase.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/PackageDatabase.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Polkit.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Polkit.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Rsync.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Rsync.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/SELinuxPackage.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/SELinuxPackage.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/SnapStore.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/SnapStore.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Sshd.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Sshd.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Swapfile.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Swapfile.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Syslog.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Syslog.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/SystemdCore.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/SystemdCore.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/SystemdTimer.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/SystemdTimer.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/TimeshiftPackage.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/TimeshiftPackage.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Udev.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Udev.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Vim.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Vim.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Wget.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Wget.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Zlib.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Zlib.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Zram.asset" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Data/Packages/Zram.asset.meta" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Scripts/Data/PackageDatabase.cs" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Scripts/Data/PackageDefinition.cs" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Scripts/Meta/PackageLoadout.cs" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Scripts/Meta/PackageScrapper.cs" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Scripts/Meta/PackageTuning.cs" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/Assets/Scripts/Meta/PackageUpgrader.cs" afterDir="false" />
|
||||||
<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$/.idea/.idea.linuxdistrosbuttheyarebreedable/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/.idea.linuxdistrosbuttheyarebreedable/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Resources/CombatScene.uss" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Resources/CombatScene.uss" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Assets/Data/Distros/Ubuntu.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Data/Distros/Ubuntu.asset" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scenes/MainMenuScene.unity" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scenes/MainMenuScene.unity" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Combat/CardEffects.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Combat/CardEffects.cs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Combat/CardEffects.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Combat/CardEffects.cs" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Combat/CombatManager.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Combat/CombatManager.cs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Combat/CombatManager.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Combat/CombatManager.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Combat/CombatantState.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Combat/CombatantState.cs" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Combat/DamagePipeline.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Combat/DamagePipeline.cs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Combat/DamagePipeline.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Combat/DamagePipeline.cs" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Core/GameEvents.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Core/GameEvents.cs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Meta/GachaCurrencyType.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Meta/GachaCurrencyType.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Meta/GachaPullContext.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Meta/GachaPullContext.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Meta/GachaRewardType.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Meta/GachaRewardType.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Meta/GachaService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Meta/GachaService.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Meta/PlayerCollection.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Meta/PlayerCollection.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Meta/PullResolver.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Meta/PullResolver.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Meta/SaveService.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Meta/SaveService.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Run/RunConfig.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Run/RunConfig.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Run/RunContext.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Run/RunContext.cs" 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/Scripts/UI/CombatSceneController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/CombatSceneController.cs" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/UI/CombatSceneController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/CombatSceneController.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/UI/FeaturedUnitPanel.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/FeaturedUnitPanel.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/UI/GachaScreenController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/GachaScreenController.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/UI/GamblingSceneController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/GamblingSceneController.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/Scripts/UI/MainMenuController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/MainMenuController.cs" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/UI/MainMenu.uss" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/UI/MainMenu.uss" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/Assets/UI/MainMenu.uxml" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/UI/MainMenu.uxml" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
@@ -63,6 +167,13 @@
|
|||||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Distros/Fedora.asset" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Assets/Data/Distros/Fedora.asset" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Distros/Mint.asset" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Assets/Data/Distros/Mint.asset" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Distros/Ubuntu.asset" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Assets/Data/Distros/Ubuntu.asset" root0="FORCE_HIGHLIGHTING" />
|
||||||
|
<setting file="file://$PROJECT_DIR$/Assets/Data/Packages/Apt.asset" root0="FORCE_HIGHLIGHTING" />
|
||||||
|
<setting file="file://$PROJECT_DIR$/Assets/Data/Packages/AptFast.asset" root0="FORCE_HIGHLIGHTING" />
|
||||||
|
<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/Syslog.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/AptUpdate.asset" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Passives/BleedingEdge.asset" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Assets/Data/Passives/BleedingEdge.asset" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Assets/Data/Passives/ItJustWorks.asset" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Assets/Data/Passives/ItJustWorks.asset" root0="FORCE_HIGHLIGHTING" />
|
||||||
@@ -83,23 +194,23 @@
|
|||||||
<component name="MetaFilesCheckinStateConfiguration" checkMetaFiles="true" />
|
<component name="MetaFilesCheckinStateConfiguration" checkMetaFiles="true" />
|
||||||
<component name="NextEditCompletionFeaturesState">
|
<component name="NextEditCompletionFeaturesState">
|
||||||
<decayedCancelled>
|
<decayedCancelled>
|
||||||
<entry key="MS100" value="1.000000000000699" />
|
<entry key="MS100" value="1.4963024003289789" />
|
||||||
<entry key="MS500" value="1.0163073776265223" />
|
<entry key="MS500" value="5.493825018740593" />
|
||||||
<entry key="S2" value="5.108221812019007" />
|
<entry key="S2" value="16.7623810091312" />
|
||||||
<entry key="S5" value="21.770600885518434" />
|
<entry key="S5" value="30.131569239395123" />
|
||||||
<entry key="S10" value="47.09517013998605" />
|
<entry key="S10" value="42.28180741555183" />
|
||||||
<entry key="S30" value="93.9785706567626" />
|
<entry key="S30" value="57.034967620889354" />
|
||||||
<entry key="S60" value="119.48644415542124" />
|
<entry key="S60" value="62.13535362816746" />
|
||||||
<entry key="M2" value="160.68491265036215" />
|
<entry key="M2" value="65.05702793593957" />
|
||||||
<entry key="M5" value="278.40590534440275" />
|
<entry key="M5" value="68.80146390839094" />
|
||||||
<entry key="M10" value="395.77142962415076" />
|
<entry key="M10" value="73.0920556177788" />
|
||||||
<entry key="M15" value="485.9382710538006" />
|
<entry key="M15" value="75.72809697957445" />
|
||||||
<entry key="M30" value="720.5335135398915" />
|
<entry key="M30" value="88.95784666638842" />
|
||||||
<entry key="H1" value="1054.9046690258854" />
|
<entry key="H1" value="204.48905359593877" />
|
||||||
<entry key="H2" value="1414.4969635593438" />
|
<entry key="H2" value="565.8614083894486" />
|
||||||
<entry key="H4" value="1731.0633909446262" />
|
<entry key="H4" value="1095.0876588283427" />
|
||||||
<entry key="D1" value="3286.6219915604" />
|
<entry key="D1" value="3089.1206296820615" />
|
||||||
<entry key="W1" value="4660.98507014222" />
|
<entry key="W1" value="4685.751345931765" />
|
||||||
</decayedCancelled>
|
</decayedCancelled>
|
||||||
<decayedSelected>
|
<decayedSelected>
|
||||||
<entry key="MS100" value="0.0" />
|
<entry key="MS100" value="0.0" />
|
||||||
@@ -109,35 +220,35 @@
|
|||||||
<entry key="S10" value="0.0" />
|
<entry key="S10" value="0.0" />
|
||||||
<entry key="S30" value="0.0" />
|
<entry key="S30" value="0.0" />
|
||||||
<entry key="S60" value="0.0" />
|
<entry key="S60" value="0.0" />
|
||||||
<entry key="M2" value="2.5063439983015887E-240" />
|
<entry key="M2" value="2.5828778732379276E-268" />
|
||||||
<entry key="M5" value="1.4441631903175532E-96" />
|
<entry key="M5" value="9.222348906385734E-108" />
|
||||||
<entry key="M10" value="1.2017334106687881E-48" />
|
<entry key="M10" value="3.0368320510667516E-54" />
|
||||||
<entry key="M15" value="1.130330440943858E-32" />
|
<entry key="M15" value="2.0970744528210016E-36" />
|
||||||
<entry key="M30" value="1.0631703388171175E-16" />
|
<entry key="M30" value="1.4481283797362389E-18" />
|
||||||
<entry key="H1" value="1.0321150378964974E-8" />
|
<entry key="H1" value="1.2045649226616757E-9" />
|
||||||
<entry key="H2" value="1.0705766421479234E-4" />
|
<entry key="H2" value="3.65736931549959E-5" />
|
||||||
<entry key="H4" value="0.014144219737749934" />
|
<entry key="H4" value="0.008267125324716448" />
|
||||||
<entry key="D1" value="1.4628029396241715" />
|
<entry key="D1" value="1.3375655629148175" />
|
||||||
<entry key="W1" value="3.4598536273655087" />
|
<entry key="W1" value="3.4158969636928482" />
|
||||||
</decayedSelected>
|
</decayedSelected>
|
||||||
<decayedShown>
|
<decayedShown>
|
||||||
<entry key="MS100" value="0.9526379980446108" />
|
<entry key="MS100" value="1.4096752248792137" />
|
||||||
<entry key="MS500" value="1.0065360445565774" />
|
<entry key="MS500" value="5.428036231472652" />
|
||||||
<entry key="S2" value="5.098242978856544" />
|
<entry key="S2" value="16.712977941585102" />
|
||||||
<entry key="S5" value="21.754020235151167" />
|
<entry key="S5" value="30.091551042144605" />
|
||||||
<entry key="S10" value="47.07706009383575" />
|
<entry key="S10" value="42.251172488375474" />
|
||||||
<entry key="S30" value="93.9663762674251" />
|
<entry key="S30" value="57.02028505912365" />
|
||||||
<entry key="S60" value="119.47863856671924" />
|
<entry key="S60" value="62.127231458210936" />
|
||||||
<entry key="M2" value="160.67946494648172" />
|
<entry key="M2" value="65.05274498886968" />
|
||||||
<entry key="M5" value="278.4016956102392" />
|
<entry key="M5" value="68.79965480133401" />
|
||||||
<entry key="M10" value="395.76819463253577" />
|
<entry key="M10" value="73.09110313975116" />
|
||||||
<entry key="M15" value="485.9354965404165" />
|
<entry key="M15" value="75.72744303179836" />
|
||||||
<entry key="M30" value="720.531339531474" />
|
<entry key="M30" value="88.95747776256005" />
|
||||||
<entry key="H1" value="1054.9030513551575" />
|
<entry key="H1" value="204.48869117823617" />
|
||||||
<entry key="H2" value="1414.4959842118083" />
|
<entry key="H2" value="565.860985887298" />
|
||||||
<entry key="H4" value="1731.0768609975287" />
|
<entry key="H4" value="1095.0954876479952" />
|
||||||
<entry key="D1" value="3288.0844643497253" />
|
<entry key="D1" value="3090.4578859402736" />
|
||||||
<entry key="W1" value="4664.444843440584" />
|
<entry key="W1" value="4689.167162525937" />
|
||||||
</decayedShown>
|
</decayedShown>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectColorInfo">{
|
<component name="ProjectColorInfo">{
|
||||||
@@ -228,7 +339,8 @@
|
|||||||
<workItem from="1783372397891" duration="989000" />
|
<workItem from="1783372397891" duration="989000" />
|
||||||
<workItem from="1783410502976" duration="23430000" />
|
<workItem from="1783410502976" duration="23430000" />
|
||||||
<workItem from="1783507489679" duration="5909000" />
|
<workItem from="1783507489679" duration="5909000" />
|
||||||
<workItem from="1783519887449" duration="4333000" />
|
<workItem from="1783519887449" duration="6425000" />
|
||||||
|
<workItem from="1783578446731" duration="5031000" />
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00001" summary="implement main screen">
|
<task id="LOCAL-00001" summary="implement main screen">
|
||||||
<option name="closed" value="true" />
|
<option name="closed" value="true" />
|
||||||
@@ -414,7 +526,15 @@
|
|||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1783503035031</updated>
|
<updated>1783503035031</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="24" />
|
<task id="LOCAL-00024" summary="make small changes to design. Implement crits.">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1783531936700</created>
|
||||||
|
<option name="number" value="00024" />
|
||||||
|
<option name="presentableId" value="LOCAL-00024" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1783531936701</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="25" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
@@ -452,7 +572,8 @@
|
|||||||
<MESSAGE value="Implement cutscene for gambling and make it dopamine-inducing" />
|
<MESSAGE value="Implement cutscene for gambling and make it dopamine-inducing" />
|
||||||
<MESSAGE value="changed most TODOs to TODONEs" />
|
<MESSAGE value="changed most TODOs to TODONEs" />
|
||||||
<MESSAGE value="Implement Java and Rust cards alongside some smaller changes" />
|
<MESSAGE value="Implement Java and Rust cards alongside some smaller changes" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="Implement Java and Rust cards alongside some smaller changes" />
|
<MESSAGE value="make small changes to design. Implement crits." />
|
||||||
|
<option name="LAST_COMMIT_MESSAGE" value="make small changes to design. Implement crits." />
|
||||||
</component>
|
</component>
|
||||||
<component name="XDebuggerManager">
|
<component name="XDebuggerManager">
|
||||||
<breakpoint-manager>
|
<breakpoint-manager>
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ MonoBehaviour:
|
|||||||
accentColor: {r: 0.9137255, g: 0.32941177, b: 0.1254902, a: 1}
|
accentColor: {r: 0.9137255, g: 0.32941177, b: 0.1254902, a: 1}
|
||||||
baseUptime: 60
|
baseUptime: 60
|
||||||
baseRam: 5
|
baseRam: 5
|
||||||
baseCyclesPerTurn: 3
|
baseCyclesPerTurn: 4
|
||||||
exclusiveCards:
|
exclusiveCards:
|
||||||
- {fileID: 11400000, guid: 9347bcc42fb6834f1907a2c0b661ff95, type: 2}
|
- {fileID: 11400000, guid: 9347bcc42fb6834f1907a2c0b661ff95, type: 2}
|
||||||
- {fileID: 11400000, guid: 1dbc28e480e52d97b9501262af30cc78, type: 2}
|
- {fileID: 11400000, guid: 1dbc28e480e52d97b9501262af30cc78, type: 2}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_Script: {fileID: 11500000, guid: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Apt
|
||||||
|
id: pkg_ubuntu_apt
|
||||||
|
displayName: apt
|
||||||
|
slot: 2
|
||||||
|
rarity: 5
|
||||||
|
description: Each time you play your 3rd card in a TURN, add a random 0-cost card of your languages to hand; on Ubuntu also refund 1 Cycle.
|
||||||
|
flavourText: There is always one more dependency.
|
||||||
|
designNotes: Ubuntu 5-star Daemon. TURN third-card trigger. requiresSystem: card-generation + per-turn-card-count. On Ubuntu refunds 1 Cycle.
|
||||||
|
intendedDistroId: ubuntu
|
||||||
|
requiresSystem:
|
||||||
|
- card-generation
|
||||||
|
- per-turn-card-count
|
||||||
|
offDistroEffect: {kind: 10, amount: 1, threshold: 3, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 10, amount: 1, threshold: 3, refundCycle: 1, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cef0ecd4cdaa4fd09c2c8578263acd20
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: AptFast
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_apt_fast
|
||||||
|
displayName: apt-fast
|
||||||
|
slot: 1
|
||||||
|
rarity: 3
|
||||||
|
description: Start of each WAVE, gain +1 Cycle that WAVE's first TURN.
|
||||||
|
flavourText: Parallel downloads, parallel consequences.
|
||||||
|
designNotes: Generic 3-star Runtime powerspike. First-turn WAVE cycle hook.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 18, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 18, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 96d18432766243138d800f9f544bc934
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Auditd
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_auditd
|
||||||
|
displayName: auditd
|
||||||
|
slot: 2
|
||||||
|
rarity: 3
|
||||||
|
description: Start of each TURN, if you have no debuffs, gain 3 Shield.
|
||||||
|
flavourText: Logs suspicious activity, including competence.
|
||||||
|
designNotes: Generic 3-star Daemon powerspike. Uses status descriptor harmful query.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 23, amount: 3, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 23, amount: 3, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a8e4cfd86f554fa19198551a7d5ed8ab
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Ccache
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_ccache
|
||||||
|
displayName: ccache
|
||||||
|
slot: 1
|
||||||
|
rarity: 3
|
||||||
|
description: Every 4th card played in a WAVE costs 0.
|
||||||
|
flavourText: Why compile twice when you can be smug once?
|
||||||
|
designNotes: Generic 3-star Runtime powerspike. Existing nth-card WAVE free-cost hook.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 8, amount: 0, threshold: 4, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 8, amount: 0, threshold: 4, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f68f89f3d4554063a891c30b1c387692
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_Script: {fileID: 11500000, guid: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: CinnamonPackage
|
||||||
|
id: pkg_mint_cinnamon
|
||||||
|
displayName: Cinnamon
|
||||||
|
slot: 1
|
||||||
|
rarity: 4
|
||||||
|
description: JavaScript cards deal +3 flat on Mint, +2 off-distro.
|
||||||
|
flavourText: Comfortable, polished, and a little too smug.
|
||||||
|
designNotes: Mint 4-star Runtime. Flat add through DamagePipeline additive step. On Mint +3; off-distro +2.
|
||||||
|
intendedDistroId: mint
|
||||||
|
requiresSystem:
|
||||||
|
- damage-pipeline-additive
|
||||||
|
offDistroEffect: {kind: 11, amount: 2, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 11, amount: 3, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5b13be9296e347459ed3659e1855a5d3
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Coreutils
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_coreutils
|
||||||
|
displayName: coreutils
|
||||||
|
slot: 0
|
||||||
|
rarity: 1
|
||||||
|
description: +2 max Uptime (COMBAT).
|
||||||
|
flavourText: The box of tiny tools that somehow runs everything.
|
||||||
|
designNotes: Generic 1-star Kernel baseline. COMBAT stat package. On/off distro identical.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 1, amount: 2, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 1, amount: 2, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7422da9aba294553a6009eb3c01498e1
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_Script: {fileID: 11500000, guid: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Cron
|
||||||
|
id: pkg_cron
|
||||||
|
displayName: cron
|
||||||
|
slot: 2
|
||||||
|
rarity: 1
|
||||||
|
description: Every 3rd TURN, gain 2 Shield.
|
||||||
|
flavourText: Eventually, it helps.
|
||||||
|
designNotes: Generic 1-star Daemon. TURN counter shield. On/off distro identical.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 6, amount: 2, threshold: 3, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 6, amount: 2, threshold: 3, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0b6678d8a231464b8ff257ece3dcfeae
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_Script: {fileID: 11500000, guid: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Curl
|
||||||
|
id: pkg_curl
|
||||||
|
displayName: curl
|
||||||
|
slot: 1
|
||||||
|
rarity: 1
|
||||||
|
description: Draw 1 extra card at the start of each WAVE.
|
||||||
|
flavourText: It downloads help, mostly by accident.
|
||||||
|
designNotes: Generic 1-star Runtime. WAVE start draw. On/off distro identical.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 3, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 3, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 415021c139b54ff1a6b9cc2e5aede209
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_Script: {fileID: 11500000, guid: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: DNF
|
||||||
|
id: pkg_fedora_dnf
|
||||||
|
displayName: DNF
|
||||||
|
slot: 1
|
||||||
|
rarity: 5
|
||||||
|
description: On Fedora, Bleeding Edge applies to the 2nd card each TURN. Also builds a stacking +2 damage buff this WAVE.
|
||||||
|
flavourText: Fast, sharp, occasionally on fire.
|
||||||
|
designNotes: Fedora 5-star Runtime. Ties into Bleeding Edge crash logic; on Fedora enables 2nd-card passive discount+bonus. Off-distro only uses the WAVE stacking +2 damage buff hook.
|
||||||
|
intendedDistroId: fedora
|
||||||
|
requiresSystem:
|
||||||
|
- fedora-passive-hook
|
||||||
|
- per-wave-damage-buff
|
||||||
|
offDistroEffect: {kind: 14, amount: 2, threshold: 1, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 14, amount: 2, threshold: 1, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 1}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f47028f76c0843629789bf128bae4c3d
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Dbus
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_dbus
|
||||||
|
displayName: dbus
|
||||||
|
slot: 2
|
||||||
|
rarity: 1
|
||||||
|
description: First time you play a queued (InterpreterQueue) card each WAVE, gain 2 Shield.
|
||||||
|
flavourText: Messages everywhere, consensus nowhere.
|
||||||
|
designNotes: Generic 1-star Daemon. InterpreterQueue play hook.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 21, amount: 2, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 21, amount: 2, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e90cac6fdbde448a9eb7432889a0ec39
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_Script: {fileID: 11500000, guid: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Docker
|
||||||
|
id: pkg_docker
|
||||||
|
displayName: docker
|
||||||
|
slot: 1
|
||||||
|
rarity: 3
|
||||||
|
description: At the start of each WAVE, add a random 0-cost basic card of the distro's languages to hand.
|
||||||
|
flavourText: Works on my daemon.
|
||||||
|
designNotes: Generic 3-star Runtime powerspike. WAVE start generation. requiresSystem: card-generation; uses existing generated-card pool when available, TODO logged if not.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem:
|
||||||
|
- card-generation
|
||||||
|
offDistroEffect: {kind: 4, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 4, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a392e5d09c864940bde926a68f4681a7
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Ext4
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_ext4
|
||||||
|
displayName: ext4
|
||||||
|
slot: 0
|
||||||
|
rarity: 2
|
||||||
|
description: +4 max Uptime (COMBAT).
|
||||||
|
flavourText: Journaling your mistakes so recovery has something to read.
|
||||||
|
designNotes: Generic 2-star Kernel. COMBAT stat package.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 1, amount: 4, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 1, amount: 4, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 309a914d85d544d4bd2e19b35d40768e
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Firewalld
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_firewalld
|
||||||
|
displayName: firewalld
|
||||||
|
slot: 2
|
||||||
|
rarity: 2
|
||||||
|
description: The first debuff applied to you each WAVE is reduced by 1 stack.
|
||||||
|
flavourText: Blocks everything except the one port you forgot about.
|
||||||
|
designNotes: Generic 2-star Daemon. TODO status prevention/rewrite hook missing.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: [status-apply-prevention-hook]
|
||||||
|
offDistroEffect: {kind: 0, amount: 0, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 0, amount: 0, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f09c5c4fed8547a7ade6e4c1129acf08
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_Script: {fileID: 11500000, guid: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Git
|
||||||
|
id: pkg_git
|
||||||
|
displayName: git
|
||||||
|
slot: 1
|
||||||
|
rarity: 2
|
||||||
|
description: The first card played each WAVE costs 1 less.
|
||||||
|
flavourText: Everyone blames the branch.
|
||||||
|
designNotes: Generic 2-star Runtime. WAVE first-card economy. On/off distro identical.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 5, amount: 1, threshold: 1, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 5, amount: 1, threshold: 1, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 36e380dd7864488a9544eff6d0aa15d5
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Glibc
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_glibc
|
||||||
|
displayName: glibc
|
||||||
|
slot: 0
|
||||||
|
rarity: 1
|
||||||
|
description: +2 max Uptime (COMBAT).
|
||||||
|
flavourText: Everything links against it, including your bad decisions.
|
||||||
|
designNotes: Generic 1-star Kernel. COMBAT stat package. Upgrade scaling increases amount at runtime.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 1, amount: 2, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 1, amount: 2, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 03b4a29f7baa4a4c8cc5945a508b64a5
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Htop
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_htop
|
||||||
|
displayName: htop
|
||||||
|
slot: 0
|
||||||
|
rarity: 2
|
||||||
|
description: +5 max Uptime (COMBAT).
|
||||||
|
flavourText: Green bars make the panic feel managed.
|
||||||
|
designNotes: Generic 2-star Kernel. COMBAT stat package. On/off distro identical.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 1, amount: 5, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 1, amount: 5, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b3e47005ebdf42788204e5b5677f9002
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Less
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_less
|
||||||
|
displayName: less
|
||||||
|
slot: 1
|
||||||
|
rarity: 1
|
||||||
|
description: Once per WAVE, the first card drawn is free to play (0 cost) that TURN.
|
||||||
|
flavourText: Less is more, except when it is just a pager.
|
||||||
|
designNotes: Generic 1-star Runtime. TODO free-cast/draw-tag hook missing.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: [free-cast-drawn-card-hook]
|
||||||
|
offDistroEffect: {kind: 0, amount: 0, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 0, amount: 0, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 76af631396664958a398073c6021a626
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_Script: {fileID: 11500000, guid: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Logrotate
|
||||||
|
id: pkg_logrotate
|
||||||
|
displayName: logrotate
|
||||||
|
slot: 2
|
||||||
|
rarity: 2
|
||||||
|
description: When you exhaust a card, gain 1 Shield.
|
||||||
|
flavourText: Deletes the evidence, keeps the casing.
|
||||||
|
designNotes: Generic 2-star Daemon. Exhaust hook; current authored exhaust path is dnf autoremove.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem:
|
||||||
|
- exhaust-hook
|
||||||
|
offDistroEffect: {kind: 7, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 7, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0f2a212cc70d422189f26c0314853ef4
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Lvm
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_lvm
|
||||||
|
displayName: lvm
|
||||||
|
slot: 0
|
||||||
|
rarity: 3
|
||||||
|
description: +8 max Uptime (COMBAT).
|
||||||
|
flavourText: Logical volumes, illogical confidence.
|
||||||
|
designNotes: Generic 3-star Kernel powerspike. COMBAT stat package.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 1, amount: 8, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 1, amount: 8, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f30e0284fa5a45aaa7507089a31aaf88
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Make
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_make
|
||||||
|
displayName: make
|
||||||
|
slot: 1
|
||||||
|
rarity: 2
|
||||||
|
description: The first Native card each WAVE deals +3.
|
||||||
|
flavourText: Tab-sensitive violence.
|
||||||
|
designNotes: Generic 2-star Runtime. Routes through existing flat effect bonus before first Native card resolves.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 20, amount: 3, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 20, amount: 3, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ed56f679bb7b4db9ad7884bfeb7f1660
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Nano
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_nano
|
||||||
|
displayName: nano
|
||||||
|
slot: 1
|
||||||
|
rarity: 1
|
||||||
|
description: The first card played each WAVE costs 1 less.
|
||||||
|
flavourText: Exit instructions included, panic reduced.
|
||||||
|
designNotes: Generic 1-star Runtime. Existing first-card-per-WAVE cost hook.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 5, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 5, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 47286d5a87334b1fa303a583a9b1085e
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_Script: {fileID: 11500000, guid: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Nginx
|
||||||
|
id: pkg_nginx
|
||||||
|
displayName: nginx
|
||||||
|
slot: 2
|
||||||
|
rarity: 3
|
||||||
|
description: Every 3rd card played in a WAVE costs 0.
|
||||||
|
flavourText: Reverse proxies your budget.
|
||||||
|
designNotes: Generic 3-star Daemon powerspike. WAVE card counter cost override.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 8, amount: 0, threshold: 3, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 8, amount: 0, threshold: 3, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: e4cb1d11f3dd44878111ce3b5f89ee8c
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Ntp
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_ntp
|
||||||
|
displayName: ntp
|
||||||
|
slot: 0
|
||||||
|
rarity: 2
|
||||||
|
description: +3 max Uptime (COMBAT); first TURN of each WAVE, gain 2 Shield.
|
||||||
|
flavourText: Corrects clock drift and, briefly, life choices.
|
||||||
|
designNotes: Generic 2-star Kernel. Uses MaxUptime now; first-turn shield TODO until multi-effect packages exist.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: [multi-effect-package]
|
||||||
|
offDistroEffect: {kind: 1, amount: 3, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 1, amount: 3, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5c9c4f393b7a4dad874f50d02984d4d5
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: OpenSSL
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_openssl
|
||||||
|
displayName: openssl
|
||||||
|
slot: 0
|
||||||
|
rarity: 1
|
||||||
|
description: +1 max Uptime (COMBAT), +1 Shield at WAVE start.
|
||||||
|
flavourText: The lock icon is mostly vibes, but the vibes are encrypted.
|
||||||
|
designNotes: Generic 1-star Kernel. Uses MaxUptime now; WAVE shield portion TODO until multi-effect packages exist.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: [multi-effect-package]
|
||||||
|
offDistroEffect: {kind: 1, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 1, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 2320e53b9b8a4f5184025ddba1581f65
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_Script: {fileID: 11500000, guid: 04c3b1510a7d45f3aba1ee24fe0cbc12, type: 3}
|
||||||
|
m_Name: PackageDatabase
|
||||||
|
allPackages:
|
||||||
|
- {fileID: 11400000, guid: 7422da9aba294553a6009eb3c01498e1, type: 2}
|
||||||
|
- {fileID: 11400000, guid: b3e47005ebdf42788204e5b5677f9002, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 7b77920d46a0434ab4e772339293d991, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 415021c139b54ff1a6b9cc2e5aede209, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 36e380dd7864488a9544eff6d0aa15d5, type: 2}
|
||||||
|
- {fileID: 11400000, guid: a392e5d09c864940bde926a68f4681a7, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 0b6678d8a231464b8ff257ece3dcfeae, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 0f2a212cc70d422189f26c0314853ef4, type: 2}
|
||||||
|
- {fileID: 11400000, guid: e4cb1d11f3dd44878111ce3b5f89ee8c, type: 2}
|
||||||
|
- {fileID: 11400000, guid: ccaa32454a304e1f96d6d340b9c1900e, type: 2}
|
||||||
|
- {fileID: 11400000, guid: cef0ecd4cdaa4fd09c2c8578263acd20, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 5b13be9296e347459ed3659e1855a5d3, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 07554ac885824a6e8e49d7d39cf2fa30, type: 2}
|
||||||
|
- {fileID: 11400000, guid: c9b1e99838c74709aafe6d659b41f231, type: 2}
|
||||||
|
- {fileID: 11400000, guid: f47028f76c0843629789bf128bae4c3d, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 03b4a29f7baa4a4c8cc5945a508b64a5, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 40d2efb5aa8d4b85a4bdc7b3cb7781d8, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 2320e53b9b8a4f5184025ddba1581f65, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 309a914d85d544d4bd2e19b35d40768e, type: 2}
|
||||||
|
- {fileID: 11400000, guid: a48fbfda32824a7cb127318c93602420, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 5c9c4f393b7a4dad874f50d02984d4d5, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 0a11dac6bc6d435192a262eb1d8ac685, type: 2}
|
||||||
|
- {fileID: 11400000, guid: f30e0284fa5a45aaa7507089a31aaf88, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 19d4c144fb5c4ae3b0bccb4b048aaa96, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 47286d5a87334b1fa303a583a9b1085e, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 76af631396664958a398073c6021a626, type: 2}
|
||||||
|
- {fileID: 11400000, guid: a3b1582341434a8981c802f8d7da2420, type: 2}
|
||||||
|
- {fileID: 11400000, guid: b47b1186672c45e19012b4e74c8b0b93, type: 2}
|
||||||
|
- {fileID: 11400000, guid: ed56f679bb7b4db9ad7884bfeb7f1660, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 96d18432766243138d800f9f544bc934, type: 2}
|
||||||
|
- {fileID: 11400000, guid: f68f89f3d4554063a891c30b1c387692, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 302d3da8597941ea99c6d507fa9d3d28, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 177e5f43f6544549bf12e02ec05ec833, type: 2}
|
||||||
|
- {fileID: 11400000, guid: e90cac6fdbde448a9eb7432889a0ec39, type: 2}
|
||||||
|
- {fileID: 11400000, guid: f3174349716e4db6a7ffed8205f2a541, type: 2}
|
||||||
|
- {fileID: 11400000, guid: f09c5c4fed8547a7ade6e4c1129acf08, type: 2}
|
||||||
|
- {fileID: 11400000, guid: 159fca0abb7249e1be485aaac5f83fbe, type: 2}
|
||||||
|
- {fileID: 11400000, guid: ac481beaf7e6453d82a439d54c2fb2f3, type: 2}
|
||||||
|
- {fileID: 11400000, guid: a8e4cfd86f554fa19198551a7d5ed8ab, type: 2}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: efca08b3991e42e5b1e03878507496a6
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Polkit
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_polkit
|
||||||
|
displayName: polkit
|
||||||
|
slot: 2
|
||||||
|
rarity: 2
|
||||||
|
description: First time you gain Shield each TURN, gain +2 extra.
|
||||||
|
flavourText: Permission denied, but with a helpful dialog nobody reads.
|
||||||
|
designNotes: Generic 2-star Daemon. Existing first shield each TURN bonus hook.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 13, amount: 2, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 13, amount: 2, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 159fca0abb7249e1be485aaac5f83fbe
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Rsync
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_rsync
|
||||||
|
displayName: rsync
|
||||||
|
slot: 1
|
||||||
|
rarity: 2
|
||||||
|
description: At WAVE start, draw 1 extra card.
|
||||||
|
flavourText: Efficiently copies hope from the deck into your hand.
|
||||||
|
designNotes: Generic 2-star Runtime. WAVE draw hook.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 3, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 3, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b47b1186672c45e19012b4e74c8b0b93
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_Script: {fileID: 11500000, guid: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: SELinuxPackage
|
||||||
|
id: pkg_fedora_selinux
|
||||||
|
displayName: SELinux
|
||||||
|
slot: 2
|
||||||
|
rarity: 4
|
||||||
|
description: First time you gain Shield each TURN, gain +5 extra on Fedora, +3 off-distro.
|
||||||
|
flavourText: It denied the damage and filed a report.
|
||||||
|
designNotes: Fedora 4-star Daemon. TURN first-shield trigger. On Fedora +5; off-distro +3.
|
||||||
|
intendedDistroId: fedora
|
||||||
|
requiresSystem:
|
||||||
|
- shield-gain-hook
|
||||||
|
offDistroEffect: {kind: 13, amount: 3, threshold: 1, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 13, amount: 5, threshold: 1, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: c9b1e99838c74709aafe6d659b41f231
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_Script: {fileID: 11500000, guid: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: SnapStore
|
||||||
|
id: pkg_ubuntu_snap_store
|
||||||
|
displayName: Snap Store
|
||||||
|
slot: 1
|
||||||
|
rarity: 4
|
||||||
|
description: First cards played each TURN cost 1 less; first 2 on Ubuntu, first 1 off-distro.
|
||||||
|
flavourText: Starts instantly after a brief geological pause.
|
||||||
|
designNotes: Ubuntu 4-star Runtime. TURN card-count cost discount. On Ubuntu threshold 2; off-distro threshold 1.
|
||||||
|
intendedDistroId: ubuntu
|
||||||
|
requiresSystem:
|
||||||
|
- per-turn-card-count
|
||||||
|
offDistroEffect: {kind: 9, amount: 1, threshold: 1, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 9, amount: 1, threshold: 2, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ccaa32454a304e1f96d6d340b9c1900e
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Sshd
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_sshd
|
||||||
|
displayName: sshd
|
||||||
|
slot: 2
|
||||||
|
rarity: 2
|
||||||
|
description: Every 3rd TURN, gain 3 Shield.
|
||||||
|
flavourText: Open port, closed heart.
|
||||||
|
designNotes: Generic 2-star Daemon. Existing nth-TURN shield hook.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 6, amount: 3, threshold: 3, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 6, amount: 3, threshold: 3, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: f3174349716e4db6a7ffed8205f2a541
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Swapfile
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_swapfile
|
||||||
|
displayName: swapfile
|
||||||
|
slot: 0
|
||||||
|
rarity: 2
|
||||||
|
description: +1 max RAM (COMBAT).
|
||||||
|
flavourText: RAM, but with the emotional latency of a spinning disk.
|
||||||
|
designNotes: Generic 2-star Kernel. COMBAT RAM stat package.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 19, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 19, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a48fbfda32824a7cb127318c93602420
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Syslog
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_syslog
|
||||||
|
displayName: syslog
|
||||||
|
slot: 2
|
||||||
|
rarity: 1
|
||||||
|
description: When you exhaust a card, gain 1 Shield.
|
||||||
|
flavourText: Writes down the problem, then pretends that helped.
|
||||||
|
designNotes: Generic 1-star Daemon. Existing exhaust shield hook.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 7, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 7, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 302d3da8597941ea99c6d507fa9d3d28
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: SystemdCore
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_systemd_core
|
||||||
|
displayName: systemd-core
|
||||||
|
slot: 0
|
||||||
|
rarity: 3
|
||||||
|
description: +1 max Cycles (COMBAT).
|
||||||
|
flavourText: Yes, it manages that too.
|
||||||
|
designNotes: Generic 3-star Kernel powerspike. COMBAT max Cycle package. On/off distro identical.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 2, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 2, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7b77920d46a0434ab4e772339293d991
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: SystemdTimer
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_systemd_timer
|
||||||
|
displayName: systemd-timer
|
||||||
|
slot: 2
|
||||||
|
rarity: 3
|
||||||
|
description: Every 3rd card played in a WAVE, gain 1 Cycle.
|
||||||
|
flavourText: Cron with a committee and better unit files.
|
||||||
|
designNotes: Generic 3-star Daemon powerspike. Nth-card WAVE cycle hook.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 24, amount: 1, threshold: 3, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 24, amount: 1, threshold: 3, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: ac481beaf7e6453d82a439d54c2fb2f3
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
%YAML 1.1
|
||||||
|
%TAG !u! tag:unity3d.com,2011:
|
||||||
|
--- !u!114 &11400000
|
||||||
|
MonoBehaviour:
|
||||||
|
m_Script: {fileID: 11500000, guid: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: TimeshiftPackage
|
||||||
|
id: pkg_mint_timeshift
|
||||||
|
displayName: Timeshift
|
||||||
|
slot: 0
|
||||||
|
rarity: 5
|
||||||
|
description: First time each WAVE Uptime would drop below a threshold, restore to it; 50% + cleanse on Mint, 30% off-distro.
|
||||||
|
flavourText: Undo button for bad life choices.
|
||||||
|
designNotes: Mint 5-star Kernel. WAVE damage/heal hook through DamagePipeline event; status cleanse on Mint only.
|
||||||
|
intendedDistroId: mint
|
||||||
|
requiresSystem:
|
||||||
|
- damage-pipeline-hook
|
||||||
|
- status-cleanse
|
||||||
|
offDistroEffect: {kind: 12, amount: 0, threshold: 30, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 12, amount: 0, threshold: 50, refundCycle: 0, cleanseDebuffs: 1, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 07554ac885824a6e8e49d7d39cf2fa30
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Udev
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_udev
|
||||||
|
displayName: udev
|
||||||
|
slot: 2
|
||||||
|
rarity: 1
|
||||||
|
description: Every 4th TURN, draw 1 card.
|
||||||
|
flavourText: A device appeared, so naturally you drew paperwork.
|
||||||
|
designNotes: Generic 1-star Daemon. TURN draw hook.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 22, amount: 1, threshold: 4, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 22, amount: 1, threshold: 4, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 177e5f43f6544549bf12e02ec05ec833
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Vim
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_vim
|
||||||
|
displayName: vim
|
||||||
|
slot: 1
|
||||||
|
rarity: 2
|
||||||
|
description: First card played each TURN costs 1 less.
|
||||||
|
flavourText: Modal editing for modal spending.
|
||||||
|
designNotes: Generic 2-star Runtime. Existing first-card-per-TURN cost hook.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 9, amount: 1, threshold: 1, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 9, amount: 1, threshold: 1, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: a3b1582341434a8981c802f8d7da2420
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Wget
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_wget
|
||||||
|
displayName: wget
|
||||||
|
slot: 1
|
||||||
|
rarity: 1
|
||||||
|
description: Draw 1 extra card on the first TURN of the first WAVE.
|
||||||
|
flavourText: Downloads one more thing before anyone reads the flags.
|
||||||
|
designNotes: Generic 1-star Runtime. First WAVE opening draw hook.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 17, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 17, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 19d4c144fb5c4ae3b0bccb4b048aaa96
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Zlib
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_zlib
|
||||||
|
displayName: zlib
|
||||||
|
slot: 0
|
||||||
|
rarity: 1
|
||||||
|
description: Start each WAVE with 3 Shield.
|
||||||
|
flavourText: Compresses incoming panic into a smaller panic.
|
||||||
|
designNotes: Generic 1-star Kernel. WAVE shield hook.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 15, amount: 3, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 15, amount: 3, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 40d2efb5aa8d4b85a4bdc7b3cb7781d8
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
%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: 48447d3db18343398488d3064324147d, type: 3}
|
||||||
|
m_Name: Zram
|
||||||
|
m_EditorClassIdentifier:
|
||||||
|
id: pkg_zram
|
||||||
|
displayName: zram
|
||||||
|
slot: 0
|
||||||
|
rarity: 3
|
||||||
|
description: +1 max Cycles (COMBAT).
|
||||||
|
flavourText: Compress the pain until it becomes throughput.
|
||||||
|
designNotes: Generic 3-star Kernel powerspike. COMBAT cycle stat package.
|
||||||
|
intendedDistroId:
|
||||||
|
requiresSystem: []
|
||||||
|
offDistroEffect: {kind: 2, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
|
onDistroEffect: {kind: 2, amount: 1, threshold: 0, refundCycle: 0, cleanseDebuffs: 0, enableFedoraSecondCardPassive: 0}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0a11dac6bc6d435192a262eb1d8ac685
|
||||||
|
NativeFormatImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
mainObjectFileID: 11400000
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@@ -274,5 +274,6 @@ MonoBehaviour:
|
|||||||
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: 1632132e32bfc31e8a293140f5908aa3, type: 2}
|
cardDatabase: {fileID: 11400000, guid: 1632132e32bfc31e8a293140f5908aa3, type: 2}
|
||||||
|
packageDatabase: {fileID: 11400000, guid: efca08b3991e42e5b1e03878507496a6, type: 2}
|
||||||
languageDeckDatabase: {fileID: 11400000, guid: a7d20000000000000000000000000001, type: 2}
|
languageDeckDatabase: {fileID: 11400000, guid: a7d20000000000000000000000000001, type: 2}
|
||||||
featuredUnitPanel: {}
|
featuredUnitPanel: {}
|
||||||
|
|||||||
@@ -84,8 +84,7 @@ namespace KernelPanic.Combat
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Source.Shield += amount;
|
context.CombatManager.GrantPlayerShield(amount, "card");
|
||||||
context.CombatManager.ReportEffectResult($"gained {amount} shield");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,8 +109,7 @@ namespace KernelPanic.Combat
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Source.Shield += amount;
|
context.CombatManager.GrantPlayerShield(amount, "card");
|
||||||
context.CombatManager.ReportEffectResult($"gained {amount} shield");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -502,8 +500,7 @@ namespace KernelPanic.Combat
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Source.Shield += overkill;
|
context.CombatManager.GrantPlayerShield(overkill, "overkill");
|
||||||
context.CombatManager.ReportEffectResult($"overkill -> {overkill} shield");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -572,6 +569,7 @@ namespace KernelPanic.Combat
|
|||||||
if (context.HandController.Remove(junk))
|
if (context.HandController.Remove(junk))
|
||||||
{
|
{
|
||||||
context.DeckController.Exhaust(junk);
|
context.DeckController.Exhaust(junk);
|
||||||
|
context.CombatManager.HandleCardExhausted(junk);
|
||||||
int cycleGain = UpgradeMath.ScaleAmount(_cycleGain, context.Card);
|
int cycleGain = UpgradeMath.ScaleAmount(_cycleGain, context.Card);
|
||||||
context.Source.Cycles += cycleGain;
|
context.Source.Cycles += cycleGain;
|
||||||
context.CombatManager.ReportEffectResult($"autoremove exhausted {GetCardName(junk)}: +{cycleGain} cycle");
|
context.CombatManager.ReportEffectResult($"autoremove exhausted {GetCardName(junk)}: +{cycleGain} cycle");
|
||||||
|
|||||||
@@ -41,6 +41,12 @@ namespace KernelPanic.Combat
|
|||||||
private int fedoraCardsDiscountedThisTurn;
|
private int fedoraCardsDiscountedThisTurn;
|
||||||
private int fedoraCrashChance = 10;
|
private int fedoraCrashChance = 10;
|
||||||
private int cardsPlayedThisTurn;
|
private int cardsPlayedThisTurn;
|
||||||
|
private int cardsPlayedThisWave;
|
||||||
|
private int turnNumberThisWave;
|
||||||
|
private bool packageShieldBonusTriggeredThisTurn;
|
||||||
|
private bool packageTimeshiftTriggeredThisWave;
|
||||||
|
private bool packageInterpreterQueueShieldTriggeredThisWave;
|
||||||
|
private bool packageNativeDamageTriggeredThisWave;
|
||||||
private int javaCardsPlayedThisCombat;
|
private int javaCardsPlayedThisCombat;
|
||||||
private int javaCardsDiscountThisTurn;
|
private int javaCardsDiscountThisTurn;
|
||||||
private int rawhideBonusCharges;
|
private int rawhideBonusCharges;
|
||||||
@@ -72,6 +78,16 @@ namespace KernelPanic.Combat
|
|||||||
runManager = GetComponent<RunManager>();
|
runManager = GetComponent<RunManager>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void OnEnable()
|
||||||
|
{
|
||||||
|
GameEvents.DamageDealt += HandlePackageDamageDealt;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDisable()
|
||||||
|
{
|
||||||
|
GameEvents.DamageDealt -= HandlePackageDamageDealt;
|
||||||
|
}
|
||||||
|
|
||||||
public void StartCombat()
|
public void StartCombat()
|
||||||
{
|
{
|
||||||
if (runConfig == null)
|
if (runConfig == null)
|
||||||
@@ -197,6 +213,7 @@ namespace KernelPanic.Combat
|
|||||||
ResolutionTrack track = card.Definition.ResolutionTrack;
|
ResolutionTrack track = card.Definition.ResolutionTrack;
|
||||||
card.MarkPlayedThisTurn(cardsPlayedThisTurn == 0);
|
card.MarkPlayedThisTurn(cardsPlayedThisTurn == 0);
|
||||||
cardsPlayedThisTurn++;
|
cardsPlayedThisTurn++;
|
||||||
|
cardsPlayedThisWave++;
|
||||||
if (card.Definition.Language == Language.Java)
|
if (card.Definition.Language == Language.Java)
|
||||||
{
|
{
|
||||||
javaCardsPlayedThisCombat++;
|
javaCardsPlayedThisCombat++;
|
||||||
@@ -256,6 +273,7 @@ namespace KernelPanic.Combat
|
|||||||
}
|
}
|
||||||
|
|
||||||
playerState.DamageMultiplierPercent = 100;
|
playerState.DamageMultiplierPercent = 100;
|
||||||
|
ApplyPackageCardPlayedEffects(card);
|
||||||
|
|
||||||
pendingTargetCard = null;
|
pendingTargetCard = null;
|
||||||
TryApplyUbuntuEmptyHandRefill();
|
TryApplyUbuntuEmptyHandRefill();
|
||||||
@@ -281,6 +299,7 @@ namespace KernelPanic.Combat
|
|||||||
cost -= javaCardsPlayedThisCombat + javaCardsDiscountThisTurn;
|
cost -= javaCardsPlayedThisCombat + javaCardsDiscountThisTurn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cost = ApplyPackageCostRules(card, cost);
|
||||||
return Mathf.Max(0, cost);
|
return Mathf.Max(0, cost);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,6 +379,16 @@ namespace KernelPanic.Combat
|
|||||||
ReportEffectResult($"next {charges} enemy attack(s) halved");
|
ReportEffectResult($"next {charges} enemy attack(s) halved");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void HandleCardExhausted(CardInstance card)
|
||||||
|
{
|
||||||
|
if (card == null || !HasPackageEffect(PackageEffectKind.ExhaustShield, out PackageEffectData effect))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GrantPlayerShield(Mathf.Max(0, effect.Amount), "logrotate");
|
||||||
|
}
|
||||||
|
|
||||||
public void ScheduleUpdateManagerRepeat(int damageAmount)
|
public void ScheduleUpdateManagerRepeat(int damageAmount)
|
||||||
{
|
{
|
||||||
delayedEffects.Add(DelayedCombatEffect.UpdateManagerRepeat(damageAmount, 2));
|
delayedEffects.Add(DelayedCombatEffect.UpdateManagerRepeat(damageAmount, 2));
|
||||||
@@ -536,6 +565,12 @@ namespace KernelPanic.Combat
|
|||||||
fedoraCrashChance = 10;
|
fedoraCrashChance = 10;
|
||||||
fedoraCardsDiscountedThisTurn = 0;
|
fedoraCardsDiscountedThisTurn = 0;
|
||||||
cardsPlayedThisTurn = 0;
|
cardsPlayedThisTurn = 0;
|
||||||
|
cardsPlayedThisWave = 0;
|
||||||
|
turnNumberThisWave = 0;
|
||||||
|
packageShieldBonusTriggeredThisTurn = false;
|
||||||
|
packageTimeshiftTriggeredThisWave = false;
|
||||||
|
packageInterpreterQueueShieldTriggeredThisWave = false;
|
||||||
|
packageNativeDamageTriggeredThisWave = false;
|
||||||
javaCardsPlayedThisCombat = 0;
|
javaCardsPlayedThisCombat = 0;
|
||||||
javaCardsDiscountThisTurn = 0;
|
javaCardsDiscountThisTurn = 0;
|
||||||
rawhideBonusCharges = 0;
|
rawhideBonusCharges = 0;
|
||||||
@@ -545,6 +580,7 @@ namespace KernelPanic.Combat
|
|||||||
RandomRoll.Seed(runConfig.RunSeed);
|
RandomRoll.Seed(runConfig.RunSeed);
|
||||||
playerState = new CombatantState(runManager.EffectiveMaxUptime(), runManager.EffectiveRam(), runManager.EffectiveMaxCycles());
|
playerState = new CombatantState(runManager.EffectiveMaxUptime(), runManager.EffectiveRam(), runManager.EffectiveMaxCycles());
|
||||||
ApplyVersionState(playerState);
|
ApplyVersionState(playerState);
|
||||||
|
ApplyPackageState(playerState);
|
||||||
yield return StartWaveSequenced(preservePlayerUptime: false);
|
yield return StartWaveSequenced(preservePlayerUptime: false);
|
||||||
Log($"booted {runConfig.Distro.DisplayName} with {runManager.RunDeck.Count} cards");
|
Log($"booted {runConfig.Distro.DisplayName} with {runManager.RunDeck.Count} cards");
|
||||||
StateChanged?.Invoke();
|
StateChanged?.Invoke();
|
||||||
@@ -557,6 +593,7 @@ namespace KernelPanic.Combat
|
|||||||
{
|
{
|
||||||
playerState = new CombatantState(runManager.EffectiveMaxUptime(), runManager.EffectiveRam(), runManager.EffectiveMaxCycles());
|
playerState = new CombatantState(runManager.EffectiveMaxUptime(), runManager.EffectiveRam(), runManager.EffectiveMaxCycles());
|
||||||
ApplyVersionState(playerState);
|
ApplyVersionState(playerState);
|
||||||
|
ApplyPackageState(playerState);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -570,11 +607,16 @@ namespace KernelPanic.Combat
|
|||||||
playerState.IsDefeated = false;
|
playerState.IsDefeated = false;
|
||||||
playerState.MutableStatuses.Clear();
|
playerState.MutableStatuses.Clear();
|
||||||
ApplyVersionState(playerState);
|
ApplyVersionState(playerState);
|
||||||
|
ApplyPackageState(playerState);
|
||||||
}
|
}
|
||||||
|
|
||||||
handController = new HandController(playerState.Ram);
|
handController = new HandController(playerState.Ram);
|
||||||
selectedEnemyIndex = -1;
|
selectedEnemyIndex = -1;
|
||||||
pendingTargetCard = null;
|
pendingTargetCard = null;
|
||||||
|
cardsPlayedThisWave = 0;
|
||||||
|
turnNumberThisWave = 0;
|
||||||
|
packageShieldBonusTriggeredThisTurn = false;
|
||||||
|
packageTimeshiftTriggeredThisWave = false;
|
||||||
|
|
||||||
List<CardInstance> startingCards = new();
|
List<CardInstance> startingCards = new();
|
||||||
for (int i = 0; i < runManager.RunDeck.Count; i++)
|
for (int i = 0; i < runManager.RunDeck.Count; i++)
|
||||||
@@ -594,6 +636,7 @@ namespace KernelPanic.Combat
|
|||||||
PickEnemyIntents();
|
PickEnemyIntents();
|
||||||
StateChanged?.Invoke();
|
StateChanged?.Invoke();
|
||||||
yield return DrawOpeningHandSequenced();
|
yield return DrawOpeningHandSequenced();
|
||||||
|
ApplyPackageWaveStartEffects();
|
||||||
skipNextAllocateDraw = true;
|
skipNextAllocateDraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -607,7 +650,10 @@ namespace KernelPanic.Combat
|
|||||||
playerState.Cycles = playerState.MaxCycles;
|
playerState.Cycles = playerState.MaxCycles;
|
||||||
fedoraCardsDiscountedThisTurn = 0;
|
fedoraCardsDiscountedThisTurn = 0;
|
||||||
cardsPlayedThisTurn = 0;
|
cardsPlayedThisTurn = 0;
|
||||||
|
turnNumberThisWave++;
|
||||||
|
packageShieldBonusTriggeredThisTurn = false;
|
||||||
javaCardsDiscountThisTurn = 0;
|
javaCardsDiscountThisTurn = 0;
|
||||||
|
ApplyPackageTurnStartEffects();
|
||||||
if (nextTurnCycleBonus > 0)
|
if (nextTurnCycleBonus > 0)
|
||||||
{
|
{
|
||||||
playerState.Cycles += nextTurnCycleBonus;
|
playerState.Cycles += nextTurnCycleBonus;
|
||||||
@@ -852,7 +898,7 @@ namespace KernelPanic.Combat
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int limit = runConfig.DistroVersion >= 5 ? 2 : 1;
|
int limit = runConfig.DistroVersion >= 5 || HasOnDistroPackageEffect(PackageEffectKind.DnfFedoraPassive, out PackageEffectData dnfEffect) && dnfEffect.EnableFedoraSecondCardPassive ? 2 : 1;
|
||||||
return fedoraCardsDiscountedThisTurn < limit;
|
return fedoraCardsDiscountedThisTurn < limit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -870,6 +916,360 @@ namespace KernelPanic.Combat
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int ApplyPackageCostRules(CardInstance card, int cost)
|
||||||
|
{
|
||||||
|
if (card == null || cost <= 0)
|
||||||
|
{
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
IReadOnlyList<PackageInstance> packages = runConfig?.EquippedPackages;
|
||||||
|
if (packages == null)
|
||||||
|
{
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nextTurnCard = cardsPlayedThisTurn + 1;
|
||||||
|
int nextWaveCard = cardsPlayedThisWave + 1;
|
||||||
|
for (int i = 0; i < packages.Count; i++)
|
||||||
|
{
|
||||||
|
PackageInstance package = packages[i];
|
||||||
|
if (package?.Definition == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackageEffectData effect = package.EffectFor(runConfig?.Distro?.Id);
|
||||||
|
switch (effect.Kind)
|
||||||
|
{
|
||||||
|
case PackageEffectKind.FirstCardEachWaveCostReduction:
|
||||||
|
if (nextWaveCard == 1)
|
||||||
|
{
|
||||||
|
cost -= Mathf.Max(0, effect.Amount);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PackageEffectKind.EveryNthCardEachWaveFree:
|
||||||
|
if (effect.Threshold > 0 && nextWaveCard % effect.Threshold == 0)
|
||||||
|
{
|
||||||
|
cost = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PackageEffectKind.FirstCardsEachTurnCostReduction:
|
||||||
|
if (nextTurnCard <= Mathf.Max(0, effect.Threshold))
|
||||||
|
{
|
||||||
|
cost -= Mathf.Max(0, effect.Amount);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cost;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyPackageState(CombatantState state)
|
||||||
|
{
|
||||||
|
if (state == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state.JavaScriptFlatDamageBonus = 0;
|
||||||
|
IReadOnlyList<PackageInstance> packages = runConfig?.EquippedPackages;
|
||||||
|
if (packages == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < packages.Count; i++)
|
||||||
|
{
|
||||||
|
PackageEffectData effect = packages[i] == null ? default : packages[i].EffectFor(runConfig?.Distro?.Id);
|
||||||
|
if (effect.Kind == PackageEffectKind.JavaScriptFlatDamage)
|
||||||
|
{
|
||||||
|
state.JavaScriptFlatDamageBonus += Mathf.Max(0, effect.Amount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyPackageWaveStartEffects()
|
||||||
|
{
|
||||||
|
IReadOnlyList<PackageInstance> packages = runConfig?.EquippedPackages;
|
||||||
|
if (packages == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < packages.Count; i++)
|
||||||
|
{
|
||||||
|
PackageInstance package = packages[i];
|
||||||
|
if (package?.Definition == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackageEffectData effect = package.EffectFor(runConfig?.Distro?.Id);
|
||||||
|
switch (effect.Kind)
|
||||||
|
{
|
||||||
|
case PackageEffectKind.WaveDraw:
|
||||||
|
StartCoroutine(DrawCardsToHandSequenced(Mathf.Max(0, effect.Amount), package.Definition.DisplayName));
|
||||||
|
break;
|
||||||
|
case PackageEffectKind.WaveStartShield:
|
||||||
|
GrantPlayerShield(Mathf.Max(0, effect.Amount), package.Definition.DisplayName);
|
||||||
|
break;
|
||||||
|
case PackageEffectKind.FirstTurnEachWaveShield:
|
||||||
|
if (turnNumberThisWave == 0)
|
||||||
|
{
|
||||||
|
GrantPlayerShield(Mathf.Max(0, effect.Amount), package.Definition.DisplayName);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PackageEffectKind.FirstTurnFirstWaveDraw:
|
||||||
|
if (CurrentWaveNumber == 1 && turnNumberThisWave == 0)
|
||||||
|
{
|
||||||
|
StartCoroutine(DrawCardsToHandSequenced(Mathf.Max(0, effect.Amount), package.Definition.DisplayName));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PackageEffectKind.WaveGenerateBasicCard:
|
||||||
|
GeneratePackageLanguageCard(package.Definition.DisplayName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyPackageTurnStartEffects()
|
||||||
|
{
|
||||||
|
if (HasPackageEffect(PackageEffectKind.EveryNthTurnShield, out PackageEffectData effect)
|
||||||
|
&& effect.Threshold > 0
|
||||||
|
&& turnNumberThisWave % effect.Threshold == 0)
|
||||||
|
{
|
||||||
|
GrantPlayerShield(Mathf.Max(0, effect.Amount), "cron");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasPackageEffect(PackageEffectKind.EveryNthTurnDraw, out effect)
|
||||||
|
&& effect.Threshold > 0
|
||||||
|
&& turnNumberThisWave % effect.Threshold == 0)
|
||||||
|
{
|
||||||
|
StartCoroutine(DrawCardsToHandSequenced(Mathf.Max(0, effect.Amount), "udev"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (turnNumberThisWave == 1
|
||||||
|
&& HasPackageEffect(PackageEffectKind.FirstTurnEachWaveCycle, out effect)
|
||||||
|
&& effect.Amount > 0)
|
||||||
|
{
|
||||||
|
playerState.Cycles += effect.Amount;
|
||||||
|
Log($"apt-fast: gained {effect.Amount} Cycle");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasPackageEffect(PackageEffectKind.StartTurnNoDebuffShield, out effect)
|
||||||
|
&& !HasHarmfulStatus(playerState))
|
||||||
|
{
|
||||||
|
GrantPlayerShield(Mathf.Max(0, effect.Amount), "auditd");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyPackageCardPlayedEffects(CardInstance card)
|
||||||
|
{
|
||||||
|
if (card == null || playerState == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasPackageEffect(PackageEffectKind.ThirdCardEachTurnGenerate, out PackageEffectData aptEffect)
|
||||||
|
&& cardsPlayedThisTurn == Mathf.Max(1, aptEffect.Threshold))
|
||||||
|
{
|
||||||
|
GeneratePackageLanguageCard("apt");
|
||||||
|
if (aptEffect.RefundCycle)
|
||||||
|
{
|
||||||
|
playerState.Cycles += 1;
|
||||||
|
Log("apt refunded 1 Cycle");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasPackageEffect(PackageEffectKind.DnfFedoraPassive, out PackageEffectData dnfEffect)
|
||||||
|
&& cardsPlayedThisTurn == 1
|
||||||
|
&& dnfEffect.Amount > 0)
|
||||||
|
{
|
||||||
|
playerState.FlatEffectBonus += dnfEffect.Amount;
|
||||||
|
Log($"DNF wave buff +{dnfEffect.Amount} damage");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!packageInterpreterQueueShieldTriggeredThisWave
|
||||||
|
&& card.Definition.ResolutionTrack == ResolutionTrack.InterpreterQueue
|
||||||
|
&& HasPackageEffect(PackageEffectKind.FirstInterpreterQueueCardEachWaveShield, out PackageEffectData queueEffect))
|
||||||
|
{
|
||||||
|
packageInterpreterQueueShieldTriggeredThisWave = true;
|
||||||
|
GrantPlayerShield(Mathf.Max(0, queueEffect.Amount), "dbus");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!packageNativeDamageTriggeredThisWave
|
||||||
|
&& card.Definition.ResolutionTrack == ResolutionTrack.Native
|
||||||
|
&& HasPackageEffect(PackageEffectKind.FirstNativeCardEachWaveFlatDamage, out PackageEffectData nativeEffect)
|
||||||
|
&& nativeEffect.Amount > 0)
|
||||||
|
{
|
||||||
|
packageNativeDamageTriggeredThisWave = true;
|
||||||
|
playerState.FlatEffectBonus += nativeEffect.Amount;
|
||||||
|
Log($"make: first Native card +{nativeEffect.Amount} damage");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HasPackageEffect(PackageEffectKind.EveryNthCardEachWaveCycle, out PackageEffectData cycleEffect)
|
||||||
|
&& cycleEffect.Threshold > 0
|
||||||
|
&& cardsPlayedThisWave % cycleEffect.Threshold == 0
|
||||||
|
&& cycleEffect.Amount > 0)
|
||||||
|
{
|
||||||
|
playerState.Cycles += cycleEffect.Amount;
|
||||||
|
Log($"systemd-timer: gained {cycleEffect.Amount} Cycle");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void GrantPlayerShield(int amount, string label)
|
||||||
|
{
|
||||||
|
if (playerState == null || amount <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int total = amount;
|
||||||
|
if (!packageShieldBonusTriggeredThisTurn
|
||||||
|
&& HasPackageEffect(PackageEffectKind.FirstShieldEachTurnBonus, out PackageEffectData effect))
|
||||||
|
{
|
||||||
|
int bonus = Mathf.Max(0, effect.Amount);
|
||||||
|
if (bonus > 0)
|
||||||
|
{
|
||||||
|
total += bonus;
|
||||||
|
packageShieldBonusTriggeredThisTurn = true;
|
||||||
|
Log($"SELinux shield +{bonus}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
playerState.Shield += total;
|
||||||
|
if (!string.IsNullOrWhiteSpace(label))
|
||||||
|
{
|
||||||
|
Log($"{label}: gained {total} Shield");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GeneratePackageLanguageCard(string label)
|
||||||
|
{
|
||||||
|
if (handController == null || handController.RemainingRam <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Language language = RandomRoll.RollRange(0, 1, new RollContext(playerState)) == 0
|
||||||
|
? runConfig.PrimaryLanguage
|
||||||
|
: runConfig.SecondaryLanguage;
|
||||||
|
|
||||||
|
if (!TryCreateGeneratedCard(language, Rarity.Common, out CardInstance generated))
|
||||||
|
{
|
||||||
|
Log($"{label}: TODO card-generation pool unavailable");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (handController.Add(generated))
|
||||||
|
{
|
||||||
|
Log($"{label}: generated {GetCardName(generated)} at 0c");
|
||||||
|
StateChanged?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandlePackageDamageDealt(DamageDealtEvent payload)
|
||||||
|
{
|
||||||
|
if (payload.Target != playerState
|
||||||
|
|| payload.UptimeDamage <= 0
|
||||||
|
|| packageTimeshiftTriggeredThisWave
|
||||||
|
|| !HasPackageEffect(PackageEffectKind.WaveThresholdRestore, out PackageEffectData effect))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int thresholdPercent = Mathf.Clamp(effect.Threshold, 1, 100);
|
||||||
|
int restoreTarget = Mathf.CeilToInt(playerState.MaxUptime * (thresholdPercent / 100f));
|
||||||
|
if (playerState.CurrentUptime >= restoreTarget)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
packageTimeshiftTriggeredThisWave = true;
|
||||||
|
playerState.CurrentUptime = restoreTarget;
|
||||||
|
if (effect.CleanseDebuffs)
|
||||||
|
{
|
||||||
|
statusEffects.CleanseHarmful(playerState);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log($"Timeshift restored uptime to {thresholdPercent}%");
|
||||||
|
StateChanged?.Invoke();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasOnDistroPackageEffect(PackageEffectKind kind, out PackageEffectData effect)
|
||||||
|
{
|
||||||
|
effect = default;
|
||||||
|
IReadOnlyList<PackageInstance> packages = runConfig?.EquippedPackages;
|
||||||
|
if (packages == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < packages.Count; i++)
|
||||||
|
{
|
||||||
|
PackageInstance package = packages[i];
|
||||||
|
if (package?.Definition == null || !package.Definition.IsIntendedFor(runConfig?.Distro?.Id))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
effect = package.EffectFor(runConfig?.Distro?.Id);
|
||||||
|
if (effect.Kind == kind)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasPackageEffect(PackageEffectKind kind, out PackageEffectData effect)
|
||||||
|
{
|
||||||
|
effect = default;
|
||||||
|
IReadOnlyList<PackageInstance> packages = runConfig?.EquippedPackages;
|
||||||
|
if (packages == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < packages.Count; i++)
|
||||||
|
{
|
||||||
|
PackageInstance package = packages[i];
|
||||||
|
if (package?.Definition == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
effect = package.EffectFor(runConfig?.Distro?.Id);
|
||||||
|
if (effect.Kind == kind)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool HasHarmfulStatus(CombatantState state)
|
||||||
|
{
|
||||||
|
if (state == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < state.Statuses.Count; i++)
|
||||||
|
{
|
||||||
|
if (!StatusEffectController.GetDescriptor(state.Statuses[i].Type).IsBeneficial)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static bool IsCrashImmune(CardInstance card)
|
private static bool IsCrashImmune(CardInstance card)
|
||||||
{
|
{
|
||||||
string id = card?.Definition?.Id;
|
string id = card?.Definition?.Id;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ namespace KernelPanic.Combat
|
|||||||
public bool IgnoreDamageMultipliers { get; set; }
|
public bool IgnoreDamageMultipliers { get; set; }
|
||||||
public bool AllowFlatDamageBuffs { get; set; }
|
public bool AllowFlatDamageBuffs { get; set; }
|
||||||
public int FlatEffectBonus { get; set; }
|
public int FlatEffectBonus { get; set; }
|
||||||
|
public int JavaScriptFlatDamageBonus { get; set; }
|
||||||
public int DamageMultiplierPercent { get; set; } = 100;
|
public int DamageMultiplierPercent { get; set; } = 100;
|
||||||
public int IncomingAttackHalfCharges { get; set; }
|
public int IncomingAttackHalfCharges { get; set; }
|
||||||
public IReadOnlyList<StatusInstance> Statuses => _statuses;
|
public IReadOnlyList<StatusInstance> Statuses => _statuses;
|
||||||
|
|||||||
@@ -64,6 +64,7 @@ namespace KernelPanic.Combat
|
|||||||
}
|
}
|
||||||
|
|
||||||
int amount = Mathf.Max(0, request.Amount);
|
int amount = Mathf.Max(0, request.Amount);
|
||||||
|
amount = ApplyFlatAdditions(amount, request);
|
||||||
amount = ApplyMultipliers(amount, request);
|
amount = ApplyMultipliers(amount, request);
|
||||||
amount = ApplyCrit(amount, request, out bool wasCritical);
|
amount = ApplyCrit(amount, request, out bool wasCritical);
|
||||||
amount = ApplyResistancesAndWeaknesses(amount, request);
|
amount = ApplyResistancesAndWeaknesses(amount, request);
|
||||||
@@ -95,6 +96,16 @@ namespace KernelPanic.Combat
|
|||||||
return Mathf.RoundToInt(amount * (multiplier / 100f));
|
return Mathf.RoundToInt(amount * (multiplier / 100f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int ApplyFlatAdditions(int amount, DamageRequest request)
|
||||||
|
{
|
||||||
|
if (request.Source != null && request.Language == Language.JavaScript)
|
||||||
|
{
|
||||||
|
amount += Mathf.Max(0, request.Source.JavaScriptFlatDamageBonus);
|
||||||
|
}
|
||||||
|
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
private static int ApplyCrit(int amount, DamageRequest request, out bool wasCritical)
|
private static int ApplyCrit(int amount, DamageRequest request, out bool wasCritical)
|
||||||
{
|
{
|
||||||
wasCritical = false;
|
wasCritical = false;
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace KernelPanic.Data
|
||||||
|
{
|
||||||
|
public sealed class PackageDatabase : ScriptableObject
|
||||||
|
{
|
||||||
|
[SerializeField] private List<PackageDefinition> allPackages = new();
|
||||||
|
|
||||||
|
public IReadOnlyList<PackageDefinition> AllPackages => allPackages;
|
||||||
|
|
||||||
|
public PackageDefinition FindById(string id)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(id))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < allPackages.Count; i++)
|
||||||
|
{
|
||||||
|
PackageDefinition package = allPackages[i];
|
||||||
|
if (package != null && string.Equals(package.Id, id, System.StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return package;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PackageDefinition FindByRarity(int rarity, int index)
|
||||||
|
{
|
||||||
|
int safeRarity = Mathf.Clamp(rarity, 1, 5);
|
||||||
|
int matchIndex = 0;
|
||||||
|
for (int i = 0; i < allPackages.Count; i++)
|
||||||
|
{
|
||||||
|
PackageDefinition package = allPackages[i];
|
||||||
|
if (package == null || package.Rarity != safeRarity)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchIndex == index)
|
||||||
|
{
|
||||||
|
return package;
|
||||||
|
}
|
||||||
|
|
||||||
|
matchIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int CountByRarity(int rarity)
|
||||||
|
{
|
||||||
|
int safeRarity = Mathf.Clamp(rarity, 1, 5);
|
||||||
|
int count = 0;
|
||||||
|
for (int i = 0; i < allPackages.Count; i++)
|
||||||
|
{
|
||||||
|
if (allPackages[i] != null && allPackages[i].Rarity == safeRarity)
|
||||||
|
{
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,166 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace KernelPanic.Data
|
||||||
|
{
|
||||||
|
public enum PackageSlot
|
||||||
|
{
|
||||||
|
Kernel,
|
||||||
|
Runtime,
|
||||||
|
Daemon
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum PackageEffectKind
|
||||||
|
{
|
||||||
|
None = 0,
|
||||||
|
MaxUptime = 1,
|
||||||
|
MaxCycles = 2,
|
||||||
|
WaveDraw = 3,
|
||||||
|
WaveGenerateBasicCard = 4,
|
||||||
|
FirstCardEachWaveCostReduction = 5,
|
||||||
|
EveryNthTurnShield = 6,
|
||||||
|
ExhaustShield = 7,
|
||||||
|
EveryNthCardEachWaveFree = 8,
|
||||||
|
FirstCardsEachTurnCostReduction = 9,
|
||||||
|
ThirdCardEachTurnGenerate = 10,
|
||||||
|
JavaScriptFlatDamage = 11,
|
||||||
|
WaveThresholdRestore = 12,
|
||||||
|
FirstShieldEachTurnBonus = 13,
|
||||||
|
DnfFedoraPassive = 14,
|
||||||
|
WaveStartShield = 15,
|
||||||
|
FirstTurnEachWaveShield = 16,
|
||||||
|
FirstTurnFirstWaveDraw = 17,
|
||||||
|
FirstTurnEachWaveCycle = 18,
|
||||||
|
MaxRam = 19,
|
||||||
|
FirstNativeCardEachWaveFlatDamage = 20,
|
||||||
|
FirstInterpreterQueueCardEachWaveShield = 21,
|
||||||
|
EveryNthTurnDraw = 22,
|
||||||
|
StartTurnNoDebuffShield = 23,
|
||||||
|
EveryNthCardEachWaveCycle = 24
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public struct PackageEffectData
|
||||||
|
{
|
||||||
|
[SerializeField] private PackageEffectKind kind;
|
||||||
|
[SerializeField] private int amount;
|
||||||
|
[SerializeField] private int threshold;
|
||||||
|
[SerializeField] private bool refundCycle;
|
||||||
|
[SerializeField] private bool cleanseDebuffs;
|
||||||
|
[SerializeField] private bool enableFedoraSecondCardPassive;
|
||||||
|
|
||||||
|
public PackageEffectData(PackageEffectKind kind, int amount, int threshold, bool refundCycle, bool cleanseDebuffs, bool enableFedoraSecondCardPassive)
|
||||||
|
{
|
||||||
|
this.kind = kind;
|
||||||
|
this.amount = amount;
|
||||||
|
this.threshold = threshold;
|
||||||
|
this.refundCycle = refundCycle;
|
||||||
|
this.cleanseDebuffs = cleanseDebuffs;
|
||||||
|
this.enableFedoraSecondCardPassive = enableFedoraSecondCardPassive;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PackageEffectKind Kind => kind;
|
||||||
|
public int Amount => amount;
|
||||||
|
public int Threshold => threshold;
|
||||||
|
public bool RefundCycle => refundCycle;
|
||||||
|
public bool CleanseDebuffs => cleanseDebuffs;
|
||||||
|
public bool EnableFedoraSecondCardPassive => enableFedoraSecondCardPassive;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Defines persistent meta packages equipped into distro Kernel/Runtime/Daemon slots.
|
||||||
|
/// Package loadouts are meta progression and carry into every run for that distro.
|
||||||
|
/// Card loadouts remain run setup only.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class PackageDefinition : ScriptableObject
|
||||||
|
{
|
||||||
|
[SerializeField] private string id;
|
||||||
|
[SerializeField] private string displayName;
|
||||||
|
[SerializeField] private PackageSlot slot;
|
||||||
|
[SerializeField, Range(1, 5)] private int rarity = 1;
|
||||||
|
[SerializeField, TextArea] private string description;
|
||||||
|
[SerializeField] private string flavourText;
|
||||||
|
[SerializeField, TextArea] private string designNotes;
|
||||||
|
[SerializeField] private string intendedDistroId;
|
||||||
|
[SerializeField] private List<string> requiresSystem = new();
|
||||||
|
[SerializeField] private PackageEffectData offDistroEffect;
|
||||||
|
[SerializeField] private PackageEffectData onDistroEffect;
|
||||||
|
|
||||||
|
public string Id => id;
|
||||||
|
public string DisplayName => displayName;
|
||||||
|
public PackageSlot Slot => slot;
|
||||||
|
public int Rarity => Mathf.Clamp(rarity, 1, 5);
|
||||||
|
public string Description => description;
|
||||||
|
public string FlavourText => flavourText;
|
||||||
|
public string FlavorText => flavourText;
|
||||||
|
public string DesignNotes => designNotes;
|
||||||
|
public string IntendedDistroId => intendedDistroId;
|
||||||
|
public IReadOnlyList<string> RequiresSystem => requiresSystem;
|
||||||
|
public PackageEffectData OffDistroEffect => offDistroEffect;
|
||||||
|
public PackageEffectData OnDistroEffect => onDistroEffect;
|
||||||
|
|
||||||
|
public bool IsIntendedFor(string distroId)
|
||||||
|
{
|
||||||
|
return !string.IsNullOrWhiteSpace(intendedDistroId)
|
||||||
|
&& string.Equals(intendedDistroId, distroId, StringComparison.OrdinalIgnoreCase);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PackageEffectData EffectFor(string distroId)
|
||||||
|
{
|
||||||
|
return IsIntendedFor(distroId) ? onDistroEffect : offDistroEffect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public sealed class PackageInstance
|
||||||
|
{
|
||||||
|
public PackageInstance(PackageDefinition definition, int upgradeLevel)
|
||||||
|
{
|
||||||
|
Definition = definition;
|
||||||
|
UpgradeLevel = Mathf.Clamp(upgradeLevel, 0, KernelPanic.Meta.PackageTuning.MaxPackageLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PackageDefinition Definition { get; }
|
||||||
|
public int UpgradeLevel { get; }
|
||||||
|
|
||||||
|
public PackageEffectData EffectFor(string distroId)
|
||||||
|
{
|
||||||
|
PackageEffectData effect = Definition == null ? default : Definition.EffectFor(distroId);
|
||||||
|
return PackageEffectScaling.Scale(effect, UpgradeLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PackageEffectScaling
|
||||||
|
{
|
||||||
|
public static PackageEffectData Scale(PackageEffectData effect, int upgradeLevel)
|
||||||
|
{
|
||||||
|
int level = Mathf.Clamp(upgradeLevel, 0, KernelPanic.Meta.PackageTuning.MaxPackageLevel);
|
||||||
|
if (level <= 0 || effect.Kind == PackageEffectKind.None)
|
||||||
|
{
|
||||||
|
return effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
int amount = effect.Amount + GetAmountPerLevel(effect.Kind, effect.Amount) * level;
|
||||||
|
return new PackageEffectData(effect.Kind, amount, effect.Threshold, effect.RefundCycle, effect.CleanseDebuffs, effect.EnableFedoraSecondCardPassive);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int GetAmountPerLevel(PackageEffectKind kind, int baseAmount)
|
||||||
|
{
|
||||||
|
return kind switch
|
||||||
|
{
|
||||||
|
PackageEffectKind.MaxUptime => Mathf.Max(1, Mathf.CeilToInt(Mathf.Max(1, baseAmount) * 0.5f)),
|
||||||
|
PackageEffectKind.MaxCycles => 1,
|
||||||
|
PackageEffectKind.MaxRam => 1,
|
||||||
|
PackageEffectKind.WaveDraw => 1,
|
||||||
|
PackageEffectKind.FirstTurnFirstWaveDraw => 1,
|
||||||
|
PackageEffectKind.FirstTurnEachWaveCycle => 1,
|
||||||
|
PackageEffectKind.FirstCardsEachTurnCostReduction => 1,
|
||||||
|
PackageEffectKind.FirstCardEachWaveCostReduction => 1,
|
||||||
|
PackageEffectKind.FirstNativeCardEachWaveFlatDamage => 1,
|
||||||
|
PackageEffectKind.JavaScriptFlatDamage => 1,
|
||||||
|
_ => 1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,12 @@ namespace KernelPanic.Meta
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public enum GachaCurrencyType
|
public enum GachaCurrencyType
|
||||||
{
|
{
|
||||||
StandardPull,
|
StandardPull
|
||||||
LimitedPull
|
}
|
||||||
|
|
||||||
|
public enum PullPaymentSource
|
||||||
|
{
|
||||||
|
Commits,
|
||||||
|
Entropy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ namespace KernelPanic.Meta
|
|||||||
public static bool HasPendingPull => pendingPull != null;
|
public static bool HasPendingPull => pendingPull != null;
|
||||||
public static bool HasCompletedPull => completedPull != null;
|
public static bool HasCompletedPull => completedPull != null;
|
||||||
|
|
||||||
public static void SetPending(string bannerId, int pullCount, int entropyTokenCount, DistroDatabase distroDatabase, string focusUnitId)
|
public static void SetPending(string bannerId, int pullCount, int entropyTokenCount, DistroDatabase distroDatabase, PackageDatabase packageDatabase, string focusUnitId)
|
||||||
{
|
{
|
||||||
pendingPull = new PendingGachaPull(bannerId, pullCount, entropyTokenCount, distroDatabase, focusUnitId);
|
pendingPull = new PendingGachaPull(bannerId, pullCount, entropyTokenCount, distroDatabase, packageDatabase, focusUnitId);
|
||||||
completedPull = null;
|
completedPull = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,12 +44,13 @@ namespace KernelPanic.Meta
|
|||||||
|
|
||||||
public sealed class PendingGachaPull
|
public sealed class PendingGachaPull
|
||||||
{
|
{
|
||||||
public PendingGachaPull(string bannerId, int pullCount, int entropyTokenCount, DistroDatabase distroDatabase, string focusUnitId)
|
public PendingGachaPull(string bannerId, int pullCount, int entropyTokenCount, DistroDatabase distroDatabase, PackageDatabase packageDatabase, string focusUnitId)
|
||||||
{
|
{
|
||||||
BannerId = string.IsNullOrWhiteSpace(bannerId) ? GachaService.BeginnerBannerId : bannerId;
|
BannerId = string.IsNullOrWhiteSpace(bannerId) ? GachaService.BeginnerBannerId : bannerId;
|
||||||
PullCount = Math.Max(1, pullCount);
|
PullCount = Math.Max(1, pullCount);
|
||||||
EntropyTokenCount = Math.Max(0, entropyTokenCount);
|
EntropyTokenCount = Math.Max(0, entropyTokenCount);
|
||||||
DistroDatabase = distroDatabase;
|
DistroDatabase = distroDatabase;
|
||||||
|
PackageDatabase = packageDatabase;
|
||||||
FocusUnitId = focusUnitId;
|
FocusUnitId = focusUnitId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,6 +58,7 @@ namespace KernelPanic.Meta
|
|||||||
public int PullCount { get; }
|
public int PullCount { get; }
|
||||||
public int EntropyTokenCount { get; }
|
public int EntropyTokenCount { get; }
|
||||||
public DistroDatabase DistroDatabase { get; }
|
public DistroDatabase DistroDatabase { get; }
|
||||||
|
public PackageDatabase PackageDatabase { get; }
|
||||||
public string FocusUnitId { get; }
|
public string FocusUnitId { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +133,7 @@ namespace KernelPanic.Meta
|
|||||||
public bool PityTriggered { get; }
|
public bool PityTriggered { get; }
|
||||||
public bool IsCharacter => RewardType == GachaRewardType.Distro || RewardType == GachaRewardType.FutureStandardFiveStarDistro;
|
public bool IsCharacter => RewardType == GachaRewardType.Distro || RewardType == GachaRewardType.FutureStandardFiveStarDistro;
|
||||||
|
|
||||||
public string TypeText => IsCharacter ? "character" : "equipment";
|
public string TypeText => IsCharacter ? "character" : "package";
|
||||||
|
|
||||||
public string StatusText
|
public string StatusText
|
||||||
{
|
{
|
||||||
@@ -173,7 +175,7 @@ namespace KernelPanic.Meta
|
|||||||
return "unknown result";
|
return "unknown result";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rewardType != GachaRewardType.Equipment)
|
if (rewardType != GachaRewardType.Package)
|
||||||
{
|
{
|
||||||
return displayName;
|
return displayName;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ namespace KernelPanic.Meta
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public enum GachaRewardType
|
public enum GachaRewardType
|
||||||
{
|
{
|
||||||
Equipment,
|
Package,
|
||||||
Distro,
|
Distro,
|
||||||
FutureStandardFiveStarDistro
|
FutureStandardFiveStarDistro
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,11 +14,12 @@ namespace KernelPanic.Meta
|
|||||||
public const string LimitedBannerId = "limited";
|
public const string LimitedBannerId = "limited";
|
||||||
public const int BeginnerMaxPulls = 50;
|
public const int BeginnerMaxPulls = 50;
|
||||||
public const int BeginnerSinglePullCost = 1;
|
public const int BeginnerSinglePullCost = 1;
|
||||||
public const int BeginnerTenPullCost = 8;
|
public const int BeginnerTenPullCost = 10;
|
||||||
public const int FourStarHardPity = 10;
|
public const int FourStarHardPity = 10;
|
||||||
public const int FiveStarSoftPityStart = 66;
|
public const int FiveStarSoftPityStart = 66;
|
||||||
public const int FiveStarHardPity = 80;
|
public const int FiveStarHardPity = 80;
|
||||||
public const int EntropyPerPullToken = 100;
|
public const int EntropyPerCommit = 100;
|
||||||
|
public const int RootCreditsToEntropy = 1;
|
||||||
public const int TestRootCreditsBalance = 10000;
|
public const int TestRootCreditsBalance = 10000;
|
||||||
|
|
||||||
private const double FourStarBaseChance = 0.12d;
|
private const double FourStarBaseChance = 0.12d;
|
||||||
@@ -41,11 +42,10 @@ namespace KernelPanic.Meta
|
|||||||
{
|
{
|
||||||
this._random = random ?? new Random();
|
this._random = random ?? new Random();
|
||||||
_currencyBalances[GachaCurrencyType.StandardPull] = 0;
|
_currencyBalances[GachaCurrencyType.StandardPull] = 0;
|
||||||
_currencyBalances[GachaCurrencyType.LimitedPull] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int PullTokens => GetCurrencyBalance(GachaCurrencyType.StandardPull);
|
public int PullTokens => GetCurrencyBalance(GachaCurrencyType.StandardPull);
|
||||||
public int LimitedPullTokens => GetCurrencyBalance(GachaCurrencyType.LimitedPull);
|
public int Commits => PullTokens;
|
||||||
public int RootCredits { get; private set; }
|
public int RootCredits { get; private set; }
|
||||||
public IReadOnlyList<DistroDefinition> BannerPool => _bannerPool;
|
public IReadOnlyList<DistroDefinition> BannerPool => _bannerPool;
|
||||||
public GachaBannerState BeginnerState => _beginnerState;
|
public GachaBannerState BeginnerState => _beginnerState;
|
||||||
@@ -62,9 +62,8 @@ namespace KernelPanic.Meta
|
|||||||
}
|
}
|
||||||
|
|
||||||
data.EnsureLists();
|
data.EnsureLists();
|
||||||
RootCredits = Math.Max(TestRootCreditsBalance, data.rootCredits);
|
RootCredits = Math.Max(0, data.rootCredits);
|
||||||
SetCurrencyBalanceSilently(GachaCurrencyType.StandardPull, data.standardPullCurrency);
|
SetCurrencyBalanceSilently(GachaCurrencyType.StandardPull, data.commitsBalance);
|
||||||
SetCurrencyBalanceSilently(GachaCurrencyType.LimitedPull, data.limitedPullCurrency);
|
|
||||||
_beginnerState = data.beginnerBannerState ?? new GachaBannerState(BeginnerBannerId);
|
_beginnerState = data.beginnerBannerState ?? new GachaBannerState(BeginnerBannerId);
|
||||||
_beginnerState.bannerId = BeginnerBannerId;
|
_beginnerState.bannerId = BeginnerBannerId;
|
||||||
_beginnerState.EnsureLists();
|
_beginnerState.EnsureLists();
|
||||||
@@ -87,8 +86,7 @@ namespace KernelPanic.Meta
|
|||||||
|
|
||||||
data.EnsureLists();
|
data.EnsureLists();
|
||||||
data.rootCredits = RootCredits;
|
data.rootCredits = RootCredits;
|
||||||
data.standardPullCurrency = GetCurrencyBalance(GachaCurrencyType.StandardPull);
|
data.commitsBalance = GetCurrencyBalance(GachaCurrencyType.StandardPull);
|
||||||
data.limitedPullCurrency = GetCurrencyBalance(GachaCurrencyType.LimitedPull);
|
|
||||||
data.beginnerBannerState = CloneState(_beginnerState);
|
data.beginnerBannerState = CloneState(_beginnerState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,6 +123,11 @@ namespace KernelPanic.Meta
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool ConvertRootCreditsToEntropy(EntropyWallet wallet, int amount, out string failureReason)
|
public bool ConvertRootCreditsToEntropy(EntropyWallet wallet, int amount, out string failureReason)
|
||||||
|
{
|
||||||
|
return BuyEntropy(wallet, amount, out failureReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool BuyEntropy(EntropyWallet wallet, int rootCredits, out string failureReason)
|
||||||
{
|
{
|
||||||
if (wallet == null)
|
if (wallet == null)
|
||||||
{
|
{
|
||||||
@@ -132,20 +135,20 @@ namespace KernelPanic.Meta
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (amount <= 0)
|
if (rootCredits <= 0)
|
||||||
{
|
{
|
||||||
failureReason = "no root-credits selected";
|
failureReason = "no Root Credits selected";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RootCredits < amount)
|
if (RootCredits < rootCredits)
|
||||||
{
|
{
|
||||||
failureReason = $"need {amount} root-credits";
|
failureReason = $"need {rootCredits} Root Credits";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RootCredits -= amount;
|
RootCredits -= rootCredits;
|
||||||
wallet.Add(amount);
|
wallet.Add(rootCredits * RootCreditsToEntropy);
|
||||||
failureReason = null;
|
failureReason = null;
|
||||||
Changed?.Invoke();
|
Changed?.Invoke();
|
||||||
return true;
|
return true;
|
||||||
@@ -187,6 +190,11 @@ namespace KernelPanic.Meta
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool CanPullBeginner(int pullCount, out string failureReason)
|
public bool CanPullBeginner(int pullCount, out string failureReason)
|
||||||
|
{
|
||||||
|
return CanAffordPull(pullCount, null, PullPaymentSource.Commits, out failureReason);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanAffordPull(int pullCount, EntropyWallet wallet, PullPaymentSource source, out string failureReason)
|
||||||
{
|
{
|
||||||
if (pullCount != 1 && pullCount != 10)
|
if (pullCount != 1 && pullCount != 10)
|
||||||
{
|
{
|
||||||
@@ -208,49 +216,73 @@ namespace KernelPanic.Meta
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cost = GetBeginnerPullCost(pullCount);
|
int cost = GetBeginnerPullCost(pullCount);
|
||||||
if (GetCurrencyBalance(GachaCurrencyType.StandardPull) < cost)
|
if (source == PullPaymentSource.Commits && GetCurrencyBalance(GachaCurrencyType.StandardPull) < cost)
|
||||||
{
|
{
|
||||||
failureReason = $"need {cost} {FormatCurrencyName(GachaCurrencyType.StandardPull)}";
|
failureReason = $"need {cost} {FormatCurrencyName(GachaCurrencyType.StandardPull)}";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int entropyCost = cost * EntropyPerCommit;
|
||||||
|
if (source == PullPaymentSource.Entropy && (wallet == null || wallet.Balance < entropyCost))
|
||||||
|
{
|
||||||
|
failureReason = $"need {entropyCost} Entropy";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
failureReason = null;
|
failureReason = null;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool PayForPull(int pullCount, EntropyWallet wallet, PullPaymentSource source, out int commitsSpent, out int entropySpent, out string failureReason)
|
||||||
|
{
|
||||||
|
commitsSpent = 0;
|
||||||
|
entropySpent = 0;
|
||||||
|
if (!CanAffordPull(pullCount, wallet, source, out failureReason))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cost = GetBeginnerPullCost(pullCount);
|
||||||
|
if (source == PullPaymentSource.Commits)
|
||||||
|
{
|
||||||
|
commitsSpent = cost;
|
||||||
|
SetCurrencyBalanceSilently(GachaCurrencyType.StandardPull, GetCurrencyBalance(GachaCurrencyType.StandardPull) - commitsSpent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
entropySpent = cost * EntropyPerCommit;
|
||||||
|
wallet.Spend(entropySpent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public int GetMissingPullTokens(GachaCurrencyType currencyType, int pullCost)
|
public int GetMissingPullTokens(GachaCurrencyType currencyType, int pullCost)
|
||||||
{
|
{
|
||||||
return Math.Max(0, pullCost - GetCurrencyBalance(currencyType));
|
return Math.Max(0, pullCost - GetCurrencyBalance(currencyType));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanCoverMissingPullTokensWithEntropy(EntropyWallet wallet, int missingPullTokens)
|
|
||||||
{
|
|
||||||
return missingPullTokens <= 0 || (wallet != null && wallet.Balance >= missingPullTokens * EntropyPerPullToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GachaPullResult PerformBeginnerPull(int pullCount)
|
public GachaPullResult PerformBeginnerPull(int pullCount)
|
||||||
{
|
{
|
||||||
return PerformBeginnerPull(pullCount, null, 0);
|
return PerformBeginnerPull(pullCount, null, PullPaymentSource.Commits);
|
||||||
}
|
}
|
||||||
|
|
||||||
public GachaPullResult PerformBeginnerPull(int pullCount, EntropyWallet wallet, int entropyTokenCount)
|
public GachaPullResult PerformBeginnerPull(int pullCount, EntropyWallet wallet, int entropyTokenCount)
|
||||||
{
|
{
|
||||||
if (!CanPullBeginnerWithEntropy(pullCount, wallet, entropyTokenCount, out string failureReason))
|
PullPaymentSource source = entropyTokenCount > 0 ? PullPaymentSource.Entropy : PullPaymentSource.Commits;
|
||||||
|
return PerformBeginnerPull(pullCount, wallet, source);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GachaPullResult PerformBeginnerPull(int pullCount, EntropyWallet wallet, PullPaymentSource source)
|
||||||
|
{
|
||||||
|
if (!CanAffordPull(pullCount, wallet, source, out string failureReason))
|
||||||
{
|
{
|
||||||
return GachaPullResult.Failed(BeginnerBannerId, failureReason);
|
return GachaPullResult.Failed(BeginnerBannerId, failureReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
int cost = GetBeginnerPullCost(pullCount);
|
if (!PayForPull(pullCount, wallet, source, out int commitSpend, out int entropySpent, out failureReason))
|
||||||
int tokenSpend = cost - entropyTokenCount;
|
|
||||||
if (tokenSpend > 0)
|
|
||||||
{
|
{
|
||||||
SetCurrencyBalanceSilently(GachaCurrencyType.StandardPull, GetCurrencyBalance(GachaCurrencyType.StandardPull) - tokenSpend);
|
return GachaPullResult.Failed(BeginnerBannerId, failureReason);
|
||||||
}
|
|
||||||
|
|
||||||
int entropySpent = entropyTokenCount * EntropyPerPullToken;
|
|
||||||
if (entropySpent > 0)
|
|
||||||
{
|
|
||||||
wallet.Spend(entropySpent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<GachaReward> rewards = new();
|
List<GachaReward> rewards = new();
|
||||||
@@ -266,14 +298,13 @@ namespace KernelPanic.Meta
|
|||||||
}
|
}
|
||||||
|
|
||||||
Changed?.Invoke();
|
Changed?.Invoke();
|
||||||
return new GachaPullResult(true, BeginnerBannerId, GachaCurrencyType.StandardPull, tokenSpend, entropySpent, rewards, null);
|
return new GachaPullResult(true, BeginnerBannerId, GachaCurrencyType.StandardPull, commitSpend, entropySpent, rewards, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string FormatCurrencyName(GachaCurrencyType currencyType)
|
public static string FormatCurrencyName(GachaCurrencyType currencyType)
|
||||||
{
|
{
|
||||||
return currencyType switch
|
return currencyType switch
|
||||||
{
|
{
|
||||||
GachaCurrencyType.LimitedPull => "Root Credits",
|
|
||||||
_ => "Commits"
|
_ => "Commits"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -335,7 +366,7 @@ namespace KernelPanic.Meta
|
|||||||
if (!hitFourStarOrCharacter)
|
if (!hitFourStarOrCharacter)
|
||||||
{
|
{
|
||||||
_beginnerState.pityCounter++;
|
_beginnerState.pityCounter++;
|
||||||
return GachaReward.Equipment(3, "3-star equipment", false, false);
|
return GachaReward.Package(3, "3-star package", false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
_beginnerState.pityCounter = 0;
|
_beginnerState.pityCounter = 0;
|
||||||
@@ -345,7 +376,7 @@ namespace KernelPanic.Meta
|
|||||||
return GachaReward.DistroReward(distro, 4, pityTriggered, false);
|
return GachaReward.DistroReward(distro, 4, pityTriggered, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return GachaReward.Equipment(4, "4-star equipment", pityTriggered, false);
|
return GachaReward.Package(4, "4-star package", pityTriggered, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryRollFiveStar(GachaBannerState state, out bool pityTriggered)
|
private bool TryRollFiveStar(GachaBannerState state, out bool pityTriggered)
|
||||||
@@ -379,7 +410,7 @@ namespace KernelPanic.Meta
|
|||||||
{
|
{
|
||||||
if (_bannerPool.Count == 0 || _random.NextDouble() >= DistroChanceOnFeaturedTier)
|
if (_bannerPool.Count == 0 || _random.NextDouble() >= DistroChanceOnFeaturedTier)
|
||||||
{
|
{
|
||||||
return GachaReward.Equipment(5, "5-star equipment", pityTriggered, false);
|
return GachaReward.Package(5, "5-star package", pityTriggered, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
DistroDefinition distro = _bannerPool.Count == 0 ? null : _bannerPool[_random.Next(_bannerPool.Count)];
|
DistroDefinition distro = _bannerPool.Count == 0 ? null : _bannerPool[_random.Next(_bannerPool.Count)];
|
||||||
@@ -420,7 +451,7 @@ namespace KernelPanic.Meta
|
|||||||
|
|
||||||
distro ??= _bannerPool.Count == 0 ? null : _bannerPool[Math.Min(guaranteeIndex, _bannerPool.Count - 1)];
|
distro ??= _bannerPool.Count == 0 ? null : _bannerPool[Math.Min(guaranteeIndex, _bannerPool.Count - 1)];
|
||||||
return distro == null
|
return distro == null
|
||||||
? GachaReward.Equipment(4, "4-star equipment", true, true)
|
? GachaReward.Package(4, "4-star package", true, true)
|
||||||
: GachaReward.DistroReward(distro, 4, true, true, reason);
|
: GachaReward.DistroReward(distro, 4, true, true, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -448,52 +479,6 @@ namespace KernelPanic.Meta
|
|||||||
_currencyBalances[currencyType] = Math.Max(0, amount);
|
_currencyBalances[currencyType] = Math.Max(0, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CanPullBeginnerWithEntropy(int pullCount, EntropyWallet wallet, int entropyTokenCount, out string failureReason)
|
|
||||||
{
|
|
||||||
if (pullCount != 1 && pullCount != 10)
|
|
||||||
{
|
|
||||||
failureReason = "only single and ten pulls are supported";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IsBeginnerBannerAvailable)
|
|
||||||
{
|
|
||||||
failureReason = "beginner banner unavailable";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int remainingPulls = BeginnerMaxPulls - _beginnerState.totalPulls;
|
|
||||||
if (pullCount > remainingPulls)
|
|
||||||
{
|
|
||||||
failureReason = $"only {remainingPulls} beginner pull(s) remain";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cost = GetBeginnerPullCost(pullCount);
|
|
||||||
if (entropyTokenCount < 0 || entropyTokenCount > cost)
|
|
||||||
{
|
|
||||||
failureReason = "invalid entropy substitute amount";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int tokenSpend = cost - entropyTokenCount;
|
|
||||||
if (GetCurrencyBalance(GachaCurrencyType.StandardPull) < tokenSpend)
|
|
||||||
{
|
|
||||||
failureReason = $"need {tokenSpend} {FormatCurrencyName(GachaCurrencyType.StandardPull)}";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int entropySpend = entropyTokenCount * EntropyPerPullToken;
|
|
||||||
if (entropySpend > 0 && (wallet == null || wallet.Balance < entropySpend))
|
|
||||||
{
|
|
||||||
failureReason = $"need {entropySpend} entropy";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
failureReason = null;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static GachaBannerState CloneState(GachaBannerState state)
|
private static GachaBannerState CloneState(GachaBannerState state)
|
||||||
{
|
{
|
||||||
state ??= new GachaBannerState(BeginnerBannerId);
|
state ??= new GachaBannerState(BeginnerBannerId);
|
||||||
@@ -542,9 +527,9 @@ namespace KernelPanic.Meta
|
|||||||
public bool Guaranteed { get; }
|
public bool Guaranteed { get; }
|
||||||
public string GuaranteeReason { get; }
|
public string GuaranteeReason { get; }
|
||||||
|
|
||||||
public static GachaReward Equipment(int starRating, string displayName, bool pityTriggered, bool guaranteed)
|
public static GachaReward Package(int starRating, string displayName, bool pityTriggered, bool guaranteed)
|
||||||
{
|
{
|
||||||
return new GachaReward(GachaRewardType.Equipment, starRating, displayName, null, pityTriggered, guaranteed, null);
|
return new GachaReward(GachaRewardType.Package, starRating, displayName, null, pityTriggered, guaranteed, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GachaReward DistroReward(DistroDefinition distro, int starRating, bool pityTriggered, bool guaranteed, string guaranteeReason = null)
|
public static GachaReward DistroReward(DistroDefinition distro, int starRating, bool pityTriggered, bool guaranteed, string guaranteeReason = null)
|
||||||
|
|||||||
@@ -0,0 +1,190 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using KernelPanic.Data;
|
||||||
|
|
||||||
|
namespace KernelPanic.Meta
|
||||||
|
{
|
||||||
|
public enum PackageLoadoutFailureReason
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
WrongSlot,
|
||||||
|
NotOwned,
|
||||||
|
SlotOccupied,
|
||||||
|
NotEquipped
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pure meta model for persistent package slots. Unlike CardLoadout, this is not
|
||||||
|
/// run-only: equipped package ids are saved per distro and reused in every run.
|
||||||
|
/// </summary>
|
||||||
|
public sealed class PackageLoadout
|
||||||
|
{
|
||||||
|
private readonly PlayerCollection _collection;
|
||||||
|
private readonly PackageDatabase _database;
|
||||||
|
private readonly Dictionary<string, Dictionary<PackageSlot, string>> _equippedByDistro = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
public PackageLoadout(PlayerCollection collection, PackageDatabase database)
|
||||||
|
{
|
||||||
|
_collection = collection;
|
||||||
|
_database = database;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IReadOnlyDictionary<PackageSlot, string> GetEquippedPackageIds(string distroId)
|
||||||
|
{
|
||||||
|
return !string.IsNullOrWhiteSpace(distroId) && _equippedByDistro.TryGetValue(distroId, out Dictionary<PackageSlot, string> equipped)
|
||||||
|
? equipped
|
||||||
|
: Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PackageDefinition GetEquippedPackage(string distroId, PackageSlot slot)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(distroId)
|
||||||
|
|| !_equippedByDistro.TryGetValue(distroId, out Dictionary<PackageSlot, string> equipped)
|
||||||
|
|| !equipped.TryGetValue(slot, out string packageId))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _database == null ? null : _database.FindById(packageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IReadOnlyList<PackageDefinition> GetEquippedPackages(string distroId)
|
||||||
|
{
|
||||||
|
List<PackageDefinition> packages = new();
|
||||||
|
AddIfEquipped(distroId, PackageSlot.Kernel, packages);
|
||||||
|
AddIfEquipped(distroId, PackageSlot.Runtime, packages);
|
||||||
|
AddIfEquipped(distroId, PackageSlot.Daemon, packages);
|
||||||
|
return packages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IReadOnlyList<PackageInstance> GetEquippedPackageInstances(string distroId)
|
||||||
|
{
|
||||||
|
List<PackageInstance> packages = new();
|
||||||
|
AddInstanceIfEquipped(distroId, PackageSlot.Kernel, packages);
|
||||||
|
AddInstanceIfEquipped(distroId, PackageSlot.Runtime, packages);
|
||||||
|
AddInstanceIfEquipped(distroId, PackageSlot.Daemon, packages);
|
||||||
|
return packages;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEquipped(string packageId)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(packageId))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (KeyValuePair<string, Dictionary<PackageSlot, string>> distro in _equippedByDistro)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<PackageSlot, string> slot in distro.Value)
|
||||||
|
{
|
||||||
|
if (string.Equals(slot.Value, packageId, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryEquip(string distroId, PackageSlot slot, string packageId, out PackageLoadoutFailureReason reason)
|
||||||
|
{
|
||||||
|
PackageDefinition package = _database == null ? null : _database.FindById(packageId);
|
||||||
|
if (package == null || _collection == null || !_collection.IsPackageOwned(package.Id))
|
||||||
|
{
|
||||||
|
reason = PackageLoadoutFailureReason.NotOwned;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (package.Slot != slot)
|
||||||
|
{
|
||||||
|
reason = PackageLoadoutFailureReason.WrongSlot;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<PackageSlot, string> equipped = EnsureDistro(distroId);
|
||||||
|
if (equipped.TryGetValue(slot, out string current) && !string.Equals(current, package.Id, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
reason = PackageLoadoutFailureReason.SlotOccupied;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
equipped[slot] = package.Id;
|
||||||
|
reason = PackageLoadoutFailureReason.None;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryUnequip(string distroId, PackageSlot slot, out PackageLoadoutFailureReason reason)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(distroId)
|
||||||
|
|| !_equippedByDistro.TryGetValue(distroId, out Dictionary<PackageSlot, string> equipped)
|
||||||
|
|| !equipped.Remove(slot))
|
||||||
|
{
|
||||||
|
reason = PackageLoadoutFailureReason.NotEquipped;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
reason = PackageLoadoutFailureReason.None;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Load(string distroId, IEnumerable<PackageLoadoutSlotSaveEntry> slots)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(distroId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dictionary<PackageSlot, string> equipped = EnsureDistro(distroId);
|
||||||
|
equipped.Clear();
|
||||||
|
foreach (PackageLoadoutSlotSaveEntry slotEntry in slots ?? Array.Empty<PackageLoadoutSlotSaveEntry>())
|
||||||
|
{
|
||||||
|
PackageDefinition package = _database == null ? null : _database.FindById(slotEntry?.packageId);
|
||||||
|
if (package == null || !_collection.IsPackageOwned(package.Id) || package.Slot != slotEntry.slot)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
equipped[package.Slot] = package.Id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_equippedByDistro.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddIfEquipped(string distroId, PackageSlot slot, List<PackageDefinition> packages)
|
||||||
|
{
|
||||||
|
PackageDefinition package = GetEquippedPackage(distroId, slot);
|
||||||
|
if (package != null)
|
||||||
|
{
|
||||||
|
packages.Add(package);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddInstanceIfEquipped(string distroId, PackageSlot slot, List<PackageInstance> packages)
|
||||||
|
{
|
||||||
|
PackageDefinition definition = GetEquippedPackage(distroId, slot);
|
||||||
|
OwnedPackageInstance owned = definition == null ? null : _collection.GetOwnedPackage(definition.Id);
|
||||||
|
if (owned != null)
|
||||||
|
{
|
||||||
|
packages.Add(owned.ToRuntimeInstance());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dictionary<PackageSlot, string> EnsureDistro(string distroId)
|
||||||
|
{
|
||||||
|
string key = string.IsNullOrWhiteSpace(distroId) ? string.Empty : distroId;
|
||||||
|
if (!_equippedByDistro.TryGetValue(key, out Dictionary<PackageSlot, string> equipped))
|
||||||
|
{
|
||||||
|
equipped = new Dictionary<PackageSlot, string>();
|
||||||
|
_equippedByDistro[key] = equipped;
|
||||||
|
}
|
||||||
|
|
||||||
|
return equipped;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly IReadOnlyDictionary<PackageSlot, string> Empty = new Dictionary<PackageSlot, string>();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using KernelPanic.Data;
|
||||||
|
|
||||||
|
namespace KernelPanic.Meta
|
||||||
|
{
|
||||||
|
public enum PackageScrapFailureReason
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
NotOwned,
|
||||||
|
Equipped
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly struct PackageScrapResult
|
||||||
|
{
|
||||||
|
public PackageScrapResult(bool success, PackageScrapFailureReason failureReason, int cacheGranted, int bandwidthRefunded)
|
||||||
|
{
|
||||||
|
Success = success;
|
||||||
|
FailureReason = failureReason;
|
||||||
|
CacheGranted = cacheGranted;
|
||||||
|
BandwidthRefunded = bandwidthRefunded;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Success { get; }
|
||||||
|
public PackageScrapFailureReason FailureReason { get; }
|
||||||
|
public int CacheGranted { get; }
|
||||||
|
public int BandwidthRefunded { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PackageScrapper
|
||||||
|
{
|
||||||
|
public static PackageScrapResult Scrap(PlayerCollection collection, PackageLoadout loadout, SaveData wallet, string packageId)
|
||||||
|
{
|
||||||
|
if (collection == null || wallet == null || string.IsNullOrWhiteSpace(packageId))
|
||||||
|
{
|
||||||
|
return new PackageScrapResult(false, PackageScrapFailureReason.NotOwned, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
OwnedPackageInstance package = collection.GetOwnedPackage(packageId);
|
||||||
|
if (package == null)
|
||||||
|
{
|
||||||
|
return new PackageScrapResult(false, PackageScrapFailureReason.NotOwned, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loadout != null && loadout.IsEquipped(packageId))
|
||||||
|
{
|
||||||
|
return new PackageScrapResult(false, PackageScrapFailureReason.Equipped, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
PackageDefinition definition = package.Definition;
|
||||||
|
int rarity = definition == null ? 1 : definition.Rarity;
|
||||||
|
int cache = PackageTuning.GetCacheForRarity(rarity) + PackageTuning.GetRefundedInvestedCache(package.UpgradeLevel, rarity);
|
||||||
|
int bandwidth = PackageTuning.GetRefundedInvestedBandwidth(package.UpgradeLevel, rarity);
|
||||||
|
|
||||||
|
if (!collection.RemovePackage(packageId))
|
||||||
|
{
|
||||||
|
return new PackageScrapResult(false, PackageScrapFailureReason.NotOwned, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
wallet.cacheBalance += Math.Max(0, cache);
|
||||||
|
wallet.bandwidthBalance += Math.Max(0, bandwidth);
|
||||||
|
return new PackageScrapResult(true, PackageScrapFailureReason.None, cache, bandwidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,69 @@
|
|||||||
|
using System;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace KernelPanic.Meta
|
||||||
|
{
|
||||||
|
public static class PackageTuning
|
||||||
|
{
|
||||||
|
public const int MaxPackageLevel = 5;
|
||||||
|
public const float RefundFraction = 1f;
|
||||||
|
public const float RarityCostMultiplier = 1f;
|
||||||
|
|
||||||
|
private static readonly int[] CachePerRarityValues = { 5, 12, 30, 80, 200 };
|
||||||
|
private static readonly int[] UpgradeCacheCostValues = { 10, 25, 50, 90, 150 };
|
||||||
|
private static readonly int[] UpgradeBandwidthCostValues = { 20, 50, 100, 180, 300 };
|
||||||
|
|
||||||
|
public static int GetCacheForRarity(int rarity)
|
||||||
|
{
|
||||||
|
return CachePerRarityValues[Mathf.Clamp(rarity, 1, CachePerRarityValues.Length) - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetUpgradeCacheCost(int nextLevel, int rarity)
|
||||||
|
{
|
||||||
|
return ApplyRarityMultiplier(UpgradeCacheCostValues[Mathf.Clamp(nextLevel, 1, UpgradeCacheCostValues.Length) - 1], rarity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetUpgradeBandwidthCost(int nextLevel, int rarity)
|
||||||
|
{
|
||||||
|
return ApplyRarityMultiplier(UpgradeBandwidthCostValues[Mathf.Clamp(nextLevel, 1, UpgradeBandwidthCostValues.Length) - 1], rarity);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetInvestedCache(int level, int rarity)
|
||||||
|
{
|
||||||
|
int total = 0;
|
||||||
|
for (int nextLevel = 1; nextLevel <= Mathf.Clamp(level, 0, MaxPackageLevel); nextLevel++)
|
||||||
|
{
|
||||||
|
total += GetUpgradeCacheCost(nextLevel, rarity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetInvestedBandwidth(int level, int rarity)
|
||||||
|
{
|
||||||
|
int total = 0;
|
||||||
|
for (int nextLevel = 1; nextLevel <= Mathf.Clamp(level, 0, MaxPackageLevel); nextLevel++)
|
||||||
|
{
|
||||||
|
total += GetUpgradeBandwidthCost(nextLevel, rarity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetRefundedInvestedCache(int level, int rarity)
|
||||||
|
{
|
||||||
|
return Mathf.RoundToInt(GetInvestedCache(level, rarity) * RefundFraction);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int GetRefundedInvestedBandwidth(int level, int rarity)
|
||||||
|
{
|
||||||
|
return Mathf.RoundToInt(GetInvestedBandwidth(level, rarity) * RefundFraction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int ApplyRarityMultiplier(int baseCost, int rarity)
|
||||||
|
{
|
||||||
|
float multiplier = RarityCostMultiplier <= 0f ? 1f : RarityCostMultiplier;
|
||||||
|
return Math.Max(0, Mathf.RoundToInt(baseCost * multiplier));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
using System;
|
||||||
|
using KernelPanic.Data;
|
||||||
|
|
||||||
|
namespace KernelPanic.Meta
|
||||||
|
{
|
||||||
|
public enum PackageUpgradeFailureReason
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
NotOwned,
|
||||||
|
MaxLevel,
|
||||||
|
InsufficientCache,
|
||||||
|
InsufficientBandwidth
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly struct PackageUpgradeResult
|
||||||
|
{
|
||||||
|
public PackageUpgradeResult(bool success, PackageUpgradeFailureReason failureReason, int cacheCost, int bandwidthCost, int newLevel)
|
||||||
|
{
|
||||||
|
Success = success;
|
||||||
|
FailureReason = failureReason;
|
||||||
|
CacheCost = cacheCost;
|
||||||
|
BandwidthCost = bandwidthCost;
|
||||||
|
NewLevel = newLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool Success { get; }
|
||||||
|
public PackageUpgradeFailureReason FailureReason { get; }
|
||||||
|
public int CacheCost { get; }
|
||||||
|
public int BandwidthCost { get; }
|
||||||
|
public int NewLevel { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PackageUpgrader
|
||||||
|
{
|
||||||
|
public static event Action<OwnedPackageInstance> Upgraded;
|
||||||
|
|
||||||
|
public static PackageUpgradeResult TryUpgrade(OwnedPackageInstance packageInstance, SaveData wallet)
|
||||||
|
{
|
||||||
|
if (packageInstance == null || wallet == null)
|
||||||
|
{
|
||||||
|
return new PackageUpgradeResult(false, PackageUpgradeFailureReason.NotOwned, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int currentLevel = Math.Max(0, packageInstance.UpgradeLevel);
|
||||||
|
if (currentLevel >= PackageTuning.MaxPackageLevel)
|
||||||
|
{
|
||||||
|
return new PackageUpgradeResult(false, PackageUpgradeFailureReason.MaxLevel, 0, 0, currentLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
int nextLevel = currentLevel + 1;
|
||||||
|
PackageDefinition definition = packageInstance.Definition;
|
||||||
|
int rarity = definition == null ? 1 : definition.Rarity;
|
||||||
|
int cacheCost = PackageTuning.GetUpgradeCacheCost(nextLevel, rarity);
|
||||||
|
int bandwidthCost = PackageTuning.GetUpgradeBandwidthCost(nextLevel, rarity);
|
||||||
|
if (wallet.cacheBalance < cacheCost)
|
||||||
|
{
|
||||||
|
return new PackageUpgradeResult(false, PackageUpgradeFailureReason.InsufficientCache, cacheCost, bandwidthCost, currentLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wallet.bandwidthBalance < bandwidthCost)
|
||||||
|
{
|
||||||
|
return new PackageUpgradeResult(false, PackageUpgradeFailureReason.InsufficientBandwidth, cacheCost, bandwidthCost, currentLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
wallet.cacheBalance -= cacheCost;
|
||||||
|
wallet.bandwidthBalance -= bandwidthCost;
|
||||||
|
packageInstance.SetUpgradeLevel(nextLevel);
|
||||||
|
Upgraded?.Invoke(packageInstance);
|
||||||
|
return new PackageUpgradeResult(true, PackageUpgradeFailureReason.None, cacheCost, bandwidthCost, nextLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,11 +10,14 @@ namespace KernelPanic.Meta
|
|||||||
public sealed class PlayerCollection
|
public sealed class PlayerCollection
|
||||||
{
|
{
|
||||||
private readonly List<DistroDefinition> _ownedUnits = new();
|
private readonly List<DistroDefinition> _ownedUnits = new();
|
||||||
|
private readonly List<OwnedPackageInstance> _ownedPackages = new();
|
||||||
private readonly Dictionary<string, int> _versions = new(StringComparer.OrdinalIgnoreCase);
|
private readonly Dictionary<string, int> _versions = new(StringComparer.OrdinalIgnoreCase);
|
||||||
private int _featuredIndex;
|
private int _featuredIndex;
|
||||||
|
|
||||||
// TODO: Populate owned units from SaveService during bootstrap.
|
// TODO: Populate owned units from SaveService during bootstrap.
|
||||||
public IReadOnlyList<DistroDefinition> OwnedUnits => _ownedUnits;
|
public IReadOnlyList<DistroDefinition> OwnedUnits => _ownedUnits;
|
||||||
|
public IReadOnlyList<OwnedPackageInstance> OwnedPackageInstances => _ownedPackages;
|
||||||
|
public IReadOnlyList<PackageDefinition> OwnedPackages => BuildOwnedPackageDefinitions();
|
||||||
public DistroDefinition FeaturedUnit => _ownedUnits.Count == 0 ? null : _ownedUnits[Math.Clamp(_featuredIndex, 0, _ownedUnits.Count - 1)];
|
public DistroDefinition FeaturedUnit => _ownedUnits.Count == 0 ? null : _ownedUnits[Math.Clamp(_featuredIndex, 0, _ownedUnits.Count - 1)];
|
||||||
|
|
||||||
public event Action Changed;
|
public event Action Changed;
|
||||||
@@ -34,6 +37,35 @@ namespace KernelPanic.Meta
|
|||||||
Add(unit, version, false);
|
Add(unit, version, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddPackage(PackageDefinition package)
|
||||||
|
{
|
||||||
|
AddPackage(package, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddPackageSilently(PackageDefinition package)
|
||||||
|
{
|
||||||
|
AddPackage(package, 0, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddPackageSilently(PackageDefinition package, int upgradeLevel)
|
||||||
|
{
|
||||||
|
AddPackage(package, upgradeLevel, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddPackage(PackageDefinition package, int upgradeLevel, bool notify)
|
||||||
|
{
|
||||||
|
if (package == null || IsPackageOwned(package.Id))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ownedPackages.Add(new OwnedPackageInstance(package, upgradeLevel));
|
||||||
|
if (notify)
|
||||||
|
{
|
||||||
|
Changed?.Invoke();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void Add(DistroDefinition unit, int version, bool notify)
|
private void Add(DistroDefinition unit, int version, bool notify)
|
||||||
{
|
{
|
||||||
if (unit == null)
|
if (unit == null)
|
||||||
@@ -82,6 +114,60 @@ namespace KernelPanic.Meta
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool IsPackageOwned(string packageId)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(packageId))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _ownedPackages.Count; i++)
|
||||||
|
{
|
||||||
|
OwnedPackageInstance package = _ownedPackages[i];
|
||||||
|
if (package != null && string.Equals(package.PackageId, packageId, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OwnedPackageInstance GetOwnedPackage(string packageId)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(packageId))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < _ownedPackages.Count; i++)
|
||||||
|
{
|
||||||
|
OwnedPackageInstance package = _ownedPackages[i];
|
||||||
|
if (package != null && string.Equals(package.PackageId, packageId, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return package;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool RemovePackage(string packageId)
|
||||||
|
{
|
||||||
|
for (int i = _ownedPackages.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
OwnedPackageInstance package = _ownedPackages[i];
|
||||||
|
if (package != null && string.Equals(package.PackageId, packageId, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
_ownedPackages.RemoveAt(i);
|
||||||
|
Changed?.Invoke();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public int GetVersion(string unitId)
|
public int GetVersion(string unitId)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(unitId))
|
if (string.IsNullOrWhiteSpace(unitId))
|
||||||
@@ -131,5 +217,42 @@ namespace KernelPanic.Meta
|
|||||||
|
|
||||||
_featuredIndex = (_featuredIndex + 1) % _ownedUnits.Count;
|
_featuredIndex = (_featuredIndex + 1) % _ownedUnits.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IReadOnlyList<PackageDefinition> BuildOwnedPackageDefinitions()
|
||||||
|
{
|
||||||
|
List<PackageDefinition> definitions = new();
|
||||||
|
for (int i = 0; i < _ownedPackages.Count; i++)
|
||||||
|
{
|
||||||
|
if (_ownedPackages[i]?.Definition != null)
|
||||||
|
{
|
||||||
|
definitions.Add(_ownedPackages[i].Definition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return definitions;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class OwnedPackageInstance
|
||||||
|
{
|
||||||
|
public OwnedPackageInstance(PackageDefinition definition, int upgradeLevel)
|
||||||
|
{
|
||||||
|
Definition = definition;
|
||||||
|
UpgradeLevel = Math.Max(0, Math.Min(PackageTuning.MaxPackageLevel, upgradeLevel));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PackageDefinition Definition { get; }
|
||||||
|
public string PackageId => Definition == null ? string.Empty : Definition.Id;
|
||||||
|
public int UpgradeLevel { get; private set; }
|
||||||
|
|
||||||
|
public PackageInstance ToRuntimeInstance()
|
||||||
|
{
|
||||||
|
return new PackageInstance(Definition, UpgradeLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetUpgradeLevel(int level)
|
||||||
|
{
|
||||||
|
UpgradeLevel = Math.Max(0, Math.Min(PackageTuning.MaxPackageLevel, level));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ namespace KernelPanic.Meta
|
|||||||
owned.merges = Math.Max(0, owned.merges) + merges;
|
owned.merges = Math.Max(0, owned.merges) + merges;
|
||||||
if (GachaTuning.DupeConsolationBandwidth > 0)
|
if (GachaTuning.DupeConsolationBandwidth > 0)
|
||||||
{
|
{
|
||||||
context.SaveData.standardPullCurrency += GachaTuning.DupeConsolationBandwidth;
|
context.SaveData.bandwidthBalance += GachaTuning.DupeConsolationBandwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Collection?.AddSilently(unit, version);
|
context.Collection?.AddSilently(unit, version);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using KernelPanic.Data;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace KernelPanic.Meta
|
namespace KernelPanic.Meta
|
||||||
@@ -60,16 +61,28 @@ namespace KernelPanic.Meta
|
|||||||
public bool starterChosen;
|
public bool starterChosen;
|
||||||
public int entropyBalance;
|
public int entropyBalance;
|
||||||
public int rootCredits = GachaService.TestRootCreditsBalance;
|
public int rootCredits = GachaService.TestRootCreditsBalance;
|
||||||
|
public int commitsBalance;
|
||||||
|
public int bandwidthBalance;
|
||||||
|
// Legacy conflated balance. Older builds used this for both Commits and Bandwidth.
|
||||||
|
// Migration preserves it as Bandwidth and starts Commits at 0 because the source is ambiguous.
|
||||||
public int standardPullCurrency;
|
public int standardPullCurrency;
|
||||||
|
// Legacy pull-token field kept only so older saves deserialize cleanly.
|
||||||
public int limitedPullCurrency;
|
public int limitedPullCurrency;
|
||||||
|
public int cacheBalance;
|
||||||
|
public int packageMerges;
|
||||||
// Legacy global balance kept only so older saves deserialize cleanly.
|
// Legacy global balance kept only so older saves deserialize cleanly.
|
||||||
// New duplicate-pull merges live on OwnedUnitSaveEntry.merges.
|
// New duplicate-pull merges live on OwnedUnitSaveEntry.merges.
|
||||||
public int merges;
|
public int merges;
|
||||||
public List<OwnedUnitSaveEntry> ownedUnits = new();
|
public List<OwnedUnitSaveEntry> ownedUnits = new();
|
||||||
|
public List<OwnedPackageSaveEntry> ownedPackages = new();
|
||||||
|
public List<string> ownedPackageIds = new();
|
||||||
|
public List<PackageLoadoutSaveEntry> packageLoadouts = new();
|
||||||
public List<string> ownedUnitIds = new();
|
public List<string> ownedUnitIds = new();
|
||||||
public List<string> bannerPoolIds = new();
|
public List<string> bannerPoolIds = new();
|
||||||
public GachaBannerState beginnerBannerState = new(GachaService.BeginnerBannerId);
|
public GachaBannerState beginnerBannerState = new(GachaService.BeginnerBannerId);
|
||||||
public LastRunLoadoutSaveEntry lastRunLoadout = new();
|
public LastRunLoadoutSaveEntry lastRunLoadout = new();
|
||||||
|
public string lastRunDistroId;
|
||||||
|
public List<DistroBestWaveSaveEntry> distroBestWaves = new();
|
||||||
|
|
||||||
public static SaveData CreateDefault()
|
public static SaveData CreateDefault()
|
||||||
{
|
{
|
||||||
@@ -79,19 +92,56 @@ namespace KernelPanic.Meta
|
|||||||
public void EnsureLists()
|
public void EnsureLists()
|
||||||
{
|
{
|
||||||
ownedUnits ??= new List<OwnedUnitSaveEntry>();
|
ownedUnits ??= new List<OwnedUnitSaveEntry>();
|
||||||
|
ownedPackages ??= new List<OwnedPackageSaveEntry>();
|
||||||
|
ownedPackageIds ??= new List<string>();
|
||||||
|
packageLoadouts ??= new List<PackageLoadoutSaveEntry>();
|
||||||
ownedUnitIds ??= new List<string>();
|
ownedUnitIds ??= new List<string>();
|
||||||
bannerPoolIds ??= new List<string>();
|
bannerPoolIds ??= new List<string>();
|
||||||
|
distroBestWaves ??= new List<DistroBestWaveSaveEntry>();
|
||||||
beginnerBannerState ??= new GachaBannerState(GachaService.BeginnerBannerId);
|
beginnerBannerState ??= new GachaBannerState(GachaService.BeginnerBannerId);
|
||||||
beginnerBannerState.bannerId = GachaService.BeginnerBannerId;
|
beginnerBannerState.bannerId = GachaService.BeginnerBannerId;
|
||||||
beginnerBannerState.EnsureLists();
|
beginnerBannerState.EnsureLists();
|
||||||
lastRunLoadout ??= new LastRunLoadoutSaveEntry();
|
lastRunLoadout ??= new LastRunLoadoutSaveEntry();
|
||||||
lastRunLoadout.EnsureLists();
|
lastRunLoadout.EnsureLists();
|
||||||
|
if (string.IsNullOrWhiteSpace(lastRunDistroId) && !string.IsNullOrWhiteSpace(lastRunLoadout.distroId))
|
||||||
|
{
|
||||||
|
lastRunDistroId = lastRunLoadout.distroId;
|
||||||
|
}
|
||||||
|
|
||||||
|
MigrateLegacyConflatedCurrency();
|
||||||
|
entropyBalance = Math.Max(0, entropyBalance);
|
||||||
|
rootCredits = Math.Max(0, rootCredits);
|
||||||
|
commitsBalance = Math.Max(0, commitsBalance);
|
||||||
|
bandwidthBalance = Math.Max(0, bandwidthBalance);
|
||||||
merges = Math.Max(0, merges);
|
merges = Math.Max(0, merges);
|
||||||
|
packageMerges = Math.Max(0, packageMerges);
|
||||||
|
cacheBalance = Math.Max(0, cacheBalance);
|
||||||
MigrateLegacyOwnedUnitIds();
|
MigrateLegacyOwnedUnitIds();
|
||||||
|
MigrateLegacyOwnedPackageIds();
|
||||||
NormalizeOwnedUnits();
|
NormalizeOwnedUnits();
|
||||||
|
NormalizeOwnedPackages();
|
||||||
|
NormalizePackageLoadouts();
|
||||||
|
NormalizeDistroBestWaves();
|
||||||
MigrateLegacyGlobalMerges();
|
MigrateLegacyGlobalMerges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void MigrateLegacyConflatedCurrency()
|
||||||
|
{
|
||||||
|
if (standardPullCurrency <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bandwidthBalance <= 0)
|
||||||
|
{
|
||||||
|
bandwidthBalance = Math.Max(0, standardPullCurrency);
|
||||||
|
Debug.Log("Migrated legacy standardPullCurrency to Bandwidth. Commits defaulted to 0 because the old field conflated pull tokens and upgrade currency.");
|
||||||
|
}
|
||||||
|
|
||||||
|
standardPullCurrency = 0;
|
||||||
|
limitedPullCurrency = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public OwnedUnitSaveEntry FindOwnedUnit(string id)
|
public OwnedUnitSaveEntry FindOwnedUnit(string id)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrWhiteSpace(id))
|
if (string.IsNullOrWhiteSpace(id))
|
||||||
@@ -176,6 +226,133 @@ namespace KernelPanic.Meta
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void NormalizeOwnedPackages()
|
||||||
|
{
|
||||||
|
HashSet<string> seen = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
for (int i = ownedPackages.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
OwnedPackageSaveEntry entry = ownedPackages[i];
|
||||||
|
if (entry == null || string.IsNullOrWhiteSpace(entry.id) || !seen.Add(entry.id))
|
||||||
|
{
|
||||||
|
ownedPackages.RemoveAt(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.upgradeLevel = Math.Max(0, Math.Min(PackageTuning.MaxPackageLevel, entry.upgradeLevel));
|
||||||
|
}
|
||||||
|
|
||||||
|
ownedPackageIds.Clear();
|
||||||
|
for (int i = 0; i < ownedPackages.Count; i++)
|
||||||
|
{
|
||||||
|
ownedPackageIds.Add(ownedPackages[i].id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int GetBestWave(string distroId)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(distroId))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureLists();
|
||||||
|
for (int i = 0; i < distroBestWaves.Count; i++)
|
||||||
|
{
|
||||||
|
DistroBestWaveSaveEntry entry = distroBestWaves[i];
|
||||||
|
if (entry != null && string.Equals(entry.distroId, distroId, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return Math.Max(0, entry.bestWave);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RecordRunStats(string distroId, int waveReached)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(distroId))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnsureLists();
|
||||||
|
lastRunDistroId = distroId;
|
||||||
|
lastRunLoadout ??= new LastRunLoadoutSaveEntry();
|
||||||
|
lastRunLoadout.distroId = distroId;
|
||||||
|
int safeWave = Math.Max(0, waveReached);
|
||||||
|
for (int i = 0; i < distroBestWaves.Count; i++)
|
||||||
|
{
|
||||||
|
DistroBestWaveSaveEntry entry = distroBestWaves[i];
|
||||||
|
if (entry != null && string.Equals(entry.distroId, distroId, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
entry.bestWave = Math.Max(entry.bestWave, safeWave);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
distroBestWaves.Add(new DistroBestWaveSaveEntry { distroId = distroId, bestWave = safeWave });
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NormalizeDistroBestWaves()
|
||||||
|
{
|
||||||
|
HashSet<string> seen = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
for (int i = distroBestWaves.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
DistroBestWaveSaveEntry entry = distroBestWaves[i];
|
||||||
|
if (entry == null || string.IsNullOrWhiteSpace(entry.distroId) || !seen.Add(entry.distroId))
|
||||||
|
{
|
||||||
|
distroBestWaves.RemoveAt(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.bestWave = Math.Max(0, entry.bestWave);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MigrateLegacyOwnedPackageIds()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ownedPackageIds.Count; i++)
|
||||||
|
{
|
||||||
|
string id = ownedPackageIds[i];
|
||||||
|
if (string.IsNullOrWhiteSpace(id) || HasOwnedPackageEntry(id))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ownedPackages.Add(new OwnedPackageSaveEntry { id = id, upgradeLevel = 0 });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasOwnedPackageEntry(string id)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < ownedPackages.Count; i++)
|
||||||
|
{
|
||||||
|
OwnedPackageSaveEntry entry = ownedPackages[i];
|
||||||
|
if (entry != null && string.Equals(entry.id, id, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void NormalizePackageLoadouts()
|
||||||
|
{
|
||||||
|
HashSet<string> seenDistros = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
for (int i = packageLoadouts.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
PackageLoadoutSaveEntry entry = packageLoadouts[i];
|
||||||
|
if (entry == null || string.IsNullOrWhiteSpace(entry.distroId) || !seenDistros.Add(entry.distroId))
|
||||||
|
{
|
||||||
|
packageLoadouts.RemoveAt(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
entry.EnsureLists();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void MigrateLegacyGlobalMerges()
|
private void MigrateLegacyGlobalMerges()
|
||||||
{
|
{
|
||||||
if (merges <= 0 || ownedUnits.Count == 0)
|
if (merges <= 0 || ownedUnits.Count == 0)
|
||||||
@@ -223,6 +400,13 @@ namespace KernelPanic.Meta
|
|||||||
public int merges;
|
public int merges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public sealed class OwnedPackageSaveEntry
|
||||||
|
{
|
||||||
|
public string id;
|
||||||
|
public int upgradeLevel;
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public sealed class LastRunLoadoutSaveEntry
|
public sealed class LastRunLoadoutSaveEntry
|
||||||
{
|
{
|
||||||
@@ -234,4 +418,39 @@ namespace KernelPanic.Meta
|
|||||||
cardIds ??= new List<string>();
|
cardIds ??= new List<string>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public sealed class DistroBestWaveSaveEntry
|
||||||
|
{
|
||||||
|
public string distroId;
|
||||||
|
public int bestWave;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public sealed class PackageLoadoutSaveEntry
|
||||||
|
{
|
||||||
|
public string distroId;
|
||||||
|
public List<PackageLoadoutSlotSaveEntry> slots = new();
|
||||||
|
|
||||||
|
public void EnsureLists()
|
||||||
|
{
|
||||||
|
slots ??= new List<PackageLoadoutSlotSaveEntry>();
|
||||||
|
HashSet<PackageSlot> seen = new();
|
||||||
|
for (int i = slots.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
PackageLoadoutSlotSaveEntry slot = slots[i];
|
||||||
|
if (slot == null || string.IsNullOrWhiteSpace(slot.packageId) || !seen.Add(slot.slot))
|
||||||
|
{
|
||||||
|
slots.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public sealed class PackageLoadoutSlotSaveEntry
|
||||||
|
{
|
||||||
|
public PackageSlot slot;
|
||||||
|
public string packageId;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user