Implement Java and Rust cards alongside some smaller changes

This commit is contained in:
2026-07-08 11:30:32 +02:00
parent 50135e2e38
commit 54906bbba1
20 changed files with 531 additions and 93 deletions
@@ -11,19 +11,26 @@
</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/Resources/GamblingScene.uss" afterDir="false" /> <change afterPath="$PROJECT_DIR$/Assets/Data/Cards/Languages/Java/JavaNewObject.asset" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Assets/Resources/RarityPresentation.uss" afterDir="false" /> <change afterPath="$PROJECT_DIR$/Assets/Data/Cards/Languages/Java/JavaPublicStaticMain.asset" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Assets/Scripts/Meta/GachaPullContext.cs" afterDir="false" /> <change afterPath="$PROJECT_DIR$/Assets/Data/Cards/Languages/Java/JavaSystemOutPrintln.asset" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Assets/Scripts/UI/GamblingSceneController.cs" afterDir="false" /> <change afterPath="$PROJECT_DIR$/Assets/Data/Cards/Languages/JavaDeck.asset" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Assets/Scripts/UI/RarityPresentation.cs" afterDir="false" /> <change afterPath="$PROJECT_DIR$/Assets/Data/Cards/Languages/Rust/RsBorrow.asset" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Assets/Data/Cards/Languages/Rust/RsFnMain.asset" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Assets/Data/Cards/Languages/Rust/RsUnwrap.asset" afterDir="false" />
<change afterPath="$PROJECT_DIR$/Assets/Data/Cards/Languages/RustDeck.asset" 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/Scenes/GamblingScene.unity" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scenes/GamblingScene.unity" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Assets/Data/Cards/CardDatabase.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Data/Cards/CardDatabase.asset" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Core/SceneLoader.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Core/SceneLoader.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Assets/Data/Cards/Fedora/BorrowChecker.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Data/Cards/Fedora/BorrowChecker.asset" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Meta/GachaTuning.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Meta/GachaTuning.cs" afterDir="false" /> <change beforePath="$PROJECT_DIR$/Assets/Data/Cards/Fedora/CargoBuildRelease.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Data/Cards/Fedora/CargoBuildRelease.asset" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Data/Cards/Languages/LanguageDeckDatabase.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Data/Cards/Languages/LanguageDeckDatabase.asset" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Data/Distros/Fedora.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Data/Distros/Fedora.asset" 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/CardInstance.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Combat/CardInstance.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/HandController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Combat/HandController.cs" afterDir="false" />
<change beforePath="$PROJECT_DIR$/Assets/Scripts/Data/LanguageCatalog.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Data/LanguageCatalog.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/GachaScreenController.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/UI/GachaScreenController.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$/ProjectSettings/EditorBuildSettings.asset" beforeDir="false" afterPath="$PROJECT_DIR$/ProjectSettings/EditorBuildSettings.asset" 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" />
@@ -55,7 +62,11 @@
} }
}</component> }</component>
<component name="HighlightingSettingsPerFile"> <component name="HighlightingSettingsPerFile">
<setting file="file://$PROJECT_DIR$/Assets/Data/Cards/Fedora/BorrowChecker.asset" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Assets/Data/Cards/Fedora/CargoBuildRelease.asset" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Assets/Data/Cards/Fedora/CargoBuildRelease.asset" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Assets/Data/Cards/Fedora/DnfUpdate.asset" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Assets/Data/Cards/Languages/Java/JavaPublicStaticMain.asset" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Assets/Data/Cards/Languages/Java/JavaSystemOutPrintln.asset" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Assets/Data/Cards/Languages/Python/PyPrint.asset" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Assets/Data/Cards/Languages/Python/PyPrint.asset" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Assets/Data/Cards/Ubuntu/AskUbuntu.asset" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Assets/Data/Cards/Ubuntu/AskUbuntu.asset" root0="FORCE_HIGHLIGHTING" />
<setting file="file://$PROJECT_DIR$/Assets/Data/Distros/DistroDatabase.asset" root0="FORCE_HIGHLIGHTING" /> <setting file="file://$PROJECT_DIR$/Assets/Data/Distros/DistroDatabase.asset" root0="FORCE_HIGHLIGHTING" />
@@ -80,23 +91,23 @@
<component name="MetaFilesCheckinStateConfiguration" checkMetaFiles="true" /> <component name="MetaFilesCheckinStateConfiguration" checkMetaFiles="true" />
<component name="NextEditCompletionFeaturesState"> <component name="NextEditCompletionFeaturesState">
<decayedCancelled> <decayedCancelled>
<entry key="MS100" value="1.0623037946223934" /> <entry key="MS100" value="1.7745080781518747" />
<entry key="MS500" value="3.3946231944932093" /> <entry key="MS500" value="5.494883000294699" />
<entry key="S2" value="13.152660945937393" /> <entry key="S2" value="13.540161770151046" />
<entry key="S5" value="24.1598334590001" /> <entry key="S5" value="23.840938265908584" />
<entry key="S10" value="33.8798077205763" /> <entry key="S10" value="37.73345622347476" />
<entry key="S30" value="58.19510567053269" /> <entry key="S30" value="84.57208484998908" />
<entry key="S60" value="77.3856499085495" /> <entry key="S60" value="143.95189989985906" />
<entry key="M2" value="102.00601157029814" /> <entry key="M2" value="220.15898543823553" />
<entry key="M5" value="137.65784976271723" /> <entry key="M5" value="315.3671327614578" />
<entry key="M10" value="165.66654267587106" /> <entry key="M10" value="385.2774636863717" />
<entry key="M15" value="186.93733876684658" /> <entry key="M15" value="435.0925737567707" />
<entry key="M30" value="255.34135629387984" /> <entry key="M30" value="551.959520858503" />
<entry key="H1" value="366.1678729821731" /> <entry key="H1" value="715.8254467553472" />
<entry key="H2" value="476.8702050334635" /> <entry key="H2" value="889.3981211254871" />
<entry key="H4" value="590.3523177793572" /> <entry key="H4" value="1053.976456033934" />
<entry key="D1" value="1946.7042196302243" /> <entry key="D1" value="2453.031132891062" />
<entry key="W1" value="3215.7039196395745" /> <entry key="W1" value="3757.0476380579075" />
</decayedCancelled> </decayedCancelled>
<decayedSelected> <decayedSelected>
<entry key="MS100" value="0.0" /> <entry key="MS100" value="0.0" />
@@ -106,35 +117,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="5.2702880915532256E-223" /> <entry key="M2" value="4.9047462196789525E-230" />
<entry key="M5" value="1.2266869422157816E-89" /> <entry key="M5" value="1.889063759565985E-92" />
<entry key="M10" value="3.502409088350206E-45" /> <entry key="M10" value="1.3744321589536667E-46" />
<entry key="M15" value="2.3062758293224876E-30" /> <entry key="M15" value="2.6632720957412003E-31" />
<entry key="M30" value="1.5186432482681809E-15" /> <entry key="M30" value="5.160691631924263E-16" />
<entry key="H1" value="3.900807883852808E-8" /> <entry key="H1" value="2.2739485517900192E-8" />
<entry key="H2" value="2.0812823039862135E-4" /> <entry key="H2" value="1.589073656746164E-4" />
<entry key="H4" value="0.01972130313642213" /> <entry key="H4" value="0.01723225556677517" />
<entry key="D1" value="1.5461273409431215" /> <entry key="D1" value="1.511748964440463" />
<entry key="W1" value="3.487343990420277" /> <entry key="W1" value="3.476159578917258" />
</decayedSelected> </decayedSelected>
<decayedShown> <decayedShown>
<entry key="MS100" value="1.0197451953704615" /> <entry key="MS100" value="1.7184635520820462" />
<entry key="MS500" value="3.3707583435859494" /> <entry key="MS500" value="5.451310134754918" />
<entry key="S2" value="13.129985145747765" /> <entry key="S2" value="13.508716422466016" />
<entry key="S5" value="24.143018672679645" /> <entry key="S5" value="23.818087310576672" />
<entry key="S10" value="33.867989076642985" /> <entry key="S10" value="37.7154028872074" />
<entry key="S30" value="58.188374682435416" /> <entry key="S30" value="84.55887260233759" />
<entry key="S60" value="77.38119558741009" /> <entry key="S60" value="143.94070760442918" />
<entry key="M2" value="102.00309255211835" /> <entry key="M2" value="220.1504902812646" />
<entry key="M5" value="137.6562714734684" /> <entry key="M5" value="315.3623307934439" />
<entry key="M10" value="165.6655746148282" /> <entry key="M10" value="385.27455591371523" />
<entry key="M15" value="186.93658735123063" /> <entry key="M15" value="435.0903859691819" />
<entry key="M30" value="255.34078224152634" /> <entry key="M30" value="551.9581184345019" />
<entry key="H1" value="366.16741523840614" /> <entry key="H1" value="715.8245138452602" />
<entry key="H2" value="476.8700971872463" /> <entry key="H2" value="889.3976854411949" />
<entry key="H4" value="590.3718230883779" /> <entry key="H4" value="1053.9933170489687" />
<entry key="D1" value="1948.2500994732964" /> <entry key="D1" value="2454.542608558042" />
<entry key="W1" value="3219.19119674037" /> <entry key="W1" value="3760.5237264671973" />
</decayedShown> </decayedShown>
</component> </component>
<component name="ProjectColorInfo">{ <component name="ProjectColorInfo">{
@@ -223,7 +234,7 @@
<workItem from="1783330590375" duration="18451000" /> <workItem from="1783330590375" duration="18451000" />
<workItem from="1783371975450" duration="26000" /> <workItem from="1783371975450" duration="26000" />
<workItem from="1783372397891" duration="989000" /> <workItem from="1783372397891" duration="989000" />
<workItem from="1783410502976" duration="19169000" /> <workItem from="1783410502976" duration="22472000" />
</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" />
@@ -385,7 +396,23 @@
<option name="project" value="LOCAL" /> <option name="project" value="LOCAL" />
<updated>1783493370994</updated> <updated>1783493370994</updated>
</task> </task>
<option name="localTasksCounter" value="21" /> <task id="LOCAL-00021" summary="Implement cutscene for gambling and make it dopamine-inducing">
<option name="closed" value="true" />
<created>1783499391622</created>
<option name="number" value="00021" />
<option name="presentableId" value="LOCAL-00021" />
<option name="project" value="LOCAL" />
<updated>1783499391622</updated>
</task>
<task id="LOCAL-00022" summary="changed most TODOs to TODONEs">
<option name="closed" value="true" />
<created>1783500547647</created>
<option name="number" value="00022" />
<option name="presentableId" value="LOCAL-00022" />
<option name="project" value="LOCAL" />
<updated>1783500547647</updated>
</task>
<option name="localTasksCounter" value="23" />
<servers /> <servers />
</component> </component>
<component name="TypeScriptGeneratedFilesManager"> <component name="TypeScriptGeneratedFilesManager">
@@ -420,7 +447,9 @@
<MESSAGE value="make some small changes to merging" /> <MESSAGE value="make some small changes to merging" />
<MESSAGE value="Fix balls" /> <MESSAGE value="Fix balls" />
<MESSAGE value="update some strings" /> <MESSAGE value="update some strings" />
<option name="LAST_COMMIT_MESSAGE" value="update some strings" /> <MESSAGE value="Implement cutscene for gambling and make it dopamine-inducing" />
<MESSAGE value="changed most TODOs to TODONEs" />
<option name="LAST_COMMIT_MESSAGE" value="changed most TODOs to TODONEs" />
</component> </component>
<component name="XDebuggerManager"> <component name="XDebuggerManager">
<breakpoint-manager> <breakpoint-manager>
+6
View File
@@ -41,3 +41,9 @@ MonoBehaviour:
- {fileID: 11400000, guid: a7d50000000000000000000000000004, type: 2} - {fileID: 11400000, guid: a7d50000000000000000000000000004, type: 2}
- {fileID: 11400000, guid: a7d50000000000000000000000000005, type: 2} - {fileID: 11400000, guid: a7d50000000000000000000000000005, type: 2}
- {fileID: 11400000, guid: a7d50000000000000000000000000006, type: 2} - {fileID: 11400000, guid: a7d50000000000000000000000000006, type: 2}
- {fileID: 11400000, guid: a7d60000000000000000000000000001, type: 2}
- {fileID: 11400000, guid: a7d60000000000000000000000000002, type: 2}
- {fileID: 11400000, guid: a7d60000000000000000000000000003, type: 2}
- {fileID: 11400000, guid: a7d60000000000000000000000000004, type: 2}
- {fileID: 11400000, guid: a7d60000000000000000000000000005, type: 2}
- {fileID: 11400000, guid: a7d60000000000000000000000000006, type: 2}
+6 -6
View File
@@ -10,18 +10,18 @@ MonoBehaviour:
m_Enabled: 1 m_Enabled: 1
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3} m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3}
m_Name: BorrowChecker m_Name: DnfAutoremove
m_EditorClassIdentifier: m_EditorClassIdentifier:
id: fedora_borrow_checker id: fedora_dnf_autoremove
displayName: borrow checker displayName: dnf autoremove
description: gain 8 shield. if this is the first card played this turn, gain 8 more. description: deal 7, then exhaust a junk/NOP/broken card from your hand. if you do, gain 1 Cycle. if you don't, do nothing.
flavorText: no aliasing, no panic. flavorText: cleaning out orphaned packages.
language: 2 language: 2
rarity: 0 rarity: 0
cycleCost: 1 cycleCost: 1
resolutionTrack: 0 resolutionTrack: 0
distroExclusive: 1 distroExclusive: 1
isToken: 0 isToken: 0
designNotes: defensive first-card payoff; should benefit from Bleeding Edge cost discount but not damage multiplier. designNotes: Fedora keeps a tidy system; requires an orphaned token/junk/NOP/broken card in hand, otherwise the card has no effect.
upgradeTarget: {fileID: 0} upgradeTarget: {fileID: 0}
effects: [] effects: []
@@ -10,18 +10,18 @@ MonoBehaviour:
m_Enabled: 1 m_Enabled: 1
m_EditorHideFlags: 0 m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3} m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3}
m_Name: CargoBuildRelease m_Name: FirstToPackage
m_EditorClassIdentifier: m_EditorClassIdentifier:
id: fedora_cargo_build id: fedora_first_to_package
displayName: cargo build --release displayName: first-to-package
description: deal 10. never misses. overkill becomes shield. description: deal 7, then Java cards cost 1 less this turn.
flavorText: optimized, audited, shipped hot. flavorText: Fedora ships new tech first; everything after comes cheaper.
language: 2 language: 8
rarity: 0 rarity: 0
cycleCost: 1 cycleCost: 1
resolutionTrack: 0 resolutionTrack: 0
distroExclusive: 1 distroExclusive: 1
isToken: 0 isToken: 0
designNotes: crash-immune Fedora finisher; Rust guaranteed hit; convert excess damage into shield after lethal calculation. designNotes: Java native tempo card; reduces the effective cost of all Java cards for the current turn after resolving.
upgradeTarget: {fileID: 0} upgradeTarget: {fileID: 0}
effects: [] effects: []
@@ -0,0 +1,29 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3}
m_Name: JavaNewObject
m_EditorClassIdentifier:
id: lang_java_new_object
displayName: new Object()
description: uses 2 RAM. deal 3. JIT applies.
flavorText: allocation as a love language.
language: 8
rarity: 0
cycleCost: 1
resolutionTrack: 0
distroExclusive: 0
isToken: 0
isRunOnly: 0
designNotes: Java starter cheap damage; benefits from combat-wide JIT warmup.
requiresSystem: []
upgradeTarget: {fileID: 0}
effects: []
@@ -0,0 +1,29 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3}
m_Name: JavaPublicStaticMain
m_EditorClassIdentifier:
id: lang_java_public_static_main
displayName: public static void main
description: uses 2 RAM. deal 7. JIT: Java cards cost 1 less this combat each time you play a Java card; the discount decays by 1 after each wave.
flavorText: verbose, but warmed up.
language: 8
rarity: 0
cycleCost: 3
resolutionTrack: 0
distroExclusive: 0
isToken: 0
isRunOnly: 0
designNotes: Java starter heavy hit; JIT cost reduction is handled by combat-wide Java warmup and cools by 1 between waves.
requiresSystem: []
upgradeTarget: {fileID: 0}
effects: []
@@ -0,0 +1,29 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3}
m_Name: JavaSystemOutPrintln
m_EditorClassIdentifier:
id: lang_java_system_out_println
displayName: System.out.println
description: uses 2 RAM. deal 5. JIT applies.
flavorText: standard output, standard damage.
language: 8
rarity: 0
cycleCost: 2
resolutionTrack: 0
distroExclusive: 0
isToken: 0
isRunOnly: 0
designNotes: Java starter mid-cost damage; benefits from combat-wide JIT warmup.
requiresSystem: []
upgradeTarget: {fileID: 0}
effects: []
@@ -0,0 +1,22 @@
%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: a7d10000000000000000000000000001, type: 3}
m_Name: JavaDeck
m_EditorClassIdentifier:
language: 8
entries:
- card: {fileID: 11400000, guid: a7d60000000000000000000000000004, type: 2}
count: 2
- card: {fileID: 11400000, guid: a7d60000000000000000000000000005, type: 2}
count: 1
- card: {fileID: 11400000, guid: a7d60000000000000000000000000006, type: 2}
count: 1
@@ -15,3 +15,5 @@ MonoBehaviour:
allDecks: allDecks:
- {fileID: 11400000, guid: a7d50000000000000000000000000001, type: 2} - {fileID: 11400000, guid: a7d50000000000000000000000000001, type: 2}
- {fileID: 11400000, guid: a7d50000000000000000000000000002, type: 2} - {fileID: 11400000, guid: a7d50000000000000000000000000002, type: 2}
- {fileID: 11400000, guid: a7d70000000000000000000000000001, type: 2}
- {fileID: 11400000, guid: a7d70000000000000000000000000002, type: 2}
@@ -0,0 +1,29 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3}
m_Name: RsBorrow
m_EditorClassIdentifier:
id: lang_rs_borrow
displayName: borrow
description: gain 5 Shield.
flavorText: no ownership transfer required.
language: 2
rarity: 0
cycleCost: 0
resolutionTrack: 0
distroExclusive: 0
isToken: 0
isRunOnly: 0
designNotes: Rust starter defense.
requiresSystem: []
upgradeTarget: {fileID: 0}
effects: []
@@ -0,0 +1,29 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3}
m_Name: RsFnMain
m_EditorClassIdentifier:
id: lang_rs_fn_main
displayName: fn main()
description: deal 6. cannot miss. overkill becomes Shield.
flavorText: the entry point has teeth.
language: 2
rarity: 0
cycleCost: 1
resolutionTrack: 0
distroExclusive: 0
isToken: 0
isRunOnly: 0
designNotes: Rust starter damage; reliable hit with overkill converted into shield.
requiresSystem: []
upgradeTarget: {fileID: 0}
effects: []
@@ -0,0 +1,29 @@
%YAML 1.1
%TAG !u! tag:unity3d.com,2011:
--- !u!114 &11400000
MonoBehaviour:
m_ObjectHideFlags: 0
m_CorrespondingSourceObject: {fileID: 0}
m_PrefabInstance: {fileID: 0}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 5178747fac4dbfc448ff15d8a687e03c, type: 3}
m_Name: RsUnwrap
m_EditorClassIdentifier:
id: lang_rs_unwrap
displayName: unwrap()
description: deal 9. cannot miss. draw 1.
flavorText: confidence, weaponized.
language: 2
rarity: 0
cycleCost: 1
resolutionTrack: 0
distroExclusive: 0
isToken: 0
isRunOnly: 0
designNotes: Rust starter burst plus replacement draw.
requiresSystem: []
upgradeTarget: {fileID: 0}
effects: []
@@ -0,0 +1,22 @@
%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: a7d10000000000000000000000000001, type: 3}
m_Name: RustDeck
m_EditorClassIdentifier:
language: 2
entries:
- card: {fileID: 11400000, guid: a7d60000000000000000000000000001, type: 2}
count: 2
- card: {fileID: 11400000, guid: a7d60000000000000000000000000002, type: 2}
count: 1
- card: {fileID: 11400000, guid: a7d60000000000000000000000000003, type: 2}
count: 1
+1 -1
View File
@@ -27,7 +27,7 @@ MonoBehaviour:
asciiArt: {fileID: 4900000, guid: f2373174b6954f2d9088d83d10e0d9e4, type: 3} asciiArt: {fileID: 4900000, guid: f2373174b6954f2d9088d83d10e0d9e4, type: 3}
accentColor: {r: 0.23529412, g: 0.43137255, b: 0.7058824, a: 1} accentColor: {r: 0.23529412, g: 0.43137255, b: 0.7058824, a: 1}
baseUptime: 55 baseUptime: 55
baseRam: 5 baseRam: 6
baseCyclesPerTurn: 3 baseCyclesPerTurn: 3
exclusiveCards: exclusiveCards:
- {fileID: 11400000, guid: 4dfd40ca206341ba9a1a486d69994611, type: 2} - {fileID: 11400000, guid: 4dfd40ca206341ba9a1a486d69994611, type: 2}
+127 -9
View File
@@ -216,7 +216,7 @@ namespace KernelPanic.Combat
public void Execute(CombatContext context) public void Execute(CombatContext context)
{ {
int room = context.HandController.RamCapacity - context.HandController.Cards.Count; int room = context.HandController.RemainingRam;
if (room <= 0) if (room <= 0)
{ {
context.CombatManager.ReportEffectResult("hand full: drew 0"); context.CombatManager.ReportEffectResult("hand full: drew 0");
@@ -242,6 +242,10 @@ namespace KernelPanic.Combat
{ {
added++; added++;
} }
else
{
context.DeckController.AddToDrawPile(drawn[i], shuffle: false);
}
} }
string capped = drawCount < requested ? " (hand full)" : string.Empty; string capped = drawCount < requested ? " (hand full)" : string.Empty;
@@ -285,7 +289,7 @@ namespace KernelPanic.Combat
{ {
public void Execute(CombatContext context) public void Execute(CombatContext context)
{ {
if (context.HandController.Cards.Count >= context.HandController.RamCapacity) if (context.HandController.RemainingRam <= 0)
{ {
context.CombatManager.ReportEffectResult("hand full: copied 0"); context.CombatManager.ReportEffectResult("hand full: copied 0");
return; return;
@@ -316,6 +320,12 @@ namespace KernelPanic.Combat
} }
CardInstance copy = selected.CopyForCombat(); CardInstance copy = selected.CopyForCombat();
if (!context.HandController.CanAdd(copy))
{
context.CombatManager.ReportEffectResult("not enough RAM to copy");
return;
}
if (context.HandController.Add(copy)) if (context.HandController.Add(copy))
{ {
string name = string.IsNullOrWhiteSpace(copy.Definition.DisplayName) ? copy.Definition.Id : copy.Definition.DisplayName; string name = string.IsNullOrWhiteSpace(copy.Definition.DisplayName) ? copy.Definition.Id : copy.Definition.DisplayName;
@@ -403,7 +413,7 @@ namespace KernelPanic.Combat
public void Execute(CombatContext context) public void Execute(CombatContext context)
{ {
if (context.HandController.Cards.Count >= context.HandController.RamCapacity) if (context.HandController.RemainingRam <= 0)
{ {
context.CombatManager.ReportEffectResult("hand full: generated 0"); context.CombatManager.ReportEffectResult("hand full: generated 0");
return; return;
@@ -415,7 +425,11 @@ namespace KernelPanic.Combat
return; return;
} }
if (context.HandController.Add(generatedCard)) if (!context.HandController.CanAdd(generatedCard))
{
context.CombatManager.ReportEffectResult("not enough RAM: generated 0");
}
else if (context.HandController.Add(generatedCard))
{ {
context.CombatManager.ReportEffectResult($"generated {GetCardName(generatedCard)} at 0c"); context.CombatManager.ReportEffectResult($"generated {GetCardName(generatedCard)} at 0c");
} }
@@ -491,6 +505,92 @@ namespace KernelPanic.Combat
} }
} }
public sealed class FirstToPackageEffect : ICardEffect
{
private readonly int _amount;
public FirstToPackageEffect(int amount)
{
_amount = amount;
}
public void Execute(CombatContext context)
{
int amount = UpgradeMath.ScaleAmount(UpgradeMath.ApplySourceFlatBonus(_amount, context), context.Card);
new DealDamageEffect(amount, amount, Language.Java).Execute(context);
context.CombatManager.AddJavaCostDiscountThisTurn(1);
}
}
public sealed class DnfAutoremoveEffect : ICardEffect
{
private readonly int _damageAmount;
private readonly int _cycleGain;
public DnfAutoremoveEffect(int damageAmount, int cycleGain)
{
_damageAmount = damageAmount;
_cycleGain = cycleGain;
}
public void Execute(CombatContext context)
{
CardInstance junk = FindJunkCard(context);
if (junk == null)
{
context.CombatManager.ReportEffectResult("dnf autoremove: no orphaned package");
return;
}
int damageAmount = UpgradeMath.ScaleAmount(UpgradeMath.ApplySourceFlatBonus(_damageAmount, context), context.Card);
new DealDamageEffect(damageAmount, damageAmount, Language.Rust).Execute(context);
if (context.HandController.Remove(junk))
{
context.DeckController.Exhaust(junk);
int cycleGain = UpgradeMath.ScaleAmount(_cycleGain, context.Card);
context.Source.Cycles += cycleGain;
context.CombatManager.ReportEffectResult($"autoremove exhausted {GetCardName(junk)}: +{cycleGain} cycle");
}
}
private static CardInstance FindJunkCard(CombatContext context)
{
for (int i = 0; i < context.HandController.Cards.Count; i++)
{
CardInstance card = context.HandController.Cards[i];
if (IsJunk(card))
{
return card;
}
}
return null;
}
private static bool IsJunk(CardInstance card)
{
if (card == null)
{
return false;
}
string id = card.Definition?.Id ?? string.Empty;
string name = card.Definition?.DisplayName ?? string.Empty;
return card.Definition != null && card.Definition.IsToken
|| card.IsBroken
|| id.IndexOf("junk", System.StringComparison.OrdinalIgnoreCase) >= 0
|| id.IndexOf("nop", System.StringComparison.OrdinalIgnoreCase) >= 0
|| name.IndexOf("junk", System.StringComparison.OrdinalIgnoreCase) >= 0
|| name.IndexOf("NOP", System.StringComparison.OrdinalIgnoreCase) >= 0
|| name.IndexOf("broken", System.StringComparison.OrdinalIgnoreCase) >= 0;
}
private static string GetCardName(CardInstance card)
{
return string.IsNullOrWhiteSpace(card?.Definition?.DisplayName) ? card?.Definition?.Id ?? "--" : card.Definition.DisplayName;
}
}
public sealed class UpdateManagerEffect : ICardEffect public sealed class UpdateManagerEffect : ICardEffect
{ {
private readonly int _amount; private readonly int _amount;
@@ -573,6 +673,16 @@ namespace KernelPanic.Combat
"lang_py_for_loop" => One(new DealDamageEffect(2, 2, Language.Python, allEnemies: true)), "lang_py_for_loop" => One(new DealDamageEffect(2, 2, Language.Python, allEnemies: true)),
"lang_js_console_log" => One(new DealDamageEffect(3, 9, Language.JavaScript)), "lang_js_console_log" => One(new DealDamageEffect(3, 9, Language.JavaScript)),
"lang_js_fetch" => One(new DealDamageEffect(5, 13, Language.JavaScript)), "lang_js_fetch" => One(new DealDamageEffect(5, 13, Language.JavaScript)),
"lang_rs_fn_main" => One(new OverkillToShieldDamageEffect(6, Language.Rust)),
"lang_rs_unwrap" => new ICardEffect[]
{
new DealDamageEffect(9, 9, Language.Rust),
new DrawEffect(1)
},
"lang_rs_borrow" => One(new ShieldEffect(5)),
"lang_java_public_static_main" => One(new DealDamageEffect(7, 7, Language.Java)),
"lang_java_system_out_println" => One(new DealDamageEffect(5, 5, Language.Java)),
"lang_java_new_object" => One(new DealDamageEffect(3, 3, Language.Java)),
"ubuntu_ask_ubuntu" => One(new DrawEffect(2)), "ubuntu_ask_ubuntu" => One(new DrawEffect(2)),
"ubuntu_unattended_upgrades" => new ICardEffect[] "ubuntu_unattended_upgrades" => new ICardEffect[]
{ {
@@ -616,8 +726,8 @@ namespace KernelPanic.Combat
}, },
"mint_nemo" => One(new ConditionalShieldRepeatDamageEffect(6, Language.JavaScript)), "mint_nemo" => One(new ConditionalShieldRepeatDamageEffect(6, Language.JavaScript)),
"mint_timeshift" => One(new TimeshiftSnapshotEffect()), "mint_timeshift" => One(new TimeshiftSnapshotEffect()),
"fedora_borrow_checker" => One(new FirstCardShieldEffect(8, 8)), "fedora_dnf_autoremove" => One(new DnfAutoremoveEffect(7, 1)),
"fedora_cargo_build" => One(new OverkillToShieldDamageEffect(10, Language.Rust)), "fedora_first_to_package" => One(new FirstToPackageEffect(7)),
"fedora_dnf_update" => One(new DealDamageEffect(9, 9, Language.Java)), "fedora_dnf_update" => One(new DealDamageEffect(9, 9, Language.Java)),
"fedora_rawhide" => One(new RawhideEffect()), "fedora_rawhide" => One(new RawhideEffect()),
"fedora_selinux" => One(new IncomingAttackHalveEffect(2)), "fedora_selinux" => One(new IncomingAttackHalveEffect(2)),
@@ -628,8 +738,10 @@ namespace KernelPanic.Combat
public static bool RequiresSingleTarget(CardDefinition definition) public static bool RequiresSingleTarget(CardDefinition definition)
{ {
return definition?.Id is "lang_js_console_log" or "lang_js_fetch" or "lang_js_typeof" or "mint_fix_broken" return definition?.Id is "lang_js_console_log" or "lang_js_fetch" or "lang_js_typeof" or "mint_fix_broken"
or "lang_rs_fn_main" or "lang_rs_unwrap" or "lang_java_public_static_main"
or "lang_java_system_out_println" or "lang_java_new_object"
or "shop_py_list_append" or "shop_js_math_random" or "shop_js_promise_all" or "ubuntu_snap_install" or "shop_py_list_append" or "shop_js_math_random" or "shop_js_promise_all" or "ubuntu_snap_install"
or "mint_nemo" or "fedora_cargo_build" or "fedora_dnf_update"; or "mint_nemo" or "fedora_dnf_autoremove" or "fedora_first_to_package" or "fedora_dnf_update";
} }
public static bool TargetsAllEnemies(CardDefinition definition) public static bool TargetsAllEnemies(CardDefinition definition)
@@ -684,6 +796,12 @@ namespace KernelPanic.Combat
"lang_js_console_log" => $"deal {UpgradeMath.ScaleAmount(3, card)}-{UpgradeMath.ScaleAmount(9, card)}.{marker}", "lang_js_console_log" => $"deal {UpgradeMath.ScaleAmount(3, card)}-{UpgradeMath.ScaleAmount(9, card)}.{marker}",
"lang_js_fetch" => $"deal {UpgradeMath.ScaleAmount(5, card)}-{UpgradeMath.ScaleAmount(13, card)}.{marker}", "lang_js_fetch" => $"deal {UpgradeMath.ScaleAmount(5, card)}-{UpgradeMath.ScaleAmount(13, card)}.{marker}",
"lang_js_typeof" => $"75%: deal {UpgradeMath.ScaleAmount(8, card)}. 25%: deal 0.{marker}", "lang_js_typeof" => $"75%: deal {UpgradeMath.ScaleAmount(8, card)}. 25%: deal 0.{marker}",
"lang_rs_fn_main" => $"deal {UpgradeMath.ScaleAmount(6, card)}. overkill becomes shield.{marker}",
"lang_rs_unwrap" => $"deal {UpgradeMath.ScaleAmount(9, card)}. draw {UpgradeMath.ScaleAmount(1, card)}.{marker}",
"lang_rs_borrow" => $"gain {UpgradeMath.ScaleShield(5, card)} shield.{marker}",
"lang_java_public_static_main" => $"uses 2 RAM. deal {UpgradeMath.ScaleAmount(7, card)}. JIT: Java cards cost 1 less this combat each time you play a Java card; discount decays by 1 after each wave.{marker}",
"lang_java_system_out_println" => $"uses 2 RAM. deal {UpgradeMath.ScaleAmount(5, card)}. JIT applies; discount decays by 1 after each wave.{marker}",
"lang_java_new_object" => $"uses 2 RAM. deal {UpgradeMath.ScaleAmount(3, card)}. JIT applies; discount decays by 1 after each wave.{marker}",
"shop_py_list_append" => $"queue: deal {UpgradeMath.ScaleAmount(4 + UnityEngine.Mathf.Max(0, card.QueuePlayCount - 1), card)}; +1 each time re-queued.{marker}", "shop_py_list_append" => $"queue: deal {UpgradeMath.ScaleAmount(4 + UnityEngine.Mathf.Max(0, card.QueuePlayCount - 1), card)}; +1 each time re-queued.{marker}",
"shop_py_async_def" => $"queue: draw {UpgradeMath.ScaleAmount(2, card)}. gain {UpgradeMath.ScaleAmount(1, card)} cycle next turn.{marker}", "shop_py_async_def" => $"queue: draw {UpgradeMath.ScaleAmount(2, card)}. gain {UpgradeMath.ScaleAmount(1, card)} cycle next turn.{marker}",
"shop_py_zip" => $"next {UpgradeMath.ScaleAmount(2, card)} queued cards resolve twice.{marker}", "shop_py_zip" => $"next {UpgradeMath.ScaleAmount(2, card)} queued cards resolve twice.{marker}",
@@ -700,8 +818,8 @@ namespace KernelPanic.Combat
"mint_cinnamon" => $"queue: gain {UpgradeMath.ScaleShield(3, card)} shield. draw {UpgradeMath.ScaleAmount(1, card)}.{marker}", "mint_cinnamon" => $"queue: gain {UpgradeMath.ScaleShield(3, card)} shield. draw {UpgradeMath.ScaleAmount(1, card)}.{marker}",
"mint_nemo" => $"deal {UpgradeMath.ScaleAmount(6, card)}. if you have shield, deal it again.{marker}", "mint_nemo" => $"deal {UpgradeMath.ScaleAmount(6, card)}. if you have shield, deal it again.{marker}",
"mint_timeshift" => $"queue: record uptime now. at end of your next turn, restore to it if lower.{marker}", "mint_timeshift" => $"queue: record uptime now. at end of your next turn, restore to it if lower.{marker}",
"fedora_borrow_checker" => $"gain {UpgradeMath.ScaleShield(8, card)} shield. if first card this turn, gain {UpgradeMath.ScaleShield(8, card)} more.{marker}", "fedora_dnf_autoremove" => $"deal {UpgradeMath.ScaleAmount(7, card)}. exhaust a junk/NOP/broken card from hand; if you do, gain {UpgradeMath.ScaleAmount(1, card)} cycle. if not, do nothing.{marker}",
"fedora_cargo_build" => $"deal {UpgradeMath.ScaleAmount(10, card)}. overkill becomes shield.{marker}", "fedora_first_to_package" => $"deal {UpgradeMath.ScaleAmount(7, card)}. Java cards cost 1 less this turn.{marker}",
"fedora_dnf_update" => $"deal {UpgradeMath.ScaleAmount(9, card)}. costs 1 less per Java card played this combat.{marker}", "fedora_dnf_update" => $"deal {UpgradeMath.ScaleAmount(9, card)}. costs 1 less per Java card played this combat.{marker}",
"fedora_rawhide" => $"draw {UpgradeMath.ScaleAmount(2, card)}. next card this turn gains bleeding edge.{marker}", "fedora_rawhide" => $"draw {UpgradeMath.ScaleAmount(2, card)}. next card this turn gains bleeding edge.{marker}",
"fedora_selinux" => $"next {UpgradeMath.ScaleAmount(2, card)} enemy attacks deal half damage.{marker}", "fedora_selinux" => $"next {UpgradeMath.ScaleAmount(2, card)} enemy attacks deal half damage.{marker}",
+9
View File
@@ -25,6 +25,7 @@ namespace KernelPanic.Combat
public int UpgradeLevel { get; private set; } public int UpgradeLevel { get; private set; }
public int QueuePlayCount { get; private set; } public int QueuePlayCount { get; private set; }
public bool WasFirstCardThisTurn { get; private set; } public bool WasFirstCardThisTurn { get; private set; }
public bool HadFedoraNonCrashBonus { get; private set; }
public bool IsBroken { get; set; } public bool IsBroken { get; set; }
public bool IsLocked { get; set; } public bool IsLocked { get; set; }
public bool CanUpgrade => UpgradeLevel == 0; public bool CanUpgrade => UpgradeLevel == 0;
@@ -100,6 +101,12 @@ namespace KernelPanic.Combat
public void MarkPlayedThisTurn(bool wasFirst) public void MarkPlayedThisTurn(bool wasFirst)
{ {
WasFirstCardThisTurn = wasFirst; WasFirstCardThisTurn = wasFirst;
HadFedoraNonCrashBonus = false;
}
public void MarkFedoraNonCrashBonus()
{
HadFedoraNonCrashBonus = true;
} }
public CardInstance CopyForCombat() public CardInstance CopyForCombat()
@@ -117,6 +124,7 @@ namespace KernelPanic.Combat
copy.UpgradeLevel = UpgradeLevel; copy.UpgradeLevel = UpgradeLevel;
copy.QueuePlayCount = QueuePlayCount; copy.QueuePlayCount = QueuePlayCount;
copy.WasFirstCardThisTurn = WasFirstCardThisTurn; copy.WasFirstCardThisTurn = WasFirstCardThisTurn;
copy.HadFedoraNonCrashBonus = HadFedoraNonCrashBonus;
copy.SetTargetSnapshot(TargetSnapshot); copy.SetTargetSnapshot(TargetSnapshot);
return copy; return copy;
} }
@@ -142,6 +150,7 @@ namespace KernelPanic.Combat
TemporaryCostDelta = 0; TemporaryCostDelta = 0;
QueuePlayCount = 0; QueuePlayCount = 0;
WasFirstCardThisTurn = false; WasFirstCardThisTurn = false;
HadFedoraNonCrashBonus = false;
IsBroken = false; IsBroken = false;
IsLocked = false; IsLocked = false;
ClearTargetSnapshot(); ClearTargetSnapshot();
+42 -7
View File
@@ -40,6 +40,7 @@ namespace KernelPanic.Combat
private int fedoraCrashChance = 10; private int fedoraCrashChance = 10;
private int cardsPlayedThisTurn; private int cardsPlayedThisTurn;
private int javaCardsPlayedThisCombat; private int javaCardsPlayedThisCombat;
private int javaCardsDiscountThisTurn;
private int rawhideBonusCharges; private int rawhideBonusCharges;
private int queuedRepeatCharges; private int queuedRepeatCharges;
private int nextTurnCycleBonus; private int nextTurnCycleBonus;
@@ -114,6 +115,7 @@ namespace KernelPanic.Combat
} }
awaitingWaveContinue = false; awaitingWaveContinue = false;
DecayJavaWarmupForNextWave();
StartWave(preservePlayerUptime: true); StartWave(preservePlayerUptime: true);
SetPhase(TurnPhase.Allocate); SetPhase(TurnPhase.Allocate);
} }
@@ -222,6 +224,7 @@ namespace KernelPanic.Combat
} }
fedoraCrashChance = Mathf.Min(90, fedoraCrashChance + 10); fedoraCrashChance = Mathf.Min(90, fedoraCrashChance + 10);
card.MarkFedoraNonCrashBonus();
playerState.DamageMultiplierPercent = runConfig.DistroVersion >= 2 ? 175 : 150; playerState.DamageMultiplierPercent = runConfig.DistroVersion >= 2 ? 175 : 150;
ApplyFedoraGrowth(card, rawhideChargeUsed); ApplyFedoraGrowth(card, rawhideChargeUsed);
} }
@@ -265,9 +268,9 @@ namespace KernelPanic.Combat
public int GetEffectiveCardCost(CardInstance card) public int GetEffectiveCardCost(CardInstance card)
{ {
int cost = GetCardCost(card); int cost = GetCardCost(card);
if (card?.Definition != null && string.Equals(card.Definition.Id, "fedora_dnf_update", StringComparison.OrdinalIgnoreCase)) if (card?.Definition != null && card.Definition.Language == Language.Java)
{ {
cost -= javaCardsPlayedThisCombat; cost -= javaCardsPlayedThisCombat + javaCardsDiscountThisTurn;
} }
return Mathf.Max(0, cost); return Mathf.Max(0, cost);
@@ -310,6 +313,18 @@ namespace KernelPanic.Combat
} }
} }
public void AddJavaCostDiscountThisTurn(int amount)
{
int safeAmount = Mathf.Max(0, amount);
if (safeAmount <= 0)
{
return;
}
javaCardsDiscountThisTurn += safeAmount;
ReportEffectResult($"Java cards cost -{safeAmount} this turn");
}
public int ConsumeQueuedResolutionCount(CardInstance card) public int ConsumeQueuedResolutionCount(CardInstance card)
{ {
if (queuedRepeatCharges <= 0 || card == null) if (queuedRepeatCharges <= 0 || card == null)
@@ -514,6 +529,7 @@ namespace KernelPanic.Combat
fedoraCardsDiscountedThisTurn = 0; fedoraCardsDiscountedThisTurn = 0;
cardsPlayedThisTurn = 0; cardsPlayedThisTurn = 0;
javaCardsPlayedThisCombat = 0; javaCardsPlayedThisCombat = 0;
javaCardsDiscountThisTurn = 0;
rawhideBonusCharges = 0; rawhideBonusCharges = 0;
queuedRepeatCharges = 0; queuedRepeatCharges = 0;
nextTurnCycleBonus = 0; nextTurnCycleBonus = 0;
@@ -582,6 +598,7 @@ namespace KernelPanic.Combat
playerState.Cycles = playerState.MaxCycles; playerState.Cycles = playerState.MaxCycles;
fedoraCardsDiscountedThisTurn = 0; fedoraCardsDiscountedThisTurn = 0;
cardsPlayedThisTurn = 0; cardsPlayedThisTurn = 0;
javaCardsDiscountThisTurn = 0;
if (nextTurnCycleBonus > 0) if (nextTurnCycleBonus > 0)
{ {
playerState.Cycles += nextTurnCycleBonus; playerState.Cycles += nextTurnCycleBonus;
@@ -717,14 +734,14 @@ namespace KernelPanic.Combat
return; return;
} }
int room = playerState.Ram - handController.Cards.Count; int room = handController.RemainingRam;
if (room <= 0) if (room <= 0)
{ {
Log($"{label}: hand full"); Log($"{label}: hand full");
return; return;
} }
int drawCount = Mathf.Min(requestedCount, room); int drawCount = requestedCount;
IReadOnlyList<CardInstance> drawn = deckController.Draw(drawCount); IReadOnlyList<CardInstance> drawn = deckController.Draw(drawCount);
int added = 0; int added = 0;
for (int i = 0; i < drawn.Count; i++) for (int i = 0; i < drawn.Count; i++)
@@ -733,6 +750,10 @@ namespace KernelPanic.Combat
{ {
added++; added++;
} }
else
{
deckController.AddToDrawPile(drawn[i], shuffle: false);
}
} }
if (added == 0 && deckController.AvailableToDrawCount == 0) if (added == 0 && deckController.AvailableToDrawCount == 0)
@@ -751,7 +772,7 @@ namespace KernelPanic.Combat
private void TryApplyUbuntuAptUpdate() private void TryApplyUbuntuAptUpdate()
{ {
if (!IsDistro("ubuntu") || handController == null || playerState == null || handController.Cards.Count >= handController.RamCapacity) if (!IsDistro("ubuntu") || handController == null || playerState == null || handController.RemainingRam <= 0)
{ {
return; return;
} }
@@ -771,6 +792,10 @@ namespace KernelPanic.Combat
{ {
Log($"apt update: staged {GetCardName(card)} from top {lookCount}"); Log($"apt update: staged {GetCardName(card)} from top {lookCount}");
} }
else
{
deckController.AddToDrawPile(card, shuffle: false);
}
} }
private void TryApplyUbuntuEmptyHandRefill() private void TryApplyUbuntuEmptyHandRefill()
@@ -789,6 +814,17 @@ namespace KernelPanic.Combat
return CanApplyFedoraPassiveBonus() || rawhideBonusCharges > 0; return CanApplyFedoraPassiveBonus() || rawhideBonusCharges > 0;
} }
private void DecayJavaWarmupForNextWave()
{
if (javaCardsPlayedThisCombat <= 0)
{
return;
}
javaCardsPlayedThisCombat = Mathf.Max(0, javaCardsPlayedThisCombat - 1);
Log($"Java JIT cooled: discount now -{javaCardsPlayedThisCombat}");
}
private bool CanApplyFedoraPassiveBonus() private bool CanApplyFedoraPassiveBonus()
{ {
if (!IsDistro("fedora") || playerState == null) if (!IsDistro("fedora") || playerState == null)
@@ -817,8 +853,7 @@ namespace KernelPanic.Combat
private static bool IsCrashImmune(CardInstance card) private static bool IsCrashImmune(CardInstance card)
{ {
string id = card?.Definition?.Id; string id = card?.Definition?.Id;
return string.Equals(id, "fedora_cargo_build", StringComparison.OrdinalIgnoreCase) return string.Equals(id, "fedora_selinux", StringComparison.OrdinalIgnoreCase);
|| string.Equals(id, "fedora_selinux", StringComparison.OrdinalIgnoreCase);
} }
private void ApplyVersionState(CombatantState state) private void ApplyVersionState(CombatantState state)
+22 -1
View File
@@ -1,4 +1,5 @@
using System.Collections.Generic; using System.Collections.Generic;
using KernelPanic.Core;
namespace KernelPanic.Combat namespace KernelPanic.Combat
{ {
@@ -16,10 +17,25 @@ namespace KernelPanic.Combat
public int RamCapacity { get; private set; } public int RamCapacity { get; private set; }
public IReadOnlyList<CardInstance> Cards => _cards; public IReadOnlyList<CardInstance> Cards => _cards;
public int UsedRam
{
get
{
int used = 0;
for (int i = 0; i < _cards.Count; i++)
{
used += GetRamCost(_cards[i]);
}
return used;
}
}
public int RemainingRam => System.Math.Max(0, RamCapacity - UsedRam);
public bool CanAdd(CardInstance card) public bool CanAdd(CardInstance card)
{ {
return card != null && _cards.Count < RamCapacity; return card != null && UsedRam + GetRamCost(card) <= RamCapacity;
} }
public bool Add(CardInstance card) public bool Add(CardInstance card)
@@ -42,5 +58,10 @@ namespace KernelPanic.Combat
{ {
_cards.Clear(); _cards.Clear();
} }
public static int GetRamCost(CardInstance card)
{
return card?.Definition != null && card.Definition.Language == Language.Java ? 2 : 1;
}
} }
} }
+2 -2
View File
@@ -13,13 +13,13 @@ namespace KernelPanic.Data
{ {
new(Language.C, "C", "bare metal", ResolutionTrack.Native, "TODO: Native cards hit immediately and reward careful resource timing. Signature mechanic copy pending.", null, Distro("arch", "Arch"), Distro("templeos", "TempleOS")), new(Language.C, "C", "bare metal", ResolutionTrack.Native, "TODO: Native cards hit immediately and reward careful resource timing. Signature mechanic copy pending.", null, Distro("arch", "Arch"), Distro("templeos", "TempleOS")),
new(Language.CPlusPlus, "C++", "template arsenal", ResolutionTrack.Native, "TODO: Native cards hit immediately with complex setup payoffs. Signature mechanic copy pending.", "unlock: upgrade a C card during a run"), new(Language.CPlusPlus, "C++", "template arsenal", ResolutionTrack.Native, "TODO: Native cards hit immediately with complex setup payoffs. Signature mechanic copy pending.", "unlock: upgrade a C card during a run"),
new(Language.Rust, "Rust", "safe systems", ResolutionTrack.Native, "TODO: Rust resolves on the native track with reliable damage and defensive spillover. Signature mechanic copy pending.", null, Distro("arch", "Arch"), Distro("fedora", "Fedora")), new(Language.Rust, "Rust", "safe systems", ResolutionTrack.Native, "Rust resolves on the native track with reliable damage and defensive spillover.", null, Distro("arch", "Arch"), Distro("fedora", "Fedora")),
new(Language.Python, "Python", "queued scripts", ResolutionTrack.InterpreterQueue, "TODO: Python queues flexible effects that resolve at end of turn. Signature mechanic copy pending.", null, Distro("ubuntu", "Ubuntu"), Distro("kali", "Kali"), Distro("mint", "Mint")), new(Language.Python, "Python", "queued scripts", ResolutionTrack.InterpreterQueue, "TODO: Python queues flexible effects that resolve at end of turn. Signature mechanic copy pending.", null, Distro("ubuntu", "Ubuntu"), Distro("kali", "Kali"), Distro("mint", "Mint")),
new(Language.JavaScript, "JavaScript", "runtime chaos", ResolutionTrack.Native, "TODO: JavaScript fires instantly with swingy side effects. Signature mechanic copy pending.", null, Distro("ubuntu", "Ubuntu"), Distro("endeavouros", "EndeavourOS"), Distro("mint", "Mint")), new(Language.JavaScript, "JavaScript", "runtime chaos", ResolutionTrack.Native, "TODO: JavaScript fires instantly with swingy side effects. Signature mechanic copy pending.", null, Distro("ubuntu", "Ubuntu"), Distro("endeavouros", "EndeavourOS"), Distro("mint", "Mint")),
new(Language.TypeScript, "TypeScript", "typed runtime", ResolutionTrack.Native, "TODO: TypeScript stabilizes JavaScript-style tempo with stricter setup. Signature mechanic copy pending.", "unlock: upgrade a JavaScript card during a run"), new(Language.TypeScript, "TypeScript", "typed runtime", ResolutionTrack.Native, "TODO: TypeScript stabilizes JavaScript-style tempo with stricter setup. Signature mechanic copy pending.", "unlock: upgrade a JavaScript card during a run"),
new(Language.Haskell, "Haskell", "lazy proofs", ResolutionTrack.LazyStack, "TODO: Haskell stores delayed work on the lazy stack before resolving in bursts. Signature mechanic copy pending.", null, Distro("gentoo", "Gentoo"), Distro("nixos", "NixOS")), new(Language.Haskell, "Haskell", "lazy proofs", ResolutionTrack.LazyStack, "TODO: Haskell stores delayed work on the lazy stack before resolving in bursts. Signature mechanic copy pending.", null, Distro("gentoo", "Gentoo"), Distro("nixos", "NixOS")),
new(Language.Assembly, "Assembly", "raw opcodes", ResolutionTrack.Native, "TODO: Assembly is immediate, low-level, and high commitment. Signature mechanic copy pending.", null, Distro("gentoo", "Gentoo"), Distro("templeos", "TempleOS")), new(Language.Assembly, "Assembly", "raw opcodes", ResolutionTrack.Native, "TODO: Assembly is immediate, low-level, and high commitment. Signature mechanic copy pending.", null, Distro("gentoo", "Gentoo"), Distro("templeos", "TempleOS")),
new(Language.Java, "Java", "warming vm", ResolutionTrack.Native, "TODO: Java starts expensive and gets cheaper as the combat warms up. Signature mechanic copy pending.", null, Distro("debian", "Debian"), Distro("fedora", "Fedora")), new(Language.Java, "Java", "warming vm", ResolutionTrack.Native, "Java cards use 2 RAM, start expensive, and get cheaper as the combat warms up. JIT cools by 1 after each wave.", null, Distro("debian", "Debian"), Distro("fedora", "Fedora")),
new(Language.Go, "Go", "small services", ResolutionTrack.Native, "TODO: Go uses direct native actions with simple scaling and concurrency hooks. Signature mechanic copy pending.", null, Distro("cachyos", "CachyOS"), Distro("nixos", "NixOS")), new(Language.Go, "Go", "small services", ResolutionTrack.Native, "TODO: Go uses direct native actions with simple scaling and concurrency hooks. Signature mechanic copy pending.", null, Distro("cachyos", "CachyOS"), Distro("nixos", "NixOS")),
new(Language.Ruby, "Ruby", "sharp scripts", ResolutionTrack.InterpreterQueue, "TODO: Ruby queues expressive effects with combo-friendly timing. Signature mechanic copy pending.", null, Distro("kali", "Kali"), Distro("endeavouros", "EndeavourOS")), new(Language.Ruby, "Ruby", "sharp scripts", ResolutionTrack.InterpreterQueue, "TODO: Ruby queues expressive effects with combo-friendly timing. Signature mechanic copy pending.", null, Distro("kali", "Kali"), Distro("endeavouros", "EndeavourOS")),
new(Language.Php, "PHP", "legacy glue", ResolutionTrack.InterpreterQueue, "TODO: PHP queues practical effects that improve when the board is messy. Signature mechanic copy pending.", null, Distro("debian", "Debian"), Distro("cachyos", "CachyOS")), new(Language.Php, "PHP", "legacy glue", ResolutionTrack.InterpreterQueue, "TODO: PHP queues practical effects that improve when the board is messy. Signature mechanic copy pending.", null, Distro("debian", "Debian"), Distro("cachyos", "CachyOS")),
+2 -2
View File
@@ -417,7 +417,7 @@ namespace KernelPanic.UI
playerPanel.Add(MeterBlock("shield", state.Shield, Mathf.Max(1, state.Shield), state.Shield > 0 ? MeterTone.Beneficial : MeterTone.Muted)); playerPanel.Add(MeterBlock("shield", state.Shield, Mathf.Max(1, state.Shield), state.Shield > 0 ? MeterTone.Beneficial : MeterTone.Muted));
playerPanel.Add(CycleBlock(state.Cycles, state.MaxCycles)); playerPanel.Add(CycleBlock(state.Cycles, state.MaxCycles));
Label ram = new($"ram hand cap {combatManager.HandController.Cards.Count}/{combatManager.HandController.RamCapacity}"); Label ram = new($"ram hand cap {combatManager.HandController.UsedRam}/{combatManager.HandController.RamCapacity}");
ram.AddToClassList("ram-note"); ram.AddToClassList("ram-note");
playerPanel.Add(ram); playerPanel.Add(ram);
playerPanel.Add(StatusBlock(state, true)); playerPanel.Add(StatusBlock(state, true));
@@ -507,7 +507,7 @@ namespace KernelPanic.UI
CombatantState state = combatManager.PlayerState; CombatantState state = combatManager.PlayerState;
IReadOnlyList<CardInstance> hand = combatManager.HandController.Cards; IReadOnlyList<CardInstance> hand = combatManager.HandController.Cards;
turnResourceGrid.Add(TurnStat("cycles", $"{state.Cycles}/{state.MaxCycles}")); turnResourceGrid.Add(TurnStat("cycles", $"{state.Cycles}/{state.MaxCycles}"));
turnResourceGrid.Add(TurnStat("hand", $"{hand.Count}/{combatManager.HandController.RamCapacity}")); turnResourceGrid.Add(TurnStat("hand", $"{combatManager.HandController.UsedRam}/{combatManager.HandController.RamCapacity}"));
turnResourceGrid.Add(TurnStat("draw", combatManager.DeckController.DrawPile.Count.ToString())); turnResourceGrid.Add(TurnStat("draw", combatManager.DeckController.DrawPile.Count.ToString()));
turnResourceGrid.Add(TurnStat("discard", combatManager.DeckController.DiscardPile.Count.ToString())); turnResourceGrid.Add(TurnStat("discard", combatManager.DeckController.DiscardPile.Count.ToString()));
turnResourceGrid.Add(TurnStat("exhaust", combatManager.DeckController.ExhaustPile.Count.ToString())); turnResourceGrid.Add(TurnStat("exhaust", combatManager.DeckController.ExhaustPile.Count.ToString()));