make small changes to design. Implement crits.
This commit is contained in:
+67
-64
@@ -11,25 +11,12 @@
|
|||||||
</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/Cards/Languages/Java/JavaNewObject.asset" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/Assets/Data/Cards/Languages/Java/JavaPublicStaticMain.asset" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/Assets/Data/Cards/Languages/Java/JavaSystemOutPrintln.asset" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/Assets/Data/Cards/Languages/JavaDeck.asset" 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/Data/Cards/CardDatabase.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Data/Cards/CardDatabase.asset" 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/Cards/Fedora/BorrowChecker.asset" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Data/Cards/Fedora/BorrowChecker.asset" 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/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/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/Combat/DamagePipeline.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Combat/DamagePipeline.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/Core/GameEvents.cs" beforeDir="false" afterPath="$PROJECT_DIR$/Assets/Scripts/Core/GameEvents.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" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
@@ -68,7 +55,10 @@
|
|||||||
<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/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/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/Languages/Rust/RsBorrow.asset" root0="FORCE_HIGHLIGHTING" />
|
||||||
|
<setting file="file://$PROJECT_DIR$/Assets/Data/Cards/Languages/Rust/RsUnwrap.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/Cards/Ubuntu/UbuntuProTrial.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" />
|
||||||
<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" />
|
||||||
@@ -76,6 +66,8 @@
|
|||||||
<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" />
|
||||||
|
<setting file="file://$PROJECT_DIR$/Assets/Scenes/FightScene.unity" root0="FORCE_HIGHLIGHTING" />
|
||||||
|
<setting file="file://$PROJECT_DIR$/Assets/Scenes/GamblingScene.unity" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Assets/Scripts/Data/LanguageDeckDatabase.cs" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Assets/Scripts/Data/LanguageDeckDatabase.cs" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Assets/Scripts/UI.meta" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Assets/Scripts/UI.meta" root0="FORCE_HIGHLIGHTING" />
|
||||||
<setting file="file://$PROJECT_DIR$/Assets/UI/MainMenuPanelSettings.asset" root0="FORCE_HIGHLIGHTING" />
|
<setting file="file://$PROJECT_DIR$/Assets/UI/MainMenuPanelSettings.asset" root0="FORCE_HIGHLIGHTING" />
|
||||||
@@ -91,23 +83,23 @@
|
|||||||
<component name="MetaFilesCheckinStateConfiguration" checkMetaFiles="true" />
|
<component name="MetaFilesCheckinStateConfiguration" checkMetaFiles="true" />
|
||||||
<component name="NextEditCompletionFeaturesState">
|
<component name="NextEditCompletionFeaturesState">
|
||||||
<decayedCancelled>
|
<decayedCancelled>
|
||||||
<entry key="MS100" value="1.7745080781518747" />
|
<entry key="MS100" value="1.000000000000699" />
|
||||||
<entry key="MS500" value="5.494883000294699" />
|
<entry key="MS500" value="1.0163073776265223" />
|
||||||
<entry key="S2" value="13.540161770151046" />
|
<entry key="S2" value="5.108221812019007" />
|
||||||
<entry key="S5" value="23.840938265908584" />
|
<entry key="S5" value="21.770600885518434" />
|
||||||
<entry key="S10" value="37.73345622347476" />
|
<entry key="S10" value="47.09517013998605" />
|
||||||
<entry key="S30" value="84.57208484998908" />
|
<entry key="S30" value="93.9785706567626" />
|
||||||
<entry key="S60" value="143.95189989985906" />
|
<entry key="S60" value="119.48644415542124" />
|
||||||
<entry key="M2" value="220.15898543823553" />
|
<entry key="M2" value="160.68491265036215" />
|
||||||
<entry key="M5" value="315.3671327614578" />
|
<entry key="M5" value="278.40590534440275" />
|
||||||
<entry key="M10" value="385.2774636863717" />
|
<entry key="M10" value="395.77142962415076" />
|
||||||
<entry key="M15" value="435.0925737567707" />
|
<entry key="M15" value="485.9382710538006" />
|
||||||
<entry key="M30" value="551.959520858503" />
|
<entry key="M30" value="720.5335135398915" />
|
||||||
<entry key="H1" value="715.8254467553472" />
|
<entry key="H1" value="1054.9046690258854" />
|
||||||
<entry key="H2" value="889.3981211254871" />
|
<entry key="H2" value="1414.4969635593438" />
|
||||||
<entry key="H4" value="1053.976456033934" />
|
<entry key="H4" value="1731.0633909446262" />
|
||||||
<entry key="D1" value="2453.031132891062" />
|
<entry key="D1" value="3286.6219915604" />
|
||||||
<entry key="W1" value="3757.0476380579075" />
|
<entry key="W1" value="4660.98507014222" />
|
||||||
</decayedCancelled>
|
</decayedCancelled>
|
||||||
<decayedSelected>
|
<decayedSelected>
|
||||||
<entry key="MS100" value="0.0" />
|
<entry key="MS100" value="0.0" />
|
||||||
@@ -117,35 +109,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="4.9047462196789525E-230" />
|
<entry key="M2" value="2.5063439983015887E-240" />
|
||||||
<entry key="M5" value="1.889063759565985E-92" />
|
<entry key="M5" value="1.4441631903175532E-96" />
|
||||||
<entry key="M10" value="1.3744321589536667E-46" />
|
<entry key="M10" value="1.2017334106687881E-48" />
|
||||||
<entry key="M15" value="2.6632720957412003E-31" />
|
<entry key="M15" value="1.130330440943858E-32" />
|
||||||
<entry key="M30" value="5.160691631924263E-16" />
|
<entry key="M30" value="1.0631703388171175E-16" />
|
||||||
<entry key="H1" value="2.2739485517900192E-8" />
|
<entry key="H1" value="1.0321150378964974E-8" />
|
||||||
<entry key="H2" value="1.589073656746164E-4" />
|
<entry key="H2" value="1.0705766421479234E-4" />
|
||||||
<entry key="H4" value="0.01723225556677517" />
|
<entry key="H4" value="0.014144219737749934" />
|
||||||
<entry key="D1" value="1.511748964440463" />
|
<entry key="D1" value="1.4628029396241715" />
|
||||||
<entry key="W1" value="3.476159578917258" />
|
<entry key="W1" value="3.4598536273655087" />
|
||||||
</decayedSelected>
|
</decayedSelected>
|
||||||
<decayedShown>
|
<decayedShown>
|
||||||
<entry key="MS100" value="1.7184635520820462" />
|
<entry key="MS100" value="0.9526379980446108" />
|
||||||
<entry key="MS500" value="5.451310134754918" />
|
<entry key="MS500" value="1.0065360445565774" />
|
||||||
<entry key="S2" value="13.508716422466016" />
|
<entry key="S2" value="5.098242978856544" />
|
||||||
<entry key="S5" value="23.818087310576672" />
|
<entry key="S5" value="21.754020235151167" />
|
||||||
<entry key="S10" value="37.7154028872074" />
|
<entry key="S10" value="47.07706009383575" />
|
||||||
<entry key="S30" value="84.55887260233759" />
|
<entry key="S30" value="93.9663762674251" />
|
||||||
<entry key="S60" value="143.94070760442918" />
|
<entry key="S60" value="119.47863856671924" />
|
||||||
<entry key="M2" value="220.1504902812646" />
|
<entry key="M2" value="160.67946494648172" />
|
||||||
<entry key="M5" value="315.3623307934439" />
|
<entry key="M5" value="278.4016956102392" />
|
||||||
<entry key="M10" value="385.27455591371523" />
|
<entry key="M10" value="395.76819463253577" />
|
||||||
<entry key="M15" value="435.0903859691819" />
|
<entry key="M15" value="485.9354965404165" />
|
||||||
<entry key="M30" value="551.9581184345019" />
|
<entry key="M30" value="720.531339531474" />
|
||||||
<entry key="H1" value="715.8245138452602" />
|
<entry key="H1" value="1054.9030513551575" />
|
||||||
<entry key="H2" value="889.3976854411949" />
|
<entry key="H2" value="1414.4959842118083" />
|
||||||
<entry key="H4" value="1053.9933170489687" />
|
<entry key="H4" value="1731.0768609975287" />
|
||||||
<entry key="D1" value="2454.542608558042" />
|
<entry key="D1" value="3288.0844643497253" />
|
||||||
<entry key="W1" value="3760.5237264671973" />
|
<entry key="W1" value="4664.444843440584" />
|
||||||
</decayedShown>
|
</decayedShown>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectColorInfo">{
|
<component name="ProjectColorInfo">{
|
||||||
@@ -175,7 +167,7 @@
|
|||||||
"node.js.selected.package.eslint": "(autodetect)",
|
"node.js.selected.package.eslint": "(autodetect)",
|
||||||
"node.js.selected.package.tslint": "(autodetect)",
|
"node.js.selected.package.tslint": "(autodetect)",
|
||||||
"nodejs_package_manager_path": "npm",
|
"nodejs_package_manager_path": "npm",
|
||||||
"settings.editor.selected.configurable": "ml.llm.LLMThirdPartyAiProvidersConfigurable",
|
"settings.editor.selected.configurable": "ml.llm.AcpAgentsConfigurable",
|
||||||
"vue.rearranger.settings.migration": "true"
|
"vue.rearranger.settings.migration": "true"
|
||||||
}
|
}
|
||||||
}</component>
|
}</component>
|
||||||
@@ -234,7 +226,9 @@
|
|||||||
<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="22472000" />
|
<workItem from="1783410502976" duration="23430000" />
|
||||||
|
<workItem from="1783507489679" duration="5909000" />
|
||||||
|
<workItem from="1783519887449" duration="4333000" />
|
||||||
</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" />
|
||||||
@@ -412,7 +406,15 @@
|
|||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1783500547647</updated>
|
<updated>1783500547647</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="23" />
|
<task id="LOCAL-00023" summary="Implement Java and Rust cards alongside some smaller changes">
|
||||||
|
<option name="closed" value="true" />
|
||||||
|
<created>1783503035031</created>
|
||||||
|
<option name="number" value="00023" />
|
||||||
|
<option name="presentableId" value="LOCAL-00023" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1783503035031</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="24" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
@@ -449,7 +451,8 @@
|
|||||||
<MESSAGE value="update some strings" />
|
<MESSAGE value="update some strings" />
|
||||||
<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" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="changed most TODOs to TODONEs" />
|
<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" />
|
||||||
</component>
|
</component>
|
||||||
<component name="XDebuggerManager">
|
<component name="XDebuggerManager">
|
||||||
<breakpoint-manager>
|
<breakpoint-manager>
|
||||||
|
|||||||
@@ -1034,13 +1034,19 @@
|
|||||||
border-right-width: 10px;
|
border-right-width: 10px;
|
||||||
border-top-width: 10px;
|
border-top-width: 10px;
|
||||||
border-bottom-width: 10px;
|
border-bottom-width: 10px;
|
||||||
border-color: var(--kp-danger);
|
border-color: transparent;
|
||||||
transition-property: opacity;
|
transition-property: opacity;
|
||||||
transition-duration: 120ms;
|
transition-duration: 120ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.damage-vignette-on {
|
.damage-vignette-on {
|
||||||
opacity: 0.62;
|
opacity: 0.62;
|
||||||
|
border-color: var(--kp-danger);
|
||||||
|
}
|
||||||
|
|
||||||
|
.damage-vignette-crit {
|
||||||
|
opacity: 0.82;
|
||||||
|
border-color: var(--kp-kill);
|
||||||
}
|
}
|
||||||
|
|
||||||
.float-number {
|
.float-number {
|
||||||
@@ -1084,6 +1090,40 @@
|
|||||||
transition-duration: 0ms;
|
transition-duration: 0ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.impact-marker {
|
||||||
|
position: absolute;
|
||||||
|
min-width: 48px;
|
||||||
|
height: 18px;
|
||||||
|
padding-left: 4px;
|
||||||
|
padding-right: 4px;
|
||||||
|
-unity-text-align: middle-center;
|
||||||
|
-unity-font-style: bold;
|
||||||
|
font-size: 10px;
|
||||||
|
opacity: 1;
|
||||||
|
background-color: var(--kp-bg-deep);
|
||||||
|
border-left-width: 1px;
|
||||||
|
border-right-width: 1px;
|
||||||
|
border-top-width: 1px;
|
||||||
|
border-bottom-width: 1px;
|
||||||
|
transition-property: left, opacity;
|
||||||
|
transition-duration: 320ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.impact-marker-hit {
|
||||||
|
color: var(--kp-damage);
|
||||||
|
border-color: var(--kp-damage);
|
||||||
|
}
|
||||||
|
|
||||||
|
.impact-marker-crit {
|
||||||
|
color: var(--kp-kill);
|
||||||
|
border-color: var(--kp-kill);
|
||||||
|
}
|
||||||
|
|
||||||
|
.impact-marker-clang {
|
||||||
|
color: var(--kp-beneficial);
|
||||||
|
border-color: var(--kp-beneficial);
|
||||||
|
}
|
||||||
|
|
||||||
.feedback-card-ghost {
|
.feedback-card-ghost {
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
transition-property: left, top, opacity;
|
transition-property: left, top, opacity;
|
||||||
@@ -1110,15 +1150,28 @@
|
|||||||
.feedback-hit {
|
.feedback-hit {
|
||||||
background-color: var(--kp-action-hover);
|
background-color: var(--kp-action-hover);
|
||||||
border-color: var(--kp-damage);
|
border-color: var(--kp-damage);
|
||||||
|
translate: 3px 0;
|
||||||
scale: 1.025 0.98;
|
scale: 1.025 0.98;
|
||||||
transition-property: scale, background-color, border-color;
|
transition-property: scale, translate, background-color, border-color;
|
||||||
transition-duration: 90ms;
|
transition-duration: 90ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.feedback-crit {
|
||||||
|
background-color: #2d0707;
|
||||||
|
border-color: var(--kp-kill);
|
||||||
|
translate: 8px 0;
|
||||||
|
scale: 1.08 0.9;
|
||||||
|
transition-property: scale, translate, background-color, border-color;
|
||||||
|
transition-duration: 170ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feedback-clang,
|
||||||
.feedback-block {
|
.feedback-block {
|
||||||
|
background-color: var(--kp-bg-deep);
|
||||||
border-color: var(--kp-beneficial);
|
border-color: var(--kp-beneficial);
|
||||||
transition-property: border-color;
|
scale: 1.02 1.02;
|
||||||
transition-duration: 90ms;
|
transition-property: scale, background-color, border-color;
|
||||||
|
transition-duration: 80ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.feedback-status {
|
.feedback-status {
|
||||||
@@ -1130,23 +1183,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.feedback-killed {
|
.feedback-killed {
|
||||||
opacity: 0.5;
|
opacity: 0.28;
|
||||||
scale: 0.95 0.95;
|
scale: 0.76 0.28;
|
||||||
|
background-color: #240606;
|
||||||
border-color: var(--kp-kill);
|
border-color: var(--kp-kill);
|
||||||
transition-property: opacity, scale, border-color;
|
transition-property: opacity, scale, background-color, border-color;
|
||||||
transition-duration: 180ms;
|
transition-duration: 220ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.death-ghost {
|
.death-ghost {
|
||||||
background-color: var(--kp-panel-raised);
|
background-color: #240606;
|
||||||
border-left-width: 2px;
|
border-left-width: 2px;
|
||||||
border-right-width: 1px;
|
border-right-width: 1px;
|
||||||
border-top-width: 1px;
|
border-top-width: 1px;
|
||||||
border-bottom-width: 1px;
|
border-bottom-width: 1px;
|
||||||
border-color: var(--kp-kill);
|
border-color: var(--kp-kill);
|
||||||
opacity: 0.72;
|
opacity: 0.74;
|
||||||
transition-property: opacity, scale;
|
transition-property: opacity, scale;
|
||||||
transition-duration: 300ms;
|
transition-duration: 220ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.enemy-anticipating {
|
||||||
|
border-color: var(--kp-accent);
|
||||||
|
translate: -8px 0;
|
||||||
|
scale: 0.94 1.06;
|
||||||
|
background-color: var(--kp-action-hover);
|
||||||
|
transition-property: translate, scale, border-color, background-color;
|
||||||
|
transition-duration: 170ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.enemy-acting {
|
.enemy-acting {
|
||||||
@@ -1156,6 +1219,33 @@
|
|||||||
transition-duration: 120ms;
|
transition-duration: 120ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.status-state-segfault,
|
||||||
|
.status-state-deadlock {
|
||||||
|
opacity: 0.68;
|
||||||
|
border-color: var(--kp-lang-haskell);
|
||||||
|
transition-property: opacity, border-color;
|
||||||
|
transition-duration: 300ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-state-race {
|
||||||
|
border-color: var(--kp-warning);
|
||||||
|
translate: 1px 0;
|
||||||
|
transition-property: translate, border-color;
|
||||||
|
transition-duration: 120ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-state-deprecated,
|
||||||
|
.status-state-dependency-error {
|
||||||
|
border-color: var(--kp-text-dim);
|
||||||
|
opacity: 0.76;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-state-upgrading {
|
||||||
|
border-color: var(--kp-beneficial);
|
||||||
|
border-right-color: var(--kp-beneficial);
|
||||||
|
border-right-width: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
.phase-pulse {
|
.phase-pulse {
|
||||||
background-color: var(--kp-warning);
|
background-color: var(--kp-warning);
|
||||||
transition-property: background-color;
|
transition-property: background-color;
|
||||||
@@ -1197,10 +1287,14 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.reduced-motion .float-number,
|
.reduced-motion .float-number,
|
||||||
|
.reduced-motion .impact-marker,
|
||||||
.reduced-motion .feedback-card-ghost,
|
.reduced-motion .feedback-card-ghost,
|
||||||
.reduced-motion .damage-vignette,
|
.reduced-motion .damage-vignette,
|
||||||
.reduced-motion .feedback-hit,
|
.reduced-motion .feedback-hit,
|
||||||
|
.reduced-motion .feedback-crit,
|
||||||
|
.reduced-motion .feedback-clang,
|
||||||
.reduced-motion .feedback-killed,
|
.reduced-motion .feedback-killed,
|
||||||
|
.reduced-motion .enemy-anticipating,
|
||||||
.reduced-motion .enemy-acting,
|
.reduced-motion .enemy-acting,
|
||||||
.reduced-motion .phase-pulse,
|
.reduced-motion .phase-pulse,
|
||||||
.reduced-motion .cycles-spent-beat,
|
.reduced-motion .cycles-spent-beat,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace KernelPanic.Combat
|
|||||||
private readonly bool _canCrit;
|
private readonly bool _canCrit;
|
||||||
private readonly bool _allEnemies;
|
private readonly bool _allEnemies;
|
||||||
|
|
||||||
public DealDamageEffect(int minAmount, int maxAmount, Language language, bool trueDamage = false, bool canCrit = false, bool allEnemies = false)
|
public DealDamageEffect(int minAmount, int maxAmount, Language language, bool trueDamage = false, bool canCrit = true, bool allEnemies = false)
|
||||||
{
|
{
|
||||||
_minAmount = minAmount;
|
_minAmount = minAmount;
|
||||||
_maxAmount = maxAmount;
|
_maxAmount = maxAmount;
|
||||||
@@ -78,6 +78,12 @@ namespace KernelPanic.Combat
|
|||||||
public void Execute(CombatContext context)
|
public void Execute(CombatContext context)
|
||||||
{
|
{
|
||||||
int amount = UpgradeMath.ScaleShield(UpgradeMath.ApplySourceFlatBonus(_amount, context), context.Card);
|
int amount = UpgradeMath.ScaleShield(UpgradeMath.ApplySourceFlatBonus(_amount, context), context.Card);
|
||||||
|
if (!context.CombatManager.CanPlayerReceiveCardShield(context.Card))
|
||||||
|
{
|
||||||
|
context.CombatManager.ReportEffectResult($"shield blocked: {amount}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
context.Source.Shield += amount;
|
context.Source.Shield += amount;
|
||||||
context.CombatManager.ReportEffectResult($"gained {amount} shield");
|
context.CombatManager.ReportEffectResult($"gained {amount} shield");
|
||||||
}
|
}
|
||||||
@@ -98,6 +104,12 @@ namespace KernelPanic.Combat
|
|||||||
{
|
{
|
||||||
int amount = _baseAmount + (context.Card != null && context.Card.WasFirstCardThisTurn ? _firstCardBonus : 0);
|
int amount = _baseAmount + (context.Card != null && context.Card.WasFirstCardThisTurn ? _firstCardBonus : 0);
|
||||||
amount = UpgradeMath.ScaleShield(UpgradeMath.ApplySourceFlatBonus(amount, context), context.Card);
|
amount = UpgradeMath.ScaleShield(UpgradeMath.ApplySourceFlatBonus(amount, context), context.Card);
|
||||||
|
if (!context.CombatManager.CanPlayerReceiveCardShield(context.Card))
|
||||||
|
{
|
||||||
|
context.CombatManager.ReportEffectResult($"shield blocked: {amount}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
context.Source.Shield += amount;
|
context.Source.Shield += amount;
|
||||||
context.CombatManager.ReportEffectResult($"gained {amount} shield");
|
context.CombatManager.ReportEffectResult($"gained {amount} shield");
|
||||||
}
|
}
|
||||||
@@ -129,7 +141,7 @@ namespace KernelPanic.Combat
|
|||||||
int roll = RandomRoll.RollRange(1, 100, new RollContext(context.Source));
|
int roll = RandomRoll.RollRange(1, 100, new RollContext(context.Source));
|
||||||
int damageAmount = UpgradeMath.ScaleAmount(UpgradeMath.ApplySourceFlatBonus(_damageAmount, context), context.Card);
|
int damageAmount = UpgradeMath.ScaleAmount(UpgradeMath.ApplySourceFlatBonus(_damageAmount, context), context.Card);
|
||||||
int amount = roll <= _successPercent ? damageAmount : 0;
|
int amount = roll <= _successPercent ? damageAmount : 0;
|
||||||
context.DamagePipeline.DealDamage(new DamageRequest(context.Source, target, amount, _language, false, false));
|
context.DamagePipeline.DealDamage(new DamageRequest(context.Source, target, amount, _language, false, true));
|
||||||
context.CombatManager.ReportEffectResult(amount == 0 ? "typeof -> NaN (0)" : $"typeof -> {amount}");
|
context.CombatManager.ReportEffectResult(amount == 0 ? "typeof -> NaN (0)" : $"typeof -> {amount}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,6 +188,13 @@ namespace KernelPanic.Combat
|
|||||||
{
|
{
|
||||||
if (_targetSelf)
|
if (_targetSelf)
|
||||||
{
|
{
|
||||||
|
if (StatusEffectController.GetDescriptor(_statusType).IsBeneficial
|
||||||
|
&& !context.CombatManager.CanPlayerReceiveCardBuff(context.Card))
|
||||||
|
{
|
||||||
|
context.CombatManager.ReportEffectResult($"{_statusType} blocked");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
context.StatusEffects.Apply(context.Source, _statusType, UpgradeMath.ScaleAmount(UpgradeMath.ApplySourceFlatBonus(_stacks, context), context.Card), _duration, context.Source, _skipNextTick);
|
context.StatusEffects.Apply(context.Source, _statusType, UpgradeMath.ScaleAmount(UpgradeMath.ApplySourceFlatBonus(_stacks, context), context.Card), _duration, context.Source, _skipNextTick);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -473,10 +492,16 @@ namespace KernelPanic.Combat
|
|||||||
|
|
||||||
int amount = UpgradeMath.ScaleAmount(UpgradeMath.ApplySourceFlatBonus(_amount, context), context.Card);
|
int amount = UpgradeMath.ScaleAmount(UpgradeMath.ApplySourceFlatBonus(_amount, context), context.Card);
|
||||||
int survivable = target.CurrentUptime + target.Shield;
|
int survivable = target.CurrentUptime + target.Shield;
|
||||||
context.DamagePipeline.DealDamage(new DamageRequest(context.Source, target, amount, _language, false, false));
|
DamageResult result = context.DamagePipeline.DealDamage(new DamageRequest(context.Source, target, amount, _language, false, true));
|
||||||
int overkill = UnityEngine.Mathf.Max(0, amount - survivable);
|
int overkill = UnityEngine.Mathf.Max(0, result.IncomingAmount - survivable);
|
||||||
if (overkill > 0)
|
if (overkill > 0)
|
||||||
{
|
{
|
||||||
|
if (!context.CombatManager.CanPlayerReceiveCardShield(context.Card))
|
||||||
|
{
|
||||||
|
context.CombatManager.ReportEffectResult($"overkill shield blocked: {overkill}");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
context.Source.Shield += overkill;
|
context.Source.Shield += overkill;
|
||||||
context.CombatManager.ReportEffectResult($"overkill -> {overkill} shield");
|
context.CombatManager.ReportEffectResult($"overkill -> {overkill} shield");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -895,6 +895,48 @@ namespace KernelPanic.Combat
|
|||||||
return string.Equals(runConfig?.Distro?.Id, id, StringComparison.OrdinalIgnoreCase);
|
return string.Equals(runConfig?.Distro?.Id, id, StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool CanPlayerReceiveCardShield(CardInstance card)
|
||||||
|
{
|
||||||
|
return CanPlayerReceiveCardBuff(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanPlayerReceiveCardHeal(CardInstance card)
|
||||||
|
{
|
||||||
|
return CanPlayerReceiveCardBuff(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanPlayerReceiveCardBuff(CardInstance card)
|
||||||
|
{
|
||||||
|
return !IsDistro("mint") || IsCurrentDistroExclusiveCard(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsCurrentDistroExclusiveCard(CardInstance card)
|
||||||
|
{
|
||||||
|
CardDefinition definition = card?.Definition;
|
||||||
|
IReadOnlyList<CardDefinition> exclusiveCards = runConfig?.Distro?.ExclusiveCards;
|
||||||
|
if (definition == null || exclusiveCards == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < exclusiveCards.Count; i++)
|
||||||
|
{
|
||||||
|
CardDefinition exclusive = exclusiveCards[i];
|
||||||
|
if (exclusive == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ReferenceEquals(exclusive, definition)
|
||||||
|
|| string.Equals(exclusive.Id, definition.Id, StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private CombatContext BuildContext(CardInstance card, IReadOnlyList<CombatantState> targets)
|
private CombatContext BuildContext(CardInstance card, IReadOnlyList<CombatantState> targets)
|
||||||
{
|
{
|
||||||
return new CombatContext(card, playerState, targets, this, damagePipeline, statusEffects, deckController, handController, enemies);
|
return new CombatContext(card, playerState, targets, this, damagePipeline, statusEffects, deckController, handController, enemies);
|
||||||
@@ -1151,7 +1193,7 @@ namespace KernelPanic.Combat
|
|||||||
List<CombatantState> targets = LivingEnemyStates();
|
List<CombatantState> targets = LivingEnemyStates();
|
||||||
for (int i = 0; i < targets.Count; i++)
|
for (int i = 0; i < targets.Count; i++)
|
||||||
{
|
{
|
||||||
damagePipeline.DealDamage(new DamageRequest(playerState, targets[i], amount, language, false, false));
|
damagePipeline.DealDamage(new DamageRequest(playerState, targets[i], amount, language, false, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
Log($"{label}: dealt {amount} to all enemies");
|
Log($"{label}: dealt {amount} to all enemies");
|
||||||
|
|||||||
@@ -31,14 +31,24 @@ namespace KernelPanic.Combat
|
|||||||
|
|
||||||
public readonly struct DamageResult
|
public readonly struct DamageResult
|
||||||
{
|
{
|
||||||
public DamageResult(int finalAmount, bool targetDefeated)
|
public DamageResult(int finalAmount, bool targetDefeated, bool wasCritical = false, int absorbedAmount = 0, int shieldDamage = 0, int uptimeDamage = 0, int incomingAmount = 0)
|
||||||
{
|
{
|
||||||
FinalAmount = finalAmount;
|
FinalAmount = finalAmount;
|
||||||
TargetDefeated = targetDefeated;
|
TargetDefeated = targetDefeated;
|
||||||
|
WasCritical = wasCritical;
|
||||||
|
AbsorbedAmount = absorbedAmount;
|
||||||
|
ShieldDamage = shieldDamage;
|
||||||
|
UptimeDamage = uptimeDamage;
|
||||||
|
IncomingAmount = incomingAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int FinalAmount { get; }
|
public int FinalAmount { get; }
|
||||||
public bool TargetDefeated { get; }
|
public bool TargetDefeated { get; }
|
||||||
|
public bool WasCritical { get; }
|
||||||
|
public int AbsorbedAmount { get; }
|
||||||
|
public int ShieldDamage { get; }
|
||||||
|
public int UptimeDamage { get; }
|
||||||
|
public int IncomingAmount { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -55,11 +65,11 @@ namespace KernelPanic.Combat
|
|||||||
|
|
||||||
int amount = Mathf.Max(0, request.Amount);
|
int amount = Mathf.Max(0, request.Amount);
|
||||||
amount = ApplyMultipliers(amount, request);
|
amount = ApplyMultipliers(amount, request);
|
||||||
amount = ApplyCrit(amount, request);
|
amount = ApplyCrit(amount, request, out bool wasCritical);
|
||||||
amount = ApplyResistancesAndWeaknesses(amount, request);
|
amount = ApplyResistancesAndWeaknesses(amount, request);
|
||||||
|
|
||||||
int finalAmount = ApplyShieldAndUptime(amount, request);
|
int finalAmount = ApplyShieldAndUptime(amount, request, out int absorbedAmount, out int shieldDamage, out int uptimeDamage);
|
||||||
GameEvents.RaiseDamageDealt(new DamageDealtEvent(request.Source, request.Target, finalAmount, request.Language));
|
GameEvents.RaiseDamageDealt(new DamageDealtEvent(request.Source, request.Target, finalAmount, request.Language, amount, absorbedAmount, wasCritical, shieldDamage, uptimeDamage));
|
||||||
|
|
||||||
bool defeated = false;
|
bool defeated = false;
|
||||||
if (request.Target.CurrentUptime <= 0 && !request.Target.IsDefeated)
|
if (request.Target.CurrentUptime <= 0 && !request.Target.IsDefeated)
|
||||||
@@ -69,7 +79,7 @@ namespace KernelPanic.Combat
|
|||||||
GameEvents.RaiseCombatantDefeated(new CombatantDefeatedEvent(request.Target));
|
GameEvents.RaiseCombatantDefeated(new CombatantDefeatedEvent(request.Target));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DamageResult(finalAmount, defeated);
|
return new DamageResult(finalAmount, defeated, wasCritical, absorbedAmount, shieldDamage, uptimeDamage, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int ApplyMultipliers(int amount, DamageRequest request)
|
private static int ApplyMultipliers(int amount, DamageRequest request)
|
||||||
@@ -85,15 +95,16 @@ namespace KernelPanic.Combat
|
|||||||
return Mathf.RoundToInt(amount * (multiplier / 100f));
|
return Mathf.RoundToInt(amount * (multiplier / 100f));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int ApplyCrit(int amount, DamageRequest request)
|
private static int ApplyCrit(int amount, DamageRequest request, out bool wasCritical)
|
||||||
{
|
{
|
||||||
if (request.Source != null && request.Source.forceMaxRolls)
|
wasCritical = false;
|
||||||
|
if (!request.CanCrit || amount <= 0 || request.Source != null && request.Source.forceMaxRolls)
|
||||||
{
|
{
|
||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add crit calculation and crit modifiers.
|
wasCritical = RandomRoll.RollRange(1, 100, new RollContext(request.Source)) <= 25;
|
||||||
return amount;
|
return wasCritical ? Mathf.CeilToInt(amount * 1.5f) : amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int ApplyResistancesAndWeaknesses(int amount, DamageRequest request)
|
private static int ApplyResistancesAndWeaknesses(int amount, DamageRequest request)
|
||||||
@@ -104,11 +115,11 @@ namespace KernelPanic.Combat
|
|||||||
return amount;
|
return amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int ApplyShieldAndUptime(int amount, DamageRequest request)
|
private static int ApplyShieldAndUptime(int amount, DamageRequest request, out int absorbedAmount, out int shieldDamage, out int uptimeDamage)
|
||||||
{
|
{
|
||||||
CombatantState target = request.Target;
|
CombatantState target = request.Target;
|
||||||
int remaining = amount;
|
int remaining = amount;
|
||||||
int shieldDamage = 0;
|
shieldDamage = 0;
|
||||||
|
|
||||||
if (!request.TrueDamage && target.Shield > 0)
|
if (!request.TrueDamage && target.Shield > 0)
|
||||||
{
|
{
|
||||||
@@ -117,8 +128,9 @@ namespace KernelPanic.Combat
|
|||||||
remaining -= shieldDamage;
|
remaining -= shieldDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
int uptimeDamage = Mathf.Min(target.CurrentUptime, remaining);
|
uptimeDamage = Mathf.Min(target.CurrentUptime, remaining);
|
||||||
target.CurrentUptime = Mathf.Max(0, target.CurrentUptime - uptimeDamage);
|
target.CurrentUptime = Mathf.Max(0, target.CurrentUptime - uptimeDamage);
|
||||||
|
absorbedAmount = Mathf.Max(0, amount - shieldDamage - uptimeDamage);
|
||||||
return shieldDamage + uptimeDamage;
|
return shieldDamage + uptimeDamage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -157,17 +157,39 @@ namespace KernelPanic.Core
|
|||||||
public readonly struct DamageDealtEvent
|
public readonly struct DamageDealtEvent
|
||||||
{
|
{
|
||||||
public DamageDealtEvent(CombatantState source, CombatantState target, int amount, Language language)
|
public DamageDealtEvent(CombatantState source, CombatantState target, int amount, Language language)
|
||||||
|
: this(source, target, amount, language, amount, 0, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DamageDealtEvent(CombatantState source, CombatantState target, int amount, Language language, int incomingAmount, int absorbedAmount, bool wasCritical)
|
||||||
|
: this(source, target, amount, language, incomingAmount, absorbedAmount, wasCritical, 0, amount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public DamageDealtEvent(CombatantState source, CombatantState target, int amount, Language language, int incomingAmount, int absorbedAmount, bool wasCritical, int shieldDamage, int uptimeDamage)
|
||||||
{
|
{
|
||||||
Source = source;
|
Source = source;
|
||||||
Target = target;
|
Target = target;
|
||||||
Amount = amount;
|
Amount = amount;
|
||||||
Language = language;
|
Language = language;
|
||||||
|
IncomingAmount = incomingAmount;
|
||||||
|
AbsorbedAmount = absorbedAmount;
|
||||||
|
WasCritical = wasCritical;
|
||||||
|
ShieldDamage = shieldDamage;
|
||||||
|
UptimeDamage = uptimeDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public CombatantState Source { get; }
|
public CombatantState Source { get; }
|
||||||
public CombatantState Target { get; }
|
public CombatantState Target { get; }
|
||||||
public int Amount { get; }
|
public int Amount { get; }
|
||||||
public Language Language { get; }
|
public Language Language { get; }
|
||||||
|
public int IncomingAmount { get; }
|
||||||
|
public int AbsorbedAmount { get; }
|
||||||
|
public bool WasCritical { get; }
|
||||||
|
public int ShieldDamage { get; }
|
||||||
|
public int UptimeDamage { get; }
|
||||||
|
public bool WasFullyBlocked => IncomingAmount > 0 && UptimeDamage <= 0;
|
||||||
|
public bool WasMitigated => ShieldDamage > 0 || AbsorbedAmount > 0 || WasFullyBlocked;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -60,7 +60,11 @@ namespace KernelPanic.UI
|
|||||||
private readonly Dictionary<CardInstance, VisualElement> stackChipElements = new();
|
private readonly Dictionary<CardInstance, VisualElement> stackChipElements = new();
|
||||||
private readonly Dictionary<CombatantState, int> previousUptime = new();
|
private readonly Dictionary<CombatantState, int> previousUptime = new();
|
||||||
private readonly Dictionary<CombatantState, int> previousShield = new();
|
private readonly Dictionary<CombatantState, int> previousShield = new();
|
||||||
|
private readonly Dictionary<VisualElement, int> feedbackBeatVersions = new();
|
||||||
private readonly HashSet<CardInstance> knownHandCards = new();
|
private readonly HashSet<CardInstance> knownHandCards = new();
|
||||||
|
private int queueCascadeIndex;
|
||||||
|
private int feedbackCascadeIndex;
|
||||||
|
private int feedbackBeatVersion;
|
||||||
|
|
||||||
private void Awake()
|
private void Awake()
|
||||||
{
|
{
|
||||||
@@ -100,6 +104,8 @@ namespace KernelPanic.UI
|
|||||||
GameEvents.EnemyWouldAct += HandleEnemyWouldAct;
|
GameEvents.EnemyWouldAct += HandleEnemyWouldAct;
|
||||||
GameEvents.PlayerDamaged += HandlePlayerDamaged;
|
GameEvents.PlayerDamaged += HandlePlayerDamaged;
|
||||||
GameEvents.StatusApplied += HandleStatusApplied;
|
GameEvents.StatusApplied += HandleStatusApplied;
|
||||||
|
GameEvents.StatusExpired += HandleStatusEnded;
|
||||||
|
GameEvents.StatusCleansed += HandleStatusEnded;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
@@ -148,6 +154,8 @@ namespace KernelPanic.UI
|
|||||||
GameEvents.EnemyWouldAct -= HandleEnemyWouldAct;
|
GameEvents.EnemyWouldAct -= HandleEnemyWouldAct;
|
||||||
GameEvents.PlayerDamaged -= HandlePlayerDamaged;
|
GameEvents.PlayerDamaged -= HandlePlayerDamaged;
|
||||||
GameEvents.StatusApplied -= HandleStatusApplied;
|
GameEvents.StatusApplied -= HandleStatusApplied;
|
||||||
|
GameEvents.StatusExpired -= HandleStatusEnded;
|
||||||
|
GameEvents.StatusCleansed -= HandleStatusEnded;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool TryBuildRunConfig(out RunConfig config)
|
private bool TryBuildRunConfig(out RunConfig config)
|
||||||
@@ -412,6 +420,7 @@ namespace KernelPanic.UI
|
|||||||
|
|
||||||
CombatantState state = combatManager.PlayerState;
|
CombatantState state = combatManager.PlayerState;
|
||||||
DetectBeneficialResourceFeedback(state, playerPanel);
|
DetectBeneficialResourceFeedback(state, playerPanel);
|
||||||
|
ApplyStatusStateClasses(playerPanel, state);
|
||||||
playerPanel.Add(MeterBlock("uptime", state.CurrentUptime, state.MaxUptime, MeterTone.Uptime));
|
playerPanel.Add(MeterBlock("uptime", state.CurrentUptime, state.MaxUptime, MeterTone.Uptime));
|
||||||
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));
|
||||||
@@ -459,6 +468,7 @@ namespace KernelPanic.UI
|
|||||||
card.Add(name);
|
card.Add(name);
|
||||||
combatantElements[enemy.State] = card;
|
combatantElements[enemy.State] = card;
|
||||||
DetectBeneficialResourceFeedback(enemy.State, card);
|
DetectBeneficialResourceFeedback(enemy.State, card);
|
||||||
|
ApplyStatusStateClasses(card, enemy.State);
|
||||||
card.Add(MeterBlock("uptime", enemy.CurrentUptime, enemy.MaxUptime, MeterTone.Uptime));
|
card.Add(MeterBlock("uptime", enemy.CurrentUptime, enemy.MaxUptime, MeterTone.Uptime));
|
||||||
if (enemy.State.Shield > 0)
|
if (enemy.State.Shield > 0)
|
||||||
{
|
{
|
||||||
@@ -1047,9 +1057,14 @@ namespace KernelPanic.UI
|
|||||||
|
|
||||||
if (payload.Track == ResolutionTrack.InterpreterQueue)
|
if (payload.Track == ResolutionTrack.InterpreterQueue)
|
||||||
{
|
{
|
||||||
VisualElement chip = queueChipElements.TryGetValue(payload.Card, out VisualElement queuedChip) ? queuedChip : interpreterStrip;
|
int delay = UIPreferences.ReducedMotion ? 0 : Mathf.Min(queueCascadeIndex * 120, 600);
|
||||||
PlayElementBeat(chip, "queue-chip-resolve", 260);
|
queueCascadeIndex++;
|
||||||
FlyCardGhost(payload.Card, chip, turnResourceGrid, "feedback-card-discard");
|
ScheduleFeedback(() =>
|
||||||
|
{
|
||||||
|
VisualElement chip = queueChipElements.TryGetValue(payload.Card, out VisualElement queuedChip) ? queuedChip : interpreterStrip;
|
||||||
|
PlayElementBeat(chip, "queue-chip-resolve", 260);
|
||||||
|
FlyCardGhost(payload.Card, chip, turnResourceGrid, "feedback-card-discard");
|
||||||
|
}, delay);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1063,63 +1078,86 @@ namespace KernelPanic.UI
|
|||||||
|
|
||||||
private void HandlePhaseChanged(PhaseChangedEvent payload)
|
private void HandlePhaseChanged(PhaseChangedEvent payload)
|
||||||
{
|
{
|
||||||
|
if (payload.NextPhase == TurnPhase.Interpret)
|
||||||
|
{
|
||||||
|
queueCascadeIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
feedbackCascadeIndex = 0;
|
||||||
ScheduleFeedback(() => PlayElementBeat(phaseLabel, "phase-pulse", 260), 0);
|
ScheduleFeedback(() => PlayElementBeat(phaseLabel, "phase-pulse", 260), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleDamageDealt(DamageDealtEvent payload)
|
private void HandleDamageDealt(DamageDealtEvent payload)
|
||||||
{
|
{
|
||||||
ScheduleFeedback(() =>
|
bool isPlayer = payload.Target == combatManager.PlayerState;
|
||||||
|
VisualElement target = CombatantElement(payload.Target);
|
||||||
|
ScheduleCombatBeat(beatIndex =>
|
||||||
{
|
{
|
||||||
bool isPlayer = payload.Target == combatManager.PlayerState;
|
string text = payload.WasFullyBlocked ? "clang" : payload.UptimeDamage <= 0 ? "blocked" : $"-{Mathf.RoundToInt(payload.UptimeDamage)}";
|
||||||
VisualElement target = CombatantElement(payload.Target);
|
string tone = payload.WasFullyBlocked || payload.WasMitigated ? "float-muted" : "float-damage";
|
||||||
string text = payload.Amount <= 0 ? "blocked" : $"-{Mathf.RoundToInt(payload.Amount)}";
|
string beatClass = payload.WasFullyBlocked || payload.WasMitigated ? "feedback-clang" : payload.WasCritical ? "feedback-crit" : "feedback-hit";
|
||||||
string tone = payload.Amount <= 0 ? "float-muted" : "float-damage";
|
int beatDuration = payload.WasCritical ? 360 : payload.WasMitigated ? 260 : 240;
|
||||||
if (payload.Amount >= 8)
|
|
||||||
|
if (payload.WasCritical || payload.UptimeDamage >= 8)
|
||||||
{
|
{
|
||||||
tone += " float-large";
|
tone += " float-large";
|
||||||
}
|
}
|
||||||
|
|
||||||
SpawnFloatingText(target, text, tone);
|
SpawnFloatingText(target, text, tone, beatIndex);
|
||||||
PlayElementBeat(target, payload.Amount <= 0 ? "feedback-block" : "feedback-hit", 240);
|
SpawnImpactMarker(target, payload.WasCritical, payload.WasMitigated, beatIndex);
|
||||||
if (isPlayer && payload.Amount > 0)
|
PlayElementBeat(target, beatClass, beatDuration);
|
||||||
|
if (isPlayer && payload.UptimeDamage > 0)
|
||||||
{
|
{
|
||||||
FlashDamageVignette();
|
FlashDamageVignette(payload.WasCritical);
|
||||||
}
|
}
|
||||||
}, 0);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleCombatantDefeated(CombatantDefeatedEvent payload)
|
private void HandleCombatantDefeated(CombatantDefeatedEvent payload)
|
||||||
{
|
{
|
||||||
ScheduleFeedback(() =>
|
VisualElement target = CombatantElement(payload.Combatant);
|
||||||
|
Rect targetBounds = target?.worldBound ?? Rect.zero;
|
||||||
|
ScheduleCombatBeat(() =>
|
||||||
{
|
{
|
||||||
VisualElement target = CombatantElement(payload.Combatant);
|
SpawnFloatingText(target, "killed", "float-kill float-large", 0);
|
||||||
SpawnFloatingText(target, "killed", "float-kill float-large");
|
SpawnDeathGhost(targetBounds);
|
||||||
SpawnDeathGhost(target);
|
if (target != enemyRow)
|
||||||
PlayElementBeat(target, "feedback-killed", 260);
|
{
|
||||||
}, 0);
|
PlayElementBeat(target, "feedback-killed", 420);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleEnemyWouldAct(EnemyWouldActEvent payload)
|
private void HandleEnemyWouldAct(EnemyWouldActEvent payload)
|
||||||
{
|
{
|
||||||
ScheduleFeedback(() => PlayElementBeat(CombatantElement(payload.Enemy?.State), "enemy-acting", 260), 0);
|
ScheduleCombatBeat(() => PlayElementBeat(CombatantElement(payload.Enemy?.State), "enemy-anticipating", 340));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandlePlayerDamaged(PlayerDamagedEvent payload)
|
private void HandlePlayerDamaged(PlayerDamagedEvent payload)
|
||||||
{
|
{
|
||||||
if (payload.Amount > 0)
|
// DamageDealt carries richer mitigation data and owns the visual hit beat.
|
||||||
{
|
|
||||||
ScheduleFeedback(FlashDamageVignette, 0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleStatusApplied(StatusAppliedEvent payload)
|
private void HandleStatusApplied(StatusAppliedEvent payload)
|
||||||
{
|
{
|
||||||
ScheduleFeedback(() =>
|
ScheduleCombatBeat(() =>
|
||||||
{
|
{
|
||||||
StatusDescriptor descriptor = StatusEffectController.GetDescriptor(payload.StatusType);
|
StatusDescriptor descriptor = StatusEffectController.GetDescriptor(payload.StatusType);
|
||||||
SpawnFloatingText(CombatantElement(payload.Target), $"{descriptor.IconKey} x{payload.Stacks}", descriptor.IsBeneficial ? "float-heal" : "float-status");
|
VisualElement target = CombatantElement(payload.Target);
|
||||||
PlayElementBeat(CombatantElement(payload.Target), descriptor.IsBeneficial ? "feedback-boost" : "feedback-status", 220);
|
ApplyStatusStateClass(target, payload.StatusType, true);
|
||||||
}, 0);
|
SpawnFloatingText(target, $"{descriptor.IconKey} x{payload.Stacks}", descriptor.IsBeneficial ? "float-heal" : "float-status");
|
||||||
|
PlayElementBeat(target, descriptor.IsBeneficial ? "feedback-boost" : "feedback-status", 220);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleStatusEnded(StatusExpiredEvent payload)
|
||||||
|
{
|
||||||
|
ApplyStatusStateClass(CombatantElement(payload.Target), payload.StatusType, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleStatusEnded(StatusCleansedEvent payload)
|
||||||
|
{
|
||||||
|
ApplyStatusStateClass(CombatantElement(payload.Target), payload.StatusType, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DetectBeneficialResourceFeedback(CombatantState state, VisualElement element)
|
private void DetectBeneficialResourceFeedback(CombatantState state, VisualElement element)
|
||||||
@@ -1181,12 +1219,31 @@ namespace KernelPanic.UI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
element.RemoveFromClassList(className);
|
int version = ++feedbackBeatVersion;
|
||||||
element.AddToClassList(className);
|
feedbackBeatVersions[element] = version;
|
||||||
ScheduleFeedback(() => element.RemoveFromClassList(className), UIPreferences.ReducedMotion ? 80 : durationMs);
|
RemoveFeedbackBeatClasses(element);
|
||||||
|
ScheduleFeedback(() =>
|
||||||
|
{
|
||||||
|
if (!feedbackBeatVersions.TryGetValue(element, out int currentVersion) || currentVersion != version)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.AddToClassList(className);
|
||||||
|
ScheduleFeedback(() =>
|
||||||
|
{
|
||||||
|
if (!feedbackBeatVersions.TryGetValue(element, out int removeVersion) || removeVersion != version)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.RemoveFromClassList(className);
|
||||||
|
feedbackBeatVersions.Remove(element);
|
||||||
|
}, UIPreferences.ReducedMotion ? 80 : durationMs);
|
||||||
|
}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SpawnFloatingText(VisualElement anchor, string text, string className)
|
private void SpawnFloatingText(VisualElement anchor, string text, string className, int cascadeOffset = 0)
|
||||||
{
|
{
|
||||||
if (feedbackLayer == null || anchor == null)
|
if (feedbackLayer == null || anchor == null)
|
||||||
{
|
{
|
||||||
@@ -1209,8 +1266,10 @@ namespace KernelPanic.UI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
label.style.left = anchorRect.center.x - rootRect.x - 30f;
|
float offsetX = (((cascadeOffset % 5) - 2) * 14f);
|
||||||
label.style.top = anchorRect.center.y - rootRect.y - 16f;
|
float offsetY = ((cascadeOffset % 3) * 5f);
|
||||||
|
label.style.left = anchorRect.center.x - rootRect.x - 30f + offsetX;
|
||||||
|
label.style.top = anchorRect.center.y - rootRect.y - 16f + offsetY;
|
||||||
feedbackLayer.Add(label);
|
feedbackLayer.Add(label);
|
||||||
|
|
||||||
if (UIPreferences.ReducedMotion)
|
if (UIPreferences.ReducedMotion)
|
||||||
@@ -1222,12 +1281,44 @@ namespace KernelPanic.UI
|
|||||||
|
|
||||||
ScheduleFeedback(() =>
|
ScheduleFeedback(() =>
|
||||||
{
|
{
|
||||||
label.style.top = anchorRect.center.y - rootRect.y - 42f;
|
label.style.top = anchorRect.center.y - rootRect.y - 42f + offsetY;
|
||||||
label.style.opacity = 0f;
|
label.style.opacity = 0f;
|
||||||
}, 20);
|
}, 20);
|
||||||
ScheduleFeedback(() => label.RemoveFromHierarchy(), 520);
|
ScheduleFeedback(() => label.RemoveFromHierarchy(), 520);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void SpawnImpactMarker(VisualElement anchor, bool critical, bool mitigated, int cascadeOffset)
|
||||||
|
{
|
||||||
|
if (feedbackLayer == null || anchor == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect anchorRect = anchor.worldBound;
|
||||||
|
Rect rootRect = root.worldBound;
|
||||||
|
Label marker = new(critical ? "crit" : mitigated ? "clang" : "hit");
|
||||||
|
marker.AddToClassList("impact-marker");
|
||||||
|
marker.AddToClassList(critical ? "impact-marker-crit" : mitigated ? "impact-marker-clang" : "impact-marker-hit");
|
||||||
|
|
||||||
|
float lane = (cascadeOffset % 4) * 18f;
|
||||||
|
marker.style.left = anchorRect.xMax - rootRect.x - 54f;
|
||||||
|
marker.style.top = anchorRect.y - rootRect.y + 8f + lane;
|
||||||
|
feedbackLayer.Add(marker);
|
||||||
|
|
||||||
|
if (UIPreferences.ReducedMotion)
|
||||||
|
{
|
||||||
|
ScheduleFeedback(() => marker.RemoveFromHierarchy(), 260);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScheduleFeedback(() =>
|
||||||
|
{
|
||||||
|
marker.style.left = anchorRect.xMax - rootRect.x - 34f;
|
||||||
|
marker.style.opacity = 0f;
|
||||||
|
}, 20);
|
||||||
|
ScheduleFeedback(() => marker.RemoveFromHierarchy(), 420);
|
||||||
|
}
|
||||||
|
|
||||||
private void FlyCardGhost(CardInstance card, VisualElement source, VisualElement destination, string className)
|
private void FlyCardGhost(CardInstance card, VisualElement source, VisualElement destination, string className)
|
||||||
{
|
{
|
||||||
if (feedbackLayer == null || card == null)
|
if (feedbackLayer == null || card == null)
|
||||||
@@ -1265,22 +1356,23 @@ namespace KernelPanic.UI
|
|||||||
ScheduleFeedback(() => ghost.RemoveFromHierarchy(), 360);
|
ScheduleFeedback(() => ghost.RemoveFromHierarchy(), 360);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SpawnDeathGhost(VisualElement source)
|
private void SpawnDeathGhost(Rect sourceRect)
|
||||||
{
|
{
|
||||||
if (feedbackLayer == null || source == null)
|
if (feedbackLayer == null || sourceRect.width <= 0f || sourceRect.height <= 0f)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rect rootRect = root.worldBound;
|
Rect rootRect = root.worldBound;
|
||||||
Rect sourceRect = source.worldBound;
|
float ghostWidth = Mathf.Min(sourceRect.width, 156f);
|
||||||
|
float ghostHeight = Mathf.Min(sourceRect.height, 132f);
|
||||||
VisualElement ghost = new();
|
VisualElement ghost = new();
|
||||||
ghost.AddToClassList("death-ghost");
|
ghost.AddToClassList("death-ghost");
|
||||||
ghost.style.position = Position.Absolute;
|
ghost.style.position = Position.Absolute;
|
||||||
ghost.style.left = sourceRect.x - rootRect.x;
|
ghost.style.left = sourceRect.center.x - rootRect.x - (ghostWidth * 0.5f);
|
||||||
ghost.style.top = sourceRect.y - rootRect.y;
|
ghost.style.top = sourceRect.center.y - rootRect.y - (ghostHeight * 0.5f);
|
||||||
ghost.style.width = sourceRect.width;
|
ghost.style.width = ghostWidth;
|
||||||
ghost.style.height = sourceRect.height;
|
ghost.style.height = ghostHeight;
|
||||||
feedbackLayer.Add(ghost);
|
feedbackLayer.Add(ghost);
|
||||||
|
|
||||||
if (UIPreferences.ReducedMotion)
|
if (UIPreferences.ReducedMotion)
|
||||||
@@ -1297,14 +1389,52 @@ namespace KernelPanic.UI
|
|||||||
ScheduleFeedback(() => ghost.RemoveFromHierarchy(), 360);
|
ScheduleFeedback(() => ghost.RemoveFromHierarchy(), 360);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void FlashDamageVignette()
|
private void FlashDamageVignette(bool critical)
|
||||||
{
|
{
|
||||||
if (damageVignette == null)
|
if (damageVignette == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayElementBeat(damageVignette, "damage-vignette-on", UIPreferences.ReducedMotion ? 120 : 240);
|
PlayElementBeat(damageVignette, critical ? "damage-vignette-crit" : "damage-vignette-on", UIPreferences.ReducedMotion ? 120 : critical ? 320 : 240);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RemoveFeedbackBeatClasses(VisualElement element)
|
||||||
|
{
|
||||||
|
element.RemoveFromClassList("feedback-hit");
|
||||||
|
element.RemoveFromClassList("feedback-crit");
|
||||||
|
element.RemoveFromClassList("feedback-clang");
|
||||||
|
element.RemoveFromClassList("feedback-block");
|
||||||
|
element.RemoveFromClassList("feedback-status");
|
||||||
|
element.RemoveFromClassList("feedback-boost");
|
||||||
|
element.RemoveFromClassList("feedback-killed");
|
||||||
|
element.RemoveFromClassList("enemy-anticipating");
|
||||||
|
element.RemoveFromClassList("enemy-acting");
|
||||||
|
element.RemoveFromClassList("phase-pulse");
|
||||||
|
element.RemoveFromClassList("cycles-spent-beat");
|
||||||
|
element.RemoveFromClassList("feedback-denied");
|
||||||
|
element.RemoveFromClassList("queue-chip-resolve");
|
||||||
|
element.RemoveFromClassList("stack-chip-resolve");
|
||||||
|
element.RemoveFromClassList("hand-card-drawn");
|
||||||
|
element.RemoveFromClassList("damage-vignette-on");
|
||||||
|
element.RemoveFromClassList("damage-vignette-crit");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ScheduleCombatBeat(Action action, int holdMs = 0)
|
||||||
|
{
|
||||||
|
ScheduleCombatBeat(_ => action?.Invoke(), holdMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ScheduleCombatBeat(Action<int> action, int holdMs = 0)
|
||||||
|
{
|
||||||
|
if (action == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int beatIndex = feedbackCascadeIndex++;
|
||||||
|
int delay = UIPreferences.ReducedMotion ? 0 : Mathf.Min(beatIndex * 120, 840);
|
||||||
|
ScheduleFeedback(() => action(beatIndex), delay + (UIPreferences.ReducedMotion ? 0 : holdMs));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ScheduleFeedback(Action action, int delayMs)
|
private void ScheduleFeedback(Action action, int delayMs)
|
||||||
@@ -1317,6 +1447,47 @@ namespace KernelPanic.UI
|
|||||||
root.schedule.Execute(action).StartingIn(Mathf.Max(0, delayMs));
|
root.schedule.Execute(action).StartingIn(Mathf.Max(0, delayMs));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ApplyStatusStateClasses(VisualElement element, CombatantState state)
|
||||||
|
{
|
||||||
|
if (element == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoveStatusStateClasses(element);
|
||||||
|
if (state == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < state.Statuses.Count; i++)
|
||||||
|
{
|
||||||
|
ApplyStatusStateClass(element, state.Statuses[i].Type, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ApplyStatusStateClass(VisualElement element, StatusType statusType, bool enabled)
|
||||||
|
{
|
||||||
|
string className = StatusStateClass(statusType);
|
||||||
|
if (element == null || string.IsNullOrEmpty(className))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.EnableInClassList(className, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RemoveStatusStateClasses(VisualElement element)
|
||||||
|
{
|
||||||
|
ApplyStatusStateClass(element, StatusType.MemoryLeak, false);
|
||||||
|
ApplyStatusStateClass(element, StatusType.Segfault, false);
|
||||||
|
ApplyStatusStateClass(element, StatusType.RaceCondition, false);
|
||||||
|
ApplyStatusStateClass(element, StatusType.Deprecated, false);
|
||||||
|
ApplyStatusStateClass(element, StatusType.DependencyError, false);
|
||||||
|
ApplyStatusStateClass(element, StatusType.Deadlock, false);
|
||||||
|
ApplyStatusStateClass(element, StatusType.UnattendedUpgrades, false);
|
||||||
|
}
|
||||||
|
|
||||||
private void HandleCombatLog(string message)
|
private void HandleCombatLog(string message)
|
||||||
{
|
{
|
||||||
if (logLabel != null)
|
if (logLabel != null)
|
||||||
@@ -1517,6 +1688,21 @@ namespace KernelPanic.UI
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static string StatusStateClass(StatusType statusType)
|
||||||
|
{
|
||||||
|
return statusType switch
|
||||||
|
{
|
||||||
|
StatusType.MemoryLeak => "status-state-leaking",
|
||||||
|
StatusType.Segfault => "status-state-segfault",
|
||||||
|
StatusType.RaceCondition => "status-state-race",
|
||||||
|
StatusType.Deprecated => "status-state-deprecated",
|
||||||
|
StatusType.DependencyError => "status-state-dependency-error",
|
||||||
|
StatusType.Deadlock => "status-state-deadlock",
|
||||||
|
StatusType.UnattendedUpgrades => "status-state-upgrading",
|
||||||
|
_ => string.Empty
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static string OfferKindText(RepositoryOfferKind kind)
|
private static string OfferKindText(RepositoryOfferKind kind)
|
||||||
{
|
{
|
||||||
return kind switch
|
return kind switch
|
||||||
|
|||||||
Reference in New Issue
Block a user