From 4768c9b3e0e5b5ecf4de2ebaf514cfc7ccf55dee Mon Sep 17 00:00:00 2001 From: KrisHD1337 Date: Mon, 6 Jul 2026 16:39:24 +0200 Subject: [PATCH 1/4] Update asset references to use new GUIDs. --- Assets/Data/Cards/CardDatabase.asset | 34 ++-- Assets/Data/Distros/Fedora.asset | 12 +- Assets/Data/Distros/Mint.asset | 12 +- Assets/Data/Distros/Ubuntu.asset | 12 +- Assets/Scenes/MainMenuScene.unity | 2 +- ...niversalRenderPipelineGlobalSettings.asset | 188 ++++++++++++++++++ 6 files changed, 224 insertions(+), 36 deletions(-) diff --git a/Assets/Data/Cards/CardDatabase.asset b/Assets/Data/Cards/CardDatabase.asset index 9973287..6260e51 100644 --- a/Assets/Data/Cards/CardDatabase.asset +++ b/Assets/Data/Cards/CardDatabase.asset @@ -9,23 +9,23 @@ MonoBehaviour: m_GameObject: {fileID: 0} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 85f230365a0e4f28a4bfbdb0a15115a8, type: 3} + m_Script: {fileID: 11500000, guid: fd9e459379f339742a14cf224cd91234, type: 3} m_Name: CardDatabase m_EditorClassIdentifier: allCards: - - {fileID: 11400000, guid: 0a4f1d1d84564f3cad58b8863e941201, type: 2} - - {fileID: 11400000, guid: 14c5d40f866a4cb6b0a6316e01f42891, type: 2} - - {fileID: 11400000, guid: 2a0f50d541f046fc99c8fb6deef4f1aa, type: 2} - - {fileID: 11400000, guid: 3d57857f3f30419c8be4c44914c5abbe, type: 2} - - {fileID: 11400000, guid: 4cae271a0f4146c59aab74e4c9d6d0f8, type: 2} - - {fileID: 11400000, guid: 5fef058a72b54b4aa2b2dd8f4d08bfe5, type: 2} - - {fileID: 11400000, guid: feda0000000000000000000000000001, type: 2} - - {fileID: 11400000, guid: feda0000000000000000000000000002, type: 2} - - {fileID: 11400000, guid: feda0000000000000000000000000003, type: 2} - - {fileID: 11400000, guid: feda0000000000000000000000000004, type: 2} - - {fileID: 11400000, guid: feda0000000000000000000000000005, type: 2} - - {fileID: 11400000, guid: c1a50000000000000000000000000001, type: 2} - - {fileID: 11400000, guid: c1a50000000000000000000000000002, type: 2} - - {fileID: 11400000, guid: c1a50000000000000000000000000003, type: 2} - - {fileID: 11400000, guid: c1a50000000000000000000000000004, type: 2} - - {fileID: 11400000, guid: c1a50000000000000000000000000005, type: 2} + - {fileID: 11400000, guid: f2a229189aa753e48806c9459618f10b, type: 2} + - {fileID: 11400000, guid: 93ddfe2f35c5c4447b1e5f49b50c544d, type: 2} + - {fileID: 11400000, guid: e6a3f582f36bb2647ab6101d60a05075, type: 2} + - {fileID: 11400000, guid: 258f2221f41c405468e0024e8e769614, type: 2} + - {fileID: 11400000, guid: e0a15eebcb5cb7b409a6afe60710e1e1, type: 2} + - {fileID: 11400000, guid: 1120e87243f2b5c48b6a334855af7937, type: 2} + - {fileID: 11400000, guid: ab370770e5f6c544996be970b87e7801, type: 2} + - {fileID: 11400000, guid: cdde7bad9bde5ff44a047263bce1bb4e, type: 2} + - {fileID: 11400000, guid: fde58599fc89f4f4ab515612f4f481f7, type: 2} + - {fileID: 11400000, guid: 7f1a9912cb72c5b448fa2cb101eb9785, type: 2} + - {fileID: 11400000, guid: f3d46628fc9cc2142ab5dfc5d78b158f, type: 2} + - {fileID: 11400000, guid: 6bfadf916238fd74b91e28a875239da4, type: 2} + - {fileID: 11400000, guid: 698dfb4b10be9f2419ca74e0b3443d48, type: 2} + - {fileID: 11400000, guid: b4a80ab16b6240d4d8d9d3a5cabd3fda, type: 2} + - {fileID: 11400000, guid: 662257d2f1d13554fb1eb6c63257859c, type: 2} + - {fileID: 11400000, guid: e6c02c38647698744903032f93fb30da, type: 2} diff --git a/Assets/Data/Distros/Fedora.asset b/Assets/Data/Distros/Fedora.asset index 799f8ae..eb1ca73 100644 --- a/Assets/Data/Distros/Fedora.asset +++ b/Assets/Data/Distros/Fedora.asset @@ -16,7 +16,7 @@ MonoBehaviour: displayName: Fedora primaryLanguage: 2 secondaryLanguage: 8 - passive: {fileID: 11400000, guid: a1100000000000000000000000000002, type: 2} + passive: {fileID: 11400000, guid: ded62c69f70d38a49b21972d857df4e2, type: 2} description: First to every new feature. Occasionally first to the bugs that come with it. playstyleSummary: high-tempo gambler. her first play each turn is pushed hard, but bleeding edge bites back. rust cards are her safety net. languageBlurbs: @@ -30,8 +30,8 @@ MonoBehaviour: baseRam: 5 baseCyclesPerTurn: 3 exclusiveCards: - - {fileID: 11400000, guid: feda0000000000000000000000000001, type: 2} - - {fileID: 11400000, guid: feda0000000000000000000000000002, type: 2} - - {fileID: 11400000, guid: feda0000000000000000000000000003, type: 2} - - {fileID: 11400000, guid: feda0000000000000000000000000004, type: 2} - - {fileID: 11400000, guid: feda0000000000000000000000000005, type: 2} + - {fileID: 11400000, guid: 93ddfe2f35c5c4447b1e5f49b50c544d, type: 2} + - {fileID: 11400000, guid: e6a3f582f36bb2647ab6101d60a05075, type: 2} + - {fileID: 11400000, guid: e0a15eebcb5cb7b409a6afe60710e1e1, type: 2} + - {fileID: 11400000, guid: fde58599fc89f4f4ab515612f4f481f7, type: 2} + - {fileID: 11400000, guid: 7f1a9912cb72c5b448fa2cb101eb9785, type: 2} diff --git a/Assets/Data/Distros/Mint.asset b/Assets/Data/Distros/Mint.asset index ec81959..cb8d112 100644 --- a/Assets/Data/Distros/Mint.asset +++ b/Assets/Data/Distros/Mint.asset @@ -16,7 +16,7 @@ MonoBehaviour: displayName: Mint primaryLanguage: 3 secondaryLanguage: 4 - passive: {fileID: 11400000, guid: a1100000000000000000000000000003, type: 2} + passive: {fileID: 11400000, guid: d97481a7d54be2045a96165d3977c980, type: 2} description: Comfort incarnate. No surprises, no drama, ever. playstyleSummary: zero-variance comfort. every number lands at its ceiling, so you always know exactly what a turn does -- at the cost of a high-roll upside. languageBlurbs: @@ -30,8 +30,8 @@ MonoBehaviour: baseRam: 5 baseCyclesPerTurn: 3 exclusiveCards: - - {fileID: 11400000, guid: c1a50000000000000000000000000001, type: 2} - - {fileID: 11400000, guid: c1a50000000000000000000000000002, type: 2} - - {fileID: 11400000, guid: c1a50000000000000000000000000003, type: 2} - - {fileID: 11400000, guid: c1a50000000000000000000000000004, type: 2} - - {fileID: 11400000, guid: c1a50000000000000000000000000005, type: 2} + - {fileID: 11400000, guid: 258f2221f41c405468e0024e8e769614, type: 2} + - {fileID: 11400000, guid: ab370770e5f6c544996be970b87e7801, type: 2} + - {fileID: 11400000, guid: cdde7bad9bde5ff44a047263bce1bb4e, type: 2} + - {fileID: 11400000, guid: 698dfb4b10be9f2419ca74e0b3443d48, type: 2} + - {fileID: 11400000, guid: e6c02c38647698744903032f93fb30da, type: 2} diff --git a/Assets/Data/Distros/Ubuntu.asset b/Assets/Data/Distros/Ubuntu.asset index 7189990..47aa428 100644 --- a/Assets/Data/Distros/Ubuntu.asset +++ b/Assets/Data/Distros/Ubuntu.asset @@ -16,7 +16,7 @@ MonoBehaviour: displayName: Ubuntu primaryLanguage: 3 secondaryLanguage: 4 - passive: {fileID: 11400000, guid: a1100000000000000000000000000001, type: 2} + passive: {fileID: 11400000, guid: 19deb73cec3d5dc42a5cc336222ce9df, type: 2} description: The friendly one. Everything works out of the box, and she will not stop helping. playstyleSummary: an accessible engine that never runs dry -- cheap python cards and a passive that always finds you the right package. languageBlurbs: @@ -30,8 +30,8 @@ MonoBehaviour: baseRam: 5 baseCyclesPerTurn: 3 exclusiveCards: - - {fileID: 11400000, guid: 0a4f1d1d84564f3cad58b8863e941201, type: 2} - - {fileID: 11400000, guid: 14c5d40f866a4cb6b0a6316e01f42891, type: 2} - - {fileID: 11400000, guid: 2a0f50d541f046fc99c8fb6deef4f1aa, type: 2} - - {fileID: 11400000, guid: 3d57857f3f30419c8be4c44914c5abbe, type: 2} - - {fileID: 11400000, guid: 4cae271a0f4146c59aab74e4c9d6d0f8, type: 2} + - {fileID: 11400000, guid: f2a229189aa753e48806c9459618f10b, type: 2} + - {fileID: 11400000, guid: 1120e87243f2b5c48b6a334855af7937, type: 2} + - {fileID: 11400000, guid: f3d46628fc9cc2142ab5dfc5d78b158f, type: 2} + - {fileID: 11400000, guid: 6bfadf916238fd74b91e28a875239da4, type: 2} + - {fileID: 11400000, guid: 662257d2f1d13554fb1eb6c63257859c, type: 2} diff --git a/Assets/Scenes/MainMenuScene.unity b/Assets/Scenes/MainMenuScene.unity index 71fcc0f..6018aad 100644 --- a/Assets/Scenes/MainMenuScene.unity +++ b/Assets/Scenes/MainMenuScene.unity @@ -306,5 +306,5 @@ MonoBehaviour: monospaceFont: {fileID: 0} motdBody: unstable userspace detected; keep a rollback shell open. distroDatabase: {fileID: 11400000, guid: 4d88ca5446fa4d80b2fbd4b12697cb7c, type: 2} - cardDatabase: {fileID: 11400000, guid: 6a8a9f37c98a4a7a9e67ab15d2d22208, type: 2} + cardDatabase: {fileID: 11400000, guid: 44015c39eebf6624daa4b49aee46bf9f, type: 2} featuredUnitPanel: {} diff --git a/Assets/UniversalRenderPipelineGlobalSettings.asset b/Assets/UniversalRenderPipelineGlobalSettings.asset index f3ba00c..8f5416f 100644 --- a/Assets/UniversalRenderPipelineGlobalSettings.asset +++ b/Assets/UniversalRenderPipelineGlobalSettings.asset @@ -67,6 +67,17 @@ MonoBehaviour: - rid: 8545822260705886216 - rid: 8545822260705886217 - rid: 8545822260705886218 + - rid: 6579781124582014978 + - rid: 6579781124582014979 + - rid: 6579781124582014980 + - rid: 6579781124582014981 + - rid: 6579781124582014982 + - rid: 6579781124582014983 + - rid: 6579781124582014984 + - rid: 6579781124582014985 + - rid: 6579781124582014986 + - rid: 6579781124582014987 + - rid: 6579781124582014988 m_RuntimeSettings: m_List: [] m_AssetVersion: 10 @@ -128,6 +139,143 @@ MonoBehaviour: - {r: 0.5, g: 0, b: 0.5, a: 1} - {r: 0.5, g: 0.5, b: 0.5, a: 1} - {r: 0, g: 0, b: 1, a: 1} + - rid: 6579781124582014978 + type: {class: RayTracingRenderPipelineResources, ns: UnityEngine.Rendering.UnifiedRayTracing, asm: Unity.UnifiedRayTracing.Runtime} + data: + m_Version: 1 + m_GeometryPoolKernels: {fileID: 7200000, guid: 98e3d58cae7210c4786f67f504c9e899, type: 3} + m_CopyBuffer: {fileID: 7200000, guid: 1b95b5dcf48d1914c9e1e7405c7660e3, type: 3} + m_CopyPositions: {fileID: 7200000, guid: 1ad53a96b58d3c3488dde4f14db1aaeb, type: 3} + m_BitHistogram: {fileID: 7200000, guid: 8670f7ce4b60cef43bed36148aa1b0a2, type: 3} + m_BlockReducePart: {fileID: 7200000, guid: 4e034cc8ea2635c4e9f063e5ddc7ea7a, type: 3} + m_BlockScan: {fileID: 7200000, guid: 4d6d5de35fa45ef4a92119397a045cc9, type: 3} + m_BuildHlbvh: {fileID: 7200000, guid: 2d70cd6be91bd7843a39a54b51c15b13, type: 3} + m_RestructureBvh: {fileID: 7200000, guid: 56641cb88dcb31a4398a4997ef7a7a8c, type: 3} + m_Scatter: {fileID: 7200000, guid: a2eaeefdac4637a44b734e85b7be9186, type: 3} + - rid: 6579781124582014979 + type: {class: PostProcessData/ShaderResources, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} + data: + stopNanPS: {fileID: 4800000, guid: 1121bb4e615ca3c48b214e79e841e823, type: 3} + subpixelMorphologicalAntialiasingPS: {fileID: 4800000, guid: 63eaba0ebfb82cc43bde059b4a8c65f6, type: 3} + gaussianDepthOfFieldPS: {fileID: 4800000, guid: 5e7134d6e63e0bc47a1dd2669cedb379, type: 3} + bokehDepthOfFieldPS: {fileID: 4800000, guid: 2aed67ad60045d54ba3a00c91e2d2631, type: 3} + cameraMotionBlurPS: {fileID: 4800000, guid: 1edcd131364091c46a17cbff0b1de97a, type: 3} + paniniProjectionPS: {fileID: 4800000, guid: a15b78cf8ca26ca4fb2090293153c62c, type: 3} + lutBuilderLdrPS: {fileID: 4800000, guid: 65df88701913c224d95fc554db28381a, type: 3} + lutBuilderHdrPS: {fileID: 4800000, guid: ec9fec698a3456d4fb18cf8bacb7a2bc, type: 3} + bloomPS: {fileID: 4800000, guid: 5f1864addb451f54bae8c86d230f736e, type: 3} + temporalAntialiasingPS: {fileID: 4800000, guid: 9c70c1a35ff15f340b38ea84842358bf, type: 3} + LensFlareDataDrivenPS: {fileID: 4800000, guid: 6cda457ac28612740adb23da5d39ea92, type: 3} + LensFlareScreenSpacePS: {fileID: 4800000, guid: 701880fecb344ea4c9cd0db3407ab287, type: 3} + scalingSetupPS: {fileID: 4800000, guid: e8ee25143a34b8c4388709ea947055d1, type: 3} + easuPS: {fileID: 4800000, guid: 562b7ae4f629f144aa97780546fce7c6, type: 3} + uberPostPS: {fileID: 4800000, guid: e7857e9d0c934dc4f83f270f8447b006, type: 3} + finalPostPassPS: {fileID: 4800000, guid: c49e63ed1bbcb334780a3bd19dfed403, type: 3} + m_ShaderResourcesVersion: 0 + - rid: 6579781124582014980 + type: {class: PostProcessData/TextureResources, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} + data: + blueNoise16LTex: + - {fileID: 2800000, guid: 81200413a40918d4d8702e94db29911c, type: 3} + - {fileID: 2800000, guid: d50c5e07c9911a74982bddf7f3075e7b, type: 3} + - {fileID: 2800000, guid: 1134690bf9216164dbc75050e35b7900, type: 3} + - {fileID: 2800000, guid: 7ce2118f74614a94aa8a0cdf2e6062c3, type: 3} + - {fileID: 2800000, guid: 2ca97df9d1801e84a8a8f2c53cb744f0, type: 3} + - {fileID: 2800000, guid: e63eef8f54aa9dc4da9a5ac094b503b5, type: 3} + - {fileID: 2800000, guid: 39451254daebd6d40b52899c1f1c0c1b, type: 3} + - {fileID: 2800000, guid: c94ad916058dff743b0f1c969ddbe660, type: 3} + - {fileID: 2800000, guid: ed5ea7ce59ca8ec4f9f14bf470a30f35, type: 3} + - {fileID: 2800000, guid: 071e954febf155243a6c81e48f452644, type: 3} + - {fileID: 2800000, guid: 96aaab9cc247d0b4c98132159688c1af, type: 3} + - {fileID: 2800000, guid: fc3fa8f108657e14486697c9a84ccfc5, type: 3} + - {fileID: 2800000, guid: bfed3e498947fcb4890b7f40f54d85b9, type: 3} + - {fileID: 2800000, guid: d512512f4af60a442ab3458489412954, type: 3} + - {fileID: 2800000, guid: 47a45908f6db0cb44a0d5e961143afec, type: 3} + - {fileID: 2800000, guid: 4dcc0502f8586f941b5c4a66717205e8, type: 3} + - {fileID: 2800000, guid: 9d92991794bb5864c8085468b97aa067, type: 3} + - {fileID: 2800000, guid: 14381521ff11cb74abe3fe65401c23be, type: 3} + - {fileID: 2800000, guid: d36f0fe53425e08499a2333cf423634c, type: 3} + - {fileID: 2800000, guid: d4044ea2490d63b43aa1765f8efbf8a9, type: 3} + - {fileID: 2800000, guid: c9bd74624d8070f429e3f46d161f9204, type: 3} + - {fileID: 2800000, guid: d5c9b274310e5524ebe32a4e4da3df1f, type: 3} + - {fileID: 2800000, guid: f69770e54f2823f43badf77916acad83, type: 3} + - {fileID: 2800000, guid: 10b6c6d22e73dea46a8ab36b6eebd629, type: 3} + - {fileID: 2800000, guid: a2ec5cbf5a9b64345ad3fab0912ddf7b, type: 3} + - {fileID: 2800000, guid: 1c3c6d69a645b804fa232004b96b7ad3, type: 3} + - {fileID: 2800000, guid: d18a24d7b4ed50f4387993566d9d3ae2, type: 3} + - {fileID: 2800000, guid: c989e1ed85cf7154caa922fec53e6af6, type: 3} + - {fileID: 2800000, guid: ff47e5a0f105eb34883b973e51f4db62, type: 3} + - {fileID: 2800000, guid: fa042edbfc40fbd4bad0ab9d505b1223, type: 3} + - {fileID: 2800000, guid: 896d9004736809c4fb5973b7c12eb8b9, type: 3} + - {fileID: 2800000, guid: 179f794063d2a66478e6e726f84a65bc, type: 3} + filmGrainTex: + - {fileID: 2800000, guid: 654c582f7f8a5a14dbd7d119cbde215d, type: 3} + - {fileID: 2800000, guid: dd77ffd079630404e879388999033049, type: 3} + - {fileID: 2800000, guid: 1097e90e1306e26439701489f391a6c0, type: 3} + - {fileID: 2800000, guid: f0b67500f7fad3b4c9f2b13e8f41ba6e, type: 3} + - {fileID: 2800000, guid: 9930fb4528622b34687b00bbe6883de7, type: 3} + - {fileID: 2800000, guid: bd9e8c758250ef449a4b4bfaad7a2133, type: 3} + - {fileID: 2800000, guid: 510a2f57334933e4a8dbabe4c30204e4, type: 3} + - {fileID: 2800000, guid: b4db8180660810945bf8d55ab44352ad, type: 3} + - {fileID: 2800000, guid: fd2fd78b392986e42a12df2177d3b89c, type: 3} + - {fileID: 2800000, guid: 5cdee82a77d13994f83b8fdabed7c301, type: 3} + smaaAreaTex: {fileID: 2800000, guid: d1f1048909d55cd4fa1126ab998f617e, type: 3} + smaaSearchTex: {fileID: 2800000, guid: 51eee22c2a633ef4aada830eed57c3fd, type: 3} + m_TexturesResourcesVersion: 0 + - rid: 6579781124582014981 + type: {class: OnTilePostProcessResource, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} + data: + m_Version: 0 + m_UberPostShader: {fileID: 4800000, guid: fe4f13c1004a07d4ea1e30bfd0326d9e, type: 3} + - rid: 6579781124582014982 + type: {class: UniversalRenderPipelineRuntimeTerrainShaders, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} + data: + m_Version: 0 + m_TerrainDetailLit: {fileID: 4800000, guid: f6783ab646d374f94b199774402a5144, type: 3} + m_TerrainDetailGrassBillboard: {fileID: 4800000, guid: 29868e73b638e48ca99a19ea58c48d90, type: 3} + m_TerrainDetailGrass: {fileID: 4800000, guid: e507fdfead5ca47e8b9a768b51c291a1, type: 3} + - rid: 6579781124582014983 + type: {class: URPReflectionProbeSettings, ns: UnityEngine.Rendering, asm: Unity.RenderPipelines.Universal.Runtime} + data: + version: 1 + useReflectionProbeRotation: 0 + - rid: 6579781124582014984 + type: {class: ScreenSpaceAmbientOcclusionDynamicResources, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} + data: + m_BlueNoise256Textures: + - {fileID: 2800000, guid: 36f118343fc974119bee3d09e2111500, type: 3} + - {fileID: 2800000, guid: 4b7b083e6b6734e8bb2838b0b50a0bc8, type: 3} + - {fileID: 2800000, guid: c06cc21c692f94f5fb5206247191eeee, type: 3} + - {fileID: 2800000, guid: cb76dd40fa7654f9587f6a344f125c9a, type: 3} + - {fileID: 2800000, guid: e32226222ff144b24bf3a5a451de54bc, type: 3} + - {fileID: 2800000, guid: 3302065f671a8450b82c9ddf07426f3a, type: 3} + - {fileID: 2800000, guid: 56a77a3e8d64f47b6afe9e3c95cb57d5, type: 3} + m_Version: 0 + - rid: 6579781124582014985 + type: {class: ScreenSpaceAmbientOcclusionPersistentResources, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} + data: + m_Shader: {fileID: 4800000, guid: 0849e84e3d62649e8882e9d6f056a017, type: 3} + m_Version: 0 + - rid: 6579781124582014986 + type: {class: URPTerrainShaderSetting, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} + data: + m_Version: 0 + m_IncludeTerrainShaders: 1 + - rid: 6579781124582014987 + type: {class: RenderingDebuggerRuntimeResources, ns: UnityEngine.Rendering, asm: Unity.RenderPipelines.Core.Runtime} + data: + m_version: 0 + - rid: 6579781124582014988 + type: {class: WorldRenderPipelineResources, ns: UnityEngine.PathTracing.Core, asm: Unity.PathTracing.Runtime} + data: + _version: 3 + _blitCubemap: {fileID: 7200000, guid: 5a992812cb320d146a66cc600200cce7, type: 3} + _blitGrayScaleCookie: {fileID: 7200000, guid: 557fa399e33bf7647bda5697c5c158df, type: 3} + _setAlphaChannelShader: {fileID: 7200000, guid: 5efaea0e81c66334aa9d062d6573e6fd, type: 3} + _environmentImportanceSamplingBuild: {fileID: 7200000, guid: 5bb2534d2411d344cbc54f880232640f, type: 3} + _skyBoxMesh: {fileID: 4300000, guid: 0529e6c5f6dea8c4a8c2835ed7de57cb, type: 2} + _sixFaceSkyBoxMesh: {fileID: 4300000, guid: a80925ceebd011741b42509226cefc74, type: 2} + _buildLightGridShader: {fileID: 7200000, guid: 16e47c1641bd0104e92b624601457bb0, type: 3} - rid: 7752762179098771456 type: {class: UniversalRenderPipelineRuntimeTextures, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} data: @@ -159,6 +307,30 @@ MonoBehaviour: m_DefaultSpeedTree7Shader: {fileID: 4800000, guid: 0f4122b9a743b744abe2fb6a0a88868b, type: 3} m_DefaultSpeedTree8Shader: {fileID: -6465566751694194690, guid: 9920c1f1781549a46ba081a2a15a16ec, type: 3} m_DefaultSpeedTree9Shader: {fileID: -6465566751694194690, guid: cbd3e1cc4ae141c42a30e33b4d666a61, type: 3} + - rid: 7752762179098771457 + type: {class: Renderer2DResources, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} + data: + m_Version: 0 + m_LightShader: {fileID: 4800000, guid: 3f6c848ca3d7bca4bbe846546ac701a1, type: 3} + m_ProjectedShadowShader: {fileID: 4800000, guid: ce09d4a80b88c5a4eb9768fab4f1ee00, type: 3} + m_SpriteShadowShader: {fileID: 4800000, guid: 44fc62292b65ab04eabcf310e799ccf6, type: 3} + m_SpriteUnshadowShader: {fileID: 4800000, guid: de02b375720b5c445afe83cd483bedf3, type: 3} + m_GeometryShadowShader: {fileID: 4800000, guid: 19349a0f9a7ed4c48a27445bcf92e5e1, type: 3} + m_GeometryUnshadowShader: {fileID: 4800000, guid: 77774d9009bb81447b048c907d4c6273, type: 3} + m_CopyDepthPS: {fileID: 4800000, guid: d6dae50ee9e1bfa4db75f19f99355220, type: 3} + m_DefaultLitMaterial: {fileID: 2100000, guid: a97c105638bdf8b4a8650670310a4cd3, type: 2} + m_DefaultUnlitMaterial: {fileID: 2100000, guid: 9dfc825aed78fcd4ba02077103263b40, type: 2} + m_DefaultMaskMaterial: {fileID: 2100000, guid: 15d0c3709176029428a0da2f8cecf0b5, type: 2} + m_DefaultMesh2DLitMaterial: {fileID: 2100000, guid: 9452ae1262a74094f8a68013fbcd1834, type: 2} + - rid: 7752762179098771458 + type: {class: UniversalRenderPipelineEditorShaders, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} + data: + m_AutodeskInteractive: {fileID: 4800000, guid: 0e9d5a909a1f7e84882a534d0d11e49f, type: 3} + m_AutodeskInteractiveTransparent: {fileID: 4800000, guid: 5c81372d981403744adbdda4433c9c11, type: 3} + m_AutodeskInteractiveMasked: {fileID: 4800000, guid: 80aa867ac363ac043847b06ad71604cd, type: 3} + m_DefaultSpeedTree7Shader: {fileID: 4800000, guid: 0f4122b9a743b744abe2fb6a0a88868b, type: 3} + m_DefaultSpeedTree8Shader: {fileID: -6465566751694194690, guid: 9920c1f1781549a46ba081a2a15a16ec, type: 3} + m_DefaultSpeedTree9Shader: {fileID: -6465566751694194690, guid: cbd3e1cc4ae141c42a30e33b4d666a61, type: 3} - rid: 7752762179098771459 type: {class: URPDefaultVolumeProfileSettings, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} data: @@ -175,6 +347,10 @@ MonoBehaviour: type: {class: RenderGraphSettings, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} data: m_Version: 0 + - rid: 7752762179098771461 + type: {class: RenderGraphSettings, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} + data: + m_Version: 0 - rid: 7752762179098771462 type: {class: UniversalRenderPipelineDebugShaders, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} data: @@ -218,6 +394,18 @@ MonoBehaviour: m_TerrainDetailLit: {fileID: 0} m_TerrainDetailGrassBillboard: {fileID: 0} m_TerrainDetailGrass: {fileID: 0} + - rid: 7752762179098771466 + type: {class: UniversalRenderPipelineRuntimeShaders, ns: UnityEngine.Rendering.Universal, asm: Unity.RenderPipelines.Universal.Runtime} + data: + m_Version: 0 + m_FallbackErrorShader: {fileID: 4800000, guid: e6e9a19c3678ded42a3bc431ebef7dbd, type: 3} + m_BlitHDROverlay: {fileID: 4800000, guid: a89bee29cffa951418fc1e2da94d1959, type: 3} + m_CoreBlitPS: {fileID: 4800000, guid: 93446b5c5339d4f00b85c159e1159b7c, type: 3} + m_CoreBlitColorAndDepthPS: {fileID: 4800000, guid: d104b2fc1ca6445babb8e90b0758136b, type: 3} + m_SamplingPS: {fileID: 4800000, guid: 04c410c9937594faa893a11dceb85f7e, type: 3} + m_TerrainDetailLit: {fileID: 0} + m_TerrainDetailGrassBillboard: {fileID: 0} + m_TerrainDetailGrass: {fileID: 0} - rid: 7752762179098771467 type: {class: GPUResidentDrawerResources, ns: UnityEngine.Rendering, asm: Unity.RenderPipelines.GPUDriven.Runtime} data: From 22754e4106f1741b56075cbcae00ba09080960ec Mon Sep 17 00:00:00 2001 From: KrisHD1337 Date: Mon, 6 Jul 2026 22:10:31 +0200 Subject: [PATCH 2/4] Add metadata for new gacha assets and implement gacha system scaffolding. --- Assets/Data/Cards.meta | 8 + Assets/Data/Cards/CardDatabase.asset.meta | 8 + Assets/Data/Cards/Fedora.meta | 8 + .../Cards/Fedora/BorrowChecker.asset.meta | 8 + .../Cards/Fedora/CargoBuildRelease.asset.meta | 8 + Assets/Data/Cards/Fedora/DnfUpdate.asset.meta | 8 + Assets/Data/Cards/Fedora/Rawhide.asset.meta | 8 + .../Cards/Fedora/SELinuxEnforcing.asset.meta | 8 + Assets/Data/Cards/Mint.meta | 8 + Assets/Data/Cards/Mint/Cinnamon.asset.meta | 8 + Assets/Data/Cards/Mint/FixBroken.asset.meta | 8 + Assets/Data/Cards/Mint/Nemo.asset.meta | 8 + .../Cards/Mint/TimeshiftSnapshot.asset.meta | 8 + .../Data/Cards/Mint/UpdateManager.asset.meta | 8 + Assets/Data/Cards/Ubuntu.meta | 8 + Assets/Data/Cards/Ubuntu/AskUbuntu.asset.meta | 8 + .../Cards/Ubuntu/DoReleaseUpgrade.asset.meta | 8 + .../Data/Cards/Ubuntu/SnapInstall.asset.meta | 8 + .../Cards/Ubuntu/SudoAptInstall.asset.meta | 8 + .../Cards/Ubuntu/UbuntuProTrial.asset.meta | 8 + .../Ubuntu/UnattendedUpgrades.asset.meta | 8 + Assets/Data/Passives.meta | 8 + Assets/Data/Passives/AptUpdate.asset.meta | 8 + Assets/Data/Passives/BleedingEdge.asset.meta | 8 + Assets/Data/Passives/ItJustWorks.asset.meta | 8 + Assets/DefaultVolumeProfile.asset | 3 + Assets/Scenes/FightScene.unity.meta | 7 + Assets/Scenes/GamblingScene.unity.meta | 7 + Assets/Scripts/Data/CardDatabase.cs.meta | 2 + Assets/Scripts/Data/PassiveDefinition.cs.meta | 2 + Assets/Scripts/Meta/CardLoadout.cs.meta | 2 + Assets/Scripts/Meta/EntropyWallet.cs | 5 + Assets/Scripts/Meta/GachaBannerState.cs | 34 ++ Assets/Scripts/Meta/GachaBannerState.cs.meta | 2 + Assets/Scripts/Meta/GachaCurrencyType.cs | 11 + Assets/Scripts/Meta/GachaCurrencyType.cs.meta | 2 + Assets/Scripts/Meta/GachaRewardType.cs | 12 + Assets/Scripts/Meta/GachaRewardType.cs.meta | 2 + Assets/Scripts/Meta/GachaService.cs | 568 +++++++++++++++++- Assets/Scripts/Meta/PlayerCollection.cs | 23 +- Assets/Scripts/Meta/SaveService.cs | 8 + .../UI/CollectionScreenController.cs.meta | 2 + Assets/Scripts/UI/CommandKeyBindings.cs.meta | 2 + Assets/Scripts/UI/DistroPresentation.cs.meta | 2 + Assets/Scripts/UI/GachaScreenController.cs | 487 +++++++++++++++ .../Scripts/UI/GachaScreenController.cs.meta | 2 + Assets/Scripts/UI/MainMenuController.cs | 398 +++++++++++- .../Scripts/UI/ScreenFrameController.cs.meta | 2 + .../UI/StarterSelectionController.cs.meta | 2 + Assets/UI/GachaScreen.uxml | 5 +- Assets/UI/MainMenu.uss | 255 ++++++++ Assets/UI/MainMenu.uxml | 31 + Assets/UI/ScreenFrame.uxml.meta | 10 + ProjectSettings/PackageManagerSettings.asset | 42 ++ ProjectSettings/ProjectSettings.asset | 5 +- gacha.md | 337 +++++++++++ 56 files changed, 2442 insertions(+), 30 deletions(-) create mode 100644 Assets/Data/Cards.meta create mode 100644 Assets/Data/Cards/CardDatabase.asset.meta create mode 100644 Assets/Data/Cards/Fedora.meta create mode 100644 Assets/Data/Cards/Fedora/BorrowChecker.asset.meta create mode 100644 Assets/Data/Cards/Fedora/CargoBuildRelease.asset.meta create mode 100644 Assets/Data/Cards/Fedora/DnfUpdate.asset.meta create mode 100644 Assets/Data/Cards/Fedora/Rawhide.asset.meta create mode 100644 Assets/Data/Cards/Fedora/SELinuxEnforcing.asset.meta create mode 100644 Assets/Data/Cards/Mint.meta create mode 100644 Assets/Data/Cards/Mint/Cinnamon.asset.meta create mode 100644 Assets/Data/Cards/Mint/FixBroken.asset.meta create mode 100644 Assets/Data/Cards/Mint/Nemo.asset.meta create mode 100644 Assets/Data/Cards/Mint/TimeshiftSnapshot.asset.meta create mode 100644 Assets/Data/Cards/Mint/UpdateManager.asset.meta create mode 100644 Assets/Data/Cards/Ubuntu.meta create mode 100644 Assets/Data/Cards/Ubuntu/AskUbuntu.asset.meta create mode 100644 Assets/Data/Cards/Ubuntu/DoReleaseUpgrade.asset.meta create mode 100644 Assets/Data/Cards/Ubuntu/SnapInstall.asset.meta create mode 100644 Assets/Data/Cards/Ubuntu/SudoAptInstall.asset.meta create mode 100644 Assets/Data/Cards/Ubuntu/UbuntuProTrial.asset.meta create mode 100644 Assets/Data/Cards/Ubuntu/UnattendedUpgrades.asset.meta create mode 100644 Assets/Data/Passives.meta create mode 100644 Assets/Data/Passives/AptUpdate.asset.meta create mode 100644 Assets/Data/Passives/BleedingEdge.asset.meta create mode 100644 Assets/Data/Passives/ItJustWorks.asset.meta create mode 100644 Assets/Scenes/FightScene.unity.meta create mode 100644 Assets/Scenes/GamblingScene.unity.meta create mode 100644 Assets/Scripts/Data/CardDatabase.cs.meta create mode 100644 Assets/Scripts/Data/PassiveDefinition.cs.meta create mode 100644 Assets/Scripts/Meta/CardLoadout.cs.meta create mode 100644 Assets/Scripts/Meta/GachaBannerState.cs create mode 100644 Assets/Scripts/Meta/GachaBannerState.cs.meta create mode 100644 Assets/Scripts/Meta/GachaCurrencyType.cs create mode 100644 Assets/Scripts/Meta/GachaCurrencyType.cs.meta create mode 100644 Assets/Scripts/Meta/GachaRewardType.cs create mode 100644 Assets/Scripts/Meta/GachaRewardType.cs.meta create mode 100644 Assets/Scripts/UI/CollectionScreenController.cs.meta create mode 100644 Assets/Scripts/UI/CommandKeyBindings.cs.meta create mode 100644 Assets/Scripts/UI/DistroPresentation.cs.meta create mode 100644 Assets/Scripts/UI/GachaScreenController.cs create mode 100644 Assets/Scripts/UI/GachaScreenController.cs.meta create mode 100644 Assets/Scripts/UI/ScreenFrameController.cs.meta create mode 100644 Assets/Scripts/UI/StarterSelectionController.cs.meta create mode 100644 Assets/UI/ScreenFrame.uxml.meta create mode 100644 ProjectSettings/PackageManagerSettings.asset create mode 100644 gacha.md diff --git a/Assets/Data/Cards.meta b/Assets/Data/Cards.meta new file mode 100644 index 0000000..a587697 --- /dev/null +++ b/Assets/Data/Cards.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 15501d6fecab8d6c39720f46b2644bc9 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/CardDatabase.asset.meta b/Assets/Data/Cards/CardDatabase.asset.meta new file mode 100644 index 0000000..7e4898d --- /dev/null +++ b/Assets/Data/Cards/CardDatabase.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1632132e32bfc31e8a293140f5908aa3 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Fedora.meta b/Assets/Data/Cards/Fedora.meta new file mode 100644 index 0000000..44c21c7 --- /dev/null +++ b/Assets/Data/Cards/Fedora.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 04f09e15db30a0756af561fca255e85b +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Fedora/BorrowChecker.asset.meta b/Assets/Data/Cards/Fedora/BorrowChecker.asset.meta new file mode 100644 index 0000000..6819725 --- /dev/null +++ b/Assets/Data/Cards/Fedora/BorrowChecker.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 4dfd40ca206341ba9a1a486d69994611 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Fedora/CargoBuildRelease.asset.meta b/Assets/Data/Cards/Fedora/CargoBuildRelease.asset.meta new file mode 100644 index 0000000..8828ae0 --- /dev/null +++ b/Assets/Data/Cards/Fedora/CargoBuildRelease.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 11e141b975f8ab190abf6c267067b575 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Fedora/DnfUpdate.asset.meta b/Assets/Data/Cards/Fedora/DnfUpdate.asset.meta new file mode 100644 index 0000000..35b9a5d --- /dev/null +++ b/Assets/Data/Cards/Fedora/DnfUpdate.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b6e048c6b94f10920a31d4c7069ba20f +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Fedora/Rawhide.asset.meta b/Assets/Data/Cards/Fedora/Rawhide.asset.meta new file mode 100644 index 0000000..f9a44be --- /dev/null +++ b/Assets/Data/Cards/Fedora/Rawhide.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 856019cbd78921a9c8846de8f81029b2 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Fedora/SELinuxEnforcing.asset.meta b/Assets/Data/Cards/Fedora/SELinuxEnforcing.asset.meta new file mode 100644 index 0000000..85ba5c9 --- /dev/null +++ b/Assets/Data/Cards/Fedora/SELinuxEnforcing.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 361650f1e83cad1119b747d294991569 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Mint.meta b/Assets/Data/Cards/Mint.meta new file mode 100644 index 0000000..724d856 --- /dev/null +++ b/Assets/Data/Cards/Mint.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 99cfb62a9ed9a6566aec84be75999c1f +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Mint/Cinnamon.asset.meta b/Assets/Data/Cards/Mint/Cinnamon.asset.meta new file mode 100644 index 0000000..f235e33 --- /dev/null +++ b/Assets/Data/Cards/Mint/Cinnamon.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 3cc3bbc086d6f0d3199af9094f9912d2 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Mint/FixBroken.asset.meta b/Assets/Data/Cards/Mint/FixBroken.asset.meta new file mode 100644 index 0000000..79a5980 --- /dev/null +++ b/Assets/Data/Cards/Mint/FixBroken.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7b5e9a8f7e3bb8eb6865533dd2b9af2f +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Mint/Nemo.asset.meta b/Assets/Data/Cards/Mint/Nemo.asset.meta new file mode 100644 index 0000000..5431f36 --- /dev/null +++ b/Assets/Data/Cards/Mint/Nemo.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 89c59c54d4bce36aaa836cfdc43f3c9f +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Mint/TimeshiftSnapshot.asset.meta b/Assets/Data/Cards/Mint/TimeshiftSnapshot.asset.meta new file mode 100644 index 0000000..83e1efc --- /dev/null +++ b/Assets/Data/Cards/Mint/TimeshiftSnapshot.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 07d51e6f24485d6aa9dfe38424e318ea +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Mint/UpdateManager.asset.meta b/Assets/Data/Cards/Mint/UpdateManager.asset.meta new file mode 100644 index 0000000..c64e516 --- /dev/null +++ b/Assets/Data/Cards/Mint/UpdateManager.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: f3cf77257a59a88518167e7e19023304 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Ubuntu.meta b/Assets/Data/Cards/Ubuntu.meta new file mode 100644 index 0000000..2590df5 --- /dev/null +++ b/Assets/Data/Cards/Ubuntu.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: caab84daf052361ab87b05d78d72eb4a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Ubuntu/AskUbuntu.asset.meta b/Assets/Data/Cards/Ubuntu/AskUbuntu.asset.meta new file mode 100644 index 0000000..aba1c03 --- /dev/null +++ b/Assets/Data/Cards/Ubuntu/AskUbuntu.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 9347bcc42fb6834f1907a2c0b661ff95 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Ubuntu/DoReleaseUpgrade.asset.meta b/Assets/Data/Cards/Ubuntu/DoReleaseUpgrade.asset.meta new file mode 100644 index 0000000..8e53edd --- /dev/null +++ b/Assets/Data/Cards/Ubuntu/DoReleaseUpgrade.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1dbc28e480e52d97b9501262af30cc78 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Ubuntu/SnapInstall.asset.meta b/Assets/Data/Cards/Ubuntu/SnapInstall.asset.meta new file mode 100644 index 0000000..4df0ed6 --- /dev/null +++ b/Assets/Data/Cards/Ubuntu/SnapInstall.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 19c884fde6ba18438b976aa154a729df +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Ubuntu/SudoAptInstall.asset.meta b/Assets/Data/Cards/Ubuntu/SudoAptInstall.asset.meta new file mode 100644 index 0000000..87441ea --- /dev/null +++ b/Assets/Data/Cards/Ubuntu/SudoAptInstall.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 26d4526631046cf5aad90867da18ea81 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Ubuntu/UbuntuProTrial.asset.meta b/Assets/Data/Cards/Ubuntu/UbuntuProTrial.asset.meta new file mode 100644 index 0000000..240b298 --- /dev/null +++ b/Assets/Data/Cards/Ubuntu/UbuntuProTrial.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7819ca459d587093e942e1b497761d72 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Cards/Ubuntu/UnattendedUpgrades.asset.meta b/Assets/Data/Cards/Ubuntu/UnattendedUpgrades.asset.meta new file mode 100644 index 0000000..bcaf4fb --- /dev/null +++ b/Assets/Data/Cards/Ubuntu/UnattendedUpgrades.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: daae1c711cc8de216966b68adc63d240 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Passives.meta b/Assets/Data/Passives.meta new file mode 100644 index 0000000..7d5c01f --- /dev/null +++ b/Assets/Data/Passives.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 76021ac16bc24526cbdacf1909a7a0cf +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Passives/AptUpdate.asset.meta b/Assets/Data/Passives/AptUpdate.asset.meta new file mode 100644 index 0000000..d8e753c --- /dev/null +++ b/Assets/Data/Passives/AptUpdate.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 19deb73cec3d5dc42a5cc336222ce9df +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Passives/BleedingEdge.asset.meta b/Assets/Data/Passives/BleedingEdge.asset.meta new file mode 100644 index 0000000..75c6083 --- /dev/null +++ b/Assets/Data/Passives/BleedingEdge.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: ded62c69f70d38a49b21972d857df4e2 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Data/Passives/ItJustWorks.asset.meta b/Assets/Data/Passives/ItJustWorks.asset.meta new file mode 100644 index 0000000..5eeb292 --- /dev/null +++ b/Assets/Data/Passives/ItJustWorks.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d97481a7d54be2045a96165d3977c980 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/DefaultVolumeProfile.asset b/Assets/DefaultVolumeProfile.asset index 0cd0e1a..8cea4d2 100644 --- a/Assets/DefaultVolumeProfile.asset +++ b/Assets/DefaultVolumeProfile.asset @@ -322,6 +322,9 @@ MonoBehaviour: highQualityFiltering: m_OverrideState: 1 m_Value: 0 + filter: + m_OverrideState: 1 + m_Value: 0 downscale: m_OverrideState: 1 m_Value: 0 diff --git a/Assets/Scenes/FightScene.unity.meta b/Assets/Scenes/FightScene.unity.meta new file mode 100644 index 0000000..b8f5e19 --- /dev/null +++ b/Assets/Scenes/FightScene.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e9acb3a424fb6f8bfada39dfd8292a93 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/GamblingScene.unity.meta b/Assets/Scenes/GamblingScene.unity.meta new file mode 100644 index 0000000..8bf6f0f --- /dev/null +++ b/Assets/Scenes/GamblingScene.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d10c95dab567850aaad42c0c5c999dde +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Data/CardDatabase.cs.meta b/Assets/Scripts/Data/CardDatabase.cs.meta new file mode 100644 index 0000000..2c4d5fb --- /dev/null +++ b/Assets/Scripts/Data/CardDatabase.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: fd9e459379f339742a14cf224cd91234 diff --git a/Assets/Scripts/Data/PassiveDefinition.cs.meta b/Assets/Scripts/Data/PassiveDefinition.cs.meta new file mode 100644 index 0000000..1faf515 --- /dev/null +++ b/Assets/Scripts/Data/PassiveDefinition.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9b1f51fb7c354203a2f93ad22fbeb101 diff --git a/Assets/Scripts/Meta/CardLoadout.cs.meta b/Assets/Scripts/Meta/CardLoadout.cs.meta new file mode 100644 index 0000000..44bca39 --- /dev/null +++ b/Assets/Scripts/Meta/CardLoadout.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: e003476e8a28025938acf6c377dfbaaa \ No newline at end of file diff --git a/Assets/Scripts/Meta/EntropyWallet.cs b/Assets/Scripts/Meta/EntropyWallet.cs index 83aa4db..b59e6f2 100644 --- a/Assets/Scripts/Meta/EntropyWallet.cs +++ b/Assets/Scripts/Meta/EntropyWallet.cs @@ -7,6 +7,11 @@ namespace KernelPanic.Meta { public int Balance { get; private set; } + public void SetBalance(int amount) + { + Balance = amount < 0 ? 0 : amount; + } + public void Add(int amount) { Balance += amount; diff --git a/Assets/Scripts/Meta/GachaBannerState.cs b/Assets/Scripts/Meta/GachaBannerState.cs new file mode 100644 index 0000000..567191a --- /dev/null +++ b/Assets/Scripts/Meta/GachaBannerState.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; + +namespace KernelPanic.Meta +{ + /// + /// Stores per-banner counters that must persist between sessions. + /// + [Serializable] + public sealed class GachaBannerState + { + public string bannerId; + public int totalPulls; + public int pityCounter; + public int fiveStarPityCounter; + public bool exhausted; + public bool featuredFiveStarGuaranteed; + public List guaranteedDistroIds = new(); + + public GachaBannerState() + { + } + + public GachaBannerState(string bannerId) + { + this.bannerId = bannerId; + } + + public void EnsureLists() + { + guaranteedDistroIds ??= new List(); + } + } +} diff --git a/Assets/Scripts/Meta/GachaBannerState.cs.meta b/Assets/Scripts/Meta/GachaBannerState.cs.meta new file mode 100644 index 0000000..9c3861a --- /dev/null +++ b/Assets/Scripts/Meta/GachaBannerState.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 29d7890153d140b2a25b1afb304581f9 diff --git a/Assets/Scripts/Meta/GachaCurrencyType.cs b/Assets/Scripts/Meta/GachaCurrencyType.cs new file mode 100644 index 0000000..4023677 --- /dev/null +++ b/Assets/Scripts/Meta/GachaCurrencyType.cs @@ -0,0 +1,11 @@ +namespace KernelPanic.Meta +{ + /// + /// Identifies currencies spent on banner pulls. + /// + public enum GachaCurrencyType + { + StandardPull, + LimitedPull + } +} diff --git a/Assets/Scripts/Meta/GachaCurrencyType.cs.meta b/Assets/Scripts/Meta/GachaCurrencyType.cs.meta new file mode 100644 index 0000000..75e843f --- /dev/null +++ b/Assets/Scripts/Meta/GachaCurrencyType.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 7262840a6d0b4569a70ca757cf4b5d19 diff --git a/Assets/Scripts/Meta/GachaRewardType.cs b/Assets/Scripts/Meta/GachaRewardType.cs new file mode 100644 index 0000000..a7dce16 --- /dev/null +++ b/Assets/Scripts/Meta/GachaRewardType.cs @@ -0,0 +1,12 @@ +namespace KernelPanic.Meta +{ + /// + /// Describes the persistent reward category produced by a gacha pull. + /// + public enum GachaRewardType + { + Equipment, + Distro, + FutureStandardFiveStarDistro + } +} diff --git a/Assets/Scripts/Meta/GachaRewardType.cs.meta b/Assets/Scripts/Meta/GachaRewardType.cs.meta new file mode 100644 index 0000000..ac7c9b9 --- /dev/null +++ b/Assets/Scripts/Meta/GachaRewardType.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 6ef2e97a60574b3896db93fd09ec5313 diff --git a/Assets/Scripts/Meta/GachaService.cs b/Assets/Scripts/Meta/GachaService.cs index 4236f45..438b173 100644 --- a/Assets/Scripts/Meta/GachaService.cs +++ b/Assets/Scripts/Meta/GachaService.cs @@ -5,16 +5,150 @@ using KernelPanic.Data; namespace KernelPanic.Meta { /// - /// Provides the contract for spending entropy on persistent unlock pulls. + /// Provides persistent banner pull logic and currency accounting. /// public sealed class GachaService { - private readonly List bannerPool = new(); + public const string BeginnerBannerId = "beginner"; + public const string StandardBannerId = "standard"; + public const string LimitedBannerId = "limited"; + public const int BeginnerMaxPulls = 50; + public const int BeginnerSinglePullCost = 1; + public const int BeginnerTenPullCost = 8; + public const int FourStarHardPity = 10; + public const int FiveStarSoftPityStart = 66; + public const int FiveStarHardPity = 80; + public const int EntropyPerPullToken = 100; - public int PullTokens => 0; // TODO: Replace with the real pull-token wallet when that meta system exists. + private const double FourStarBaseChance = 0.12d; + private const double FiveStarBaseChance = 0.008d; + private const double FiveStarSoftPityStep = 0.07d; + private const double DistroChanceOnFeaturedTier = 0.5d; + private const double LimitedStandardFiveStarChance = 1d / 3d; + + private readonly List bannerPool = new(); + private readonly Dictionary currencyBalances = new(); + private readonly Random random; + private GachaBannerState beginnerState = new(BeginnerBannerId); + + public GachaService() + : this(new Random()) + { + } + + public GachaService(Random random) + { + this.random = random ?? new Random(); + currencyBalances[GachaCurrencyType.StandardPull] = 0; + currencyBalances[GachaCurrencyType.LimitedPull] = 0; + } + + public int PullTokens => GetCurrencyBalance(GachaCurrencyType.StandardPull); + public int LimitedPullTokens => GetCurrencyBalance(GachaCurrencyType.LimitedPull); + public int RootCredits { get; private set; } public IReadOnlyList BannerPool => bannerPool; + public GachaBannerState BeginnerState => beginnerState; + public bool IsBeginnerBannerAvailable => !beginnerState.exhausted && beginnerState.totalPulls < BeginnerMaxPulls && bannerPool.Count > 0; public event Action BannerPoolChanged; + public event Action Changed; + + public void LoadProgress(SaveData data) + { + if (data == null) + { + return; + } + + data.EnsureLists(); + RootCredits = Math.Max(0, data.rootCredits); + SetCurrencyBalanceSilently(GachaCurrencyType.StandardPull, data.standardPullCurrency); + SetCurrencyBalanceSilently(GachaCurrencyType.LimitedPull, data.limitedPullCurrency); + beginnerState = data.beginnerBannerState ?? new GachaBannerState(BeginnerBannerId); + beginnerState.bannerId = BeginnerBannerId; + beginnerState.EnsureLists(); + if (beginnerState.totalPulls >= BeginnerMaxPulls) + { + beginnerState.exhausted = true; + } + + beginnerState.fiveStarPityCounter = Math.Max(0, beginnerState.fiveStarPityCounter); + + Changed?.Invoke(); + } + + public void WriteProgress(SaveData data) + { + if (data == null) + { + return; + } + + data.EnsureLists(); + data.rootCredits = RootCredits; + data.standardPullCurrency = GetCurrencyBalance(GachaCurrencyType.StandardPull); + data.limitedPullCurrency = GetCurrencyBalance(GachaCurrencyType.LimitedPull); + data.beginnerBannerState = CloneState(beginnerState); + } + + public int GetCurrencyBalance(GachaCurrencyType currencyType) + { + return currencyBalances.TryGetValue(currencyType, out int balance) ? balance : 0; + } + + public void SetCurrencyBalance(GachaCurrencyType currencyType, int amount) + { + SetCurrencyBalanceSilently(currencyType, amount); + Changed?.Invoke(); + } + + public void AddCurrency(GachaCurrencyType currencyType, int amount) + { + if (amount <= 0) + { + return; + } + + SetCurrencyBalance(currencyType, GetCurrencyBalance(currencyType) + amount); + } + + public void AddRootCredits(int amount) + { + if (amount <= 0) + { + return; + } + + RootCredits += amount; + Changed?.Invoke(); + } + + public bool ConvertRootCreditsToEntropy(EntropyWallet wallet, int amount, out string failureReason) + { + if (wallet == null) + { + failureReason = "entropy wallet unavailable"; + return false; + } + + if (amount <= 0) + { + failureReason = "no root-credits selected"; + return false; + } + + if (RootCredits < amount) + { + failureReason = $"need {amount} root-credits"; + return false; + } + + RootCredits -= amount; + wallet.Add(amount); + failureReason = null; + Changed?.Invoke(); + return true; + } public void AddToBannerPool(DistroDefinition distro) { @@ -25,26 +159,446 @@ namespace KernelPanic.Meta bannerPool.Add(distro); BannerPoolChanged?.Invoke(); + Changed?.Invoke(); + } + + public void SetBeginnerGuaranteedDistros(IReadOnlyList distros) + { + beginnerState.guaranteedDistroIds.Clear(); + if (distros != null) + { + for (int i = 0; i < distros.Count; i++) + { + DistroDefinition distro = distros[i]; + if (distro != null && !string.IsNullOrWhiteSpace(distro.Id)) + { + beginnerState.guaranteedDistroIds.Add(distro.Id); + } + } + } + + Changed?.Invoke(); + } + + public int GetBeginnerPullCost(int pullCount) + { + return pullCount == 10 ? BeginnerTenPullCost : BeginnerSinglePullCost; + } + + public bool CanPullBeginner(int pullCount, out string failureReason) + { + if (pullCount != 1 && pullCount != 10) + { + failureReason = "only single and ten pulls are supported"; + return false; + } + + if (!IsBeginnerBannerAvailable) + { + failureReason = "beginner banner unavailable"; + return false; + } + + int remainingPulls = BeginnerMaxPulls - beginnerState.totalPulls; + if (pullCount > remainingPulls) + { + failureReason = $"only {remainingPulls} beginner pull(s) remain"; + return false; + } + + int cost = GetBeginnerPullCost(pullCount); + if (GetCurrencyBalance(GachaCurrencyType.StandardPull) < cost) + { + failureReason = $"need {cost} {FormatCurrencyName(GachaCurrencyType.StandardPull)}"; + return false; + } + + failureReason = null; + return true; + } + + public int GetMissingPullTokens(GachaCurrencyType currencyType, int pullCost) + { + return Math.Max(0, pullCost - GetCurrencyBalance(currencyType)); + } + + public bool CanCoverMissingPullTokensWithEntropy(EntropyWallet wallet, int missingPullTokens) + { + return missingPullTokens <= 0 || (wallet != null && wallet.Balance >= missingPullTokens * EntropyPerPullToken); + } + + public GachaPullResult PerformBeginnerPull(int pullCount) + { + return PerformBeginnerPull(pullCount, null, 0); + } + + public GachaPullResult PerformBeginnerPull(int pullCount, EntropyWallet wallet, int entropyTokenCount) + { + if (!CanPullBeginnerWithEntropy(pullCount, wallet, entropyTokenCount, out string failureReason)) + { + return GachaPullResult.Failed(BeginnerBannerId, failureReason); + } + + int cost = GetBeginnerPullCost(pullCount); + int tokenSpend = cost - entropyTokenCount; + if (tokenSpend > 0) + { + SetCurrencyBalanceSilently(GachaCurrencyType.StandardPull, GetCurrencyBalance(GachaCurrencyType.StandardPull) - tokenSpend); + } + + int entropySpent = entropyTokenCount * EntropyPerPullToken; + if (entropySpent > 0) + { + wallet.Spend(entropySpent); + } + + List rewards = new(); + for (int i = 0; i < pullCount; i++) + { + beginnerState.totalPulls++; + rewards.Add(RollBeginnerReward(beginnerState.totalPulls)); + } + + if (beginnerState.totalPulls >= BeginnerMaxPulls) + { + beginnerState.exhausted = true; + } + + Changed?.Invoke(); + return new GachaPullResult(true, BeginnerBannerId, GachaCurrencyType.StandardPull, tokenSpend, entropySpent, rewards, null); + } + + public static string FormatCurrencyName(GachaCurrencyType currencyType) + { + return currencyType switch + { + GachaCurrencyType.LimitedPull => "feature-pull-token", + _ => "stable-pull-token" + }; + } + + public static double GetFiveStarChance(GachaBannerState state) + { + return GetFiveStarChance(state == null ? 0 : state.fiveStarPityCounter); + } + + public static double GetFiveStarChance(int fiveStarPityCounter) + { + int pityPullNumber = Math.Max(0, fiveStarPityCounter) + 1; + if (pityPullNumber >= FiveStarHardPity) + { + return 1d; + } + + if (pityPullNumber < FiveStarSoftPityStart) + { + return FiveStarBaseChance; + } + + int softPitySteps = pityPullNumber - FiveStarSoftPityStart + 1; + return Math.Min(1d, FiveStarBaseChance + softPitySteps * FiveStarSoftPityStep); } public GachaPullResult PerformPull(EntropyWallet wallet, int cost) { - throw new NotImplementedException(); + return PerformBeginnerPull(1); + } + + private GachaReward RollBeginnerReward(int pullNumber) + { + if (pullNumber == 20) + { + AdvanceFiveStarPityAfterNonFiveStar(beginnerState); + return RewardGuaranteedBeginnerDistro(0, "20-pull starter guarantee"); + } + + if (pullNumber == 40) + { + AdvanceFiveStarPityAfterNonFiveStar(beginnerState); + return RewardGuaranteedBeginnerDistro(1, "40-pull starter guarantee"); + } + + if (pullNumber == 50) + { + beginnerState.pityCounter = 0; + return GachaReward.FutureStandardFiveStar("future standard 5-star distro", "50-pull beginner capstone"); + } + + if (TryRollFiveStar(beginnerState, out bool fiveStarPityTriggered)) + { + return RewardRandomFiveStar(fiveStarPityTriggered); + } + + bool pityTriggered = beginnerState.pityCounter >= FourStarHardPity - 1; + bool hitFourStarOrCharacter = pityTriggered || random.NextDouble() < FourStarBaseChance; + if (!hitFourStarOrCharacter) + { + beginnerState.pityCounter++; + return GachaReward.Equipment(3, "3-star equipment", false, false); + } + + beginnerState.pityCounter = 0; + if (bannerPool.Count > 0 && random.NextDouble() < DistroChanceOnFeaturedTier) + { + DistroDefinition distro = bannerPool[random.Next(bannerPool.Count)]; + return GachaReward.DistroReward(distro, 4, pityTriggered, false); + } + + return GachaReward.Equipment(4, "4-star equipment", pityTriggered, false); + } + + private bool TryRollFiveStar(GachaBannerState state, out bool pityTriggered) + { + state ??= beginnerState; + int pityPullNumber = Math.Max(0, state.fiveStarPityCounter) + 1; + pityTriggered = pityPullNumber >= FiveStarSoftPityStart; + + double chance = GetFiveStarChance(state); + bool hit = chance >= 1d || random.NextDouble() < chance; + if (!hit) + { + state.fiveStarPityCounter++; + return false; + } + + state.fiveStarPityCounter = 0; + state.pityCounter = 0; + return true; + } + + private static void AdvanceFiveStarPityAfterNonFiveStar(GachaBannerState state) + { + if (state != null) + { + state.fiveStarPityCounter++; + } + } + + private GachaReward RewardRandomFiveStar(bool pityTriggered) + { + if (bannerPool.Count == 0 || random.NextDouble() >= DistroChanceOnFeaturedTier) + { + return GachaReward.Equipment(5, "5-star equipment", pityTriggered, false); + } + + DistroDefinition distro = bannerPool.Count == 0 ? null : bannerPool[random.Next(bannerPool.Count)]; + return GachaReward.DistroReward(distro, 5, pityTriggered, false); + } + + public bool ResolveFeaturedTierIsDistro() + { + return random.NextDouble() < DistroChanceOnFeaturedTier; + } + + public bool ResolveLimitedFiveStarUsesStandardPool(GachaBannerState limitedState) + { + if (limitedState == null) + { + return false; + } + + if (limitedState.featuredFiveStarGuaranteed) + { + limitedState.featuredFiveStarGuaranteed = false; + return false; + } + + bool useStandardPool = random.NextDouble() < LimitedStandardFiveStarChance; + limitedState.featuredFiveStarGuaranteed = useStandardPool; + return useStandardPool; + } + + private GachaReward RewardGuaranteedBeginnerDistro(int guaranteeIndex, string reason) + { + beginnerState.pityCounter = 0; + DistroDefinition distro = null; + if (guaranteeIndex >= 0 && guaranteeIndex < beginnerState.guaranteedDistroIds.Count) + { + distro = FindBannerPoolDistro(beginnerState.guaranteedDistroIds[guaranteeIndex]); + } + + distro ??= bannerPool.Count == 0 ? null : bannerPool[Math.Min(guaranteeIndex, bannerPool.Count - 1)]; + return distro == null + ? GachaReward.Equipment(4, "4-star equipment", true, true) + : GachaReward.DistroReward(distro, 4, true, true, reason); + } + + private DistroDefinition FindBannerPoolDistro(string id) + { + if (string.IsNullOrWhiteSpace(id)) + { + return null; + } + + for (int i = 0; i < bannerPool.Count; i++) + { + DistroDefinition distro = bannerPool[i]; + if (distro != null && string.Equals(distro.Id, id, StringComparison.OrdinalIgnoreCase)) + { + return distro; + } + } + + return null; + } + + private void SetCurrencyBalanceSilently(GachaCurrencyType currencyType, int amount) + { + currencyBalances[currencyType] = Math.Max(0, amount); + } + + private bool CanPullBeginnerWithEntropy(int pullCount, EntropyWallet wallet, int entropyTokenCount, out string failureReason) + { + if (pullCount != 1 && pullCount != 10) + { + failureReason = "only single and ten pulls are supported"; + return false; + } + + if (!IsBeginnerBannerAvailable) + { + failureReason = "beginner banner unavailable"; + return false; + } + + int remainingPulls = BeginnerMaxPulls - beginnerState.totalPulls; + if (pullCount > remainingPulls) + { + failureReason = $"only {remainingPulls} beginner pull(s) remain"; + return false; + } + + int cost = GetBeginnerPullCost(pullCount); + if (entropyTokenCount < 0 || entropyTokenCount > cost) + { + failureReason = "invalid entropy substitute amount"; + return false; + } + + int tokenSpend = cost - entropyTokenCount; + if (GetCurrencyBalance(GachaCurrencyType.StandardPull) < tokenSpend) + { + failureReason = $"need {tokenSpend} {FormatCurrencyName(GachaCurrencyType.StandardPull)}"; + return false; + } + + int entropySpend = entropyTokenCount * EntropyPerPullToken; + if (entropySpend > 0 && (wallet == null || wallet.Balance < entropySpend)) + { + failureReason = $"need {entropySpend} entropy"; + return false; + } + + failureReason = null; + return true; + } + + private static GachaBannerState CloneState(GachaBannerState state) + { + state ??= new GachaBannerState(BeginnerBannerId); + state.EnsureLists(); + GachaBannerState clone = new(state.bannerId) + { + totalPulls = state.totalPulls, + pityCounter = state.pityCounter, + fiveStarPityCounter = state.fiveStarPityCounter, + exhausted = state.exhausted, + featuredFiveStarGuaranteed = state.featuredFiveStarGuaranteed + }; + clone.guaranteedDistroIds.AddRange(state.guaranteedDistroIds); + return clone; } } /// - /// Represents the result of a persistent unlock pull. + /// Describes one reward entry from one pull. + /// + public readonly struct GachaReward + { + private GachaReward( + GachaRewardType rewardType, + int starRating, + string displayName, + DistroDefinition distro, + bool pityTriggered, + bool guaranteed, + string guaranteeReason) + { + RewardType = rewardType; + StarRating = starRating; + DisplayName = displayName; + Distro = distro; + PityTriggered = pityTriggered; + Guaranteed = guaranteed; + GuaranteeReason = guaranteeReason; + } + + public GachaRewardType RewardType { get; } + public int StarRating { get; } + public string DisplayName { get; } + public DistroDefinition Distro { get; } + public bool PityTriggered { get; } + public bool Guaranteed { get; } + public string GuaranteeReason { get; } + + public static GachaReward Equipment(int starRating, string displayName, bool pityTriggered, bool guaranteed) + { + return new GachaReward(GachaRewardType.Equipment, starRating, displayName, null, pityTriggered, guaranteed, null); + } + + public static GachaReward DistroReward(DistroDefinition distro, int starRating, bool pityTriggered, bool guaranteed, string guaranteeReason = null) + { + string displayName = distro == null ? "unknown distro" : DistroDisplayName(distro); + return new GachaReward(GachaRewardType.Distro, starRating, displayName, distro, pityTriggered, guaranteed, guaranteeReason); + } + + public static GachaReward FutureStandardFiveStar(string displayName, string guaranteeReason) + { + return new GachaReward(GachaRewardType.FutureStandardFiveStarDistro, 5, displayName, null, true, true, guaranteeReason); + } + + private static string DistroDisplayName(DistroDefinition distro) + { + return string.IsNullOrWhiteSpace(distro.DisplayName) ? distro.name : distro.DisplayName; + } + } + + /// + /// Represents the result of a banner pull request. /// public readonly struct GachaPullResult { - public GachaPullResult(bool success, string unlockId) + public GachaPullResult( + bool success, + string bannerId, + GachaCurrencyType currencyType, + int currencySpent, + int entropySpent, + IReadOnlyList rewards, + string failureReason) { Success = success; - UnlockId = unlockId; + BannerId = bannerId; + CurrencyType = currencyType; + CurrencySpent = currencySpent; + EntropySpent = entropySpent; + Rewards = rewards ?? Array.Empty(); + FailureReason = failureReason; + UnlockId = Rewards.Count > 0 && Rewards[0].Distro != null ? Rewards[0].Distro.Id : null; } public bool Success { get; } + public string BannerId { get; } + public GachaCurrencyType CurrencyType { get; } + public int CurrencySpent { get; } + public int EntropySpent { get; } + public IReadOnlyList Rewards { get; } + public string FailureReason { get; } public string UnlockId { get; } + + public static GachaPullResult Failed(string bannerId, string reason) + { + return new GachaPullResult(false, bannerId, GachaCurrencyType.StandardPull, 0, 0, Array.Empty(), reason); + } } } diff --git a/Assets/Scripts/Meta/PlayerCollection.cs b/Assets/Scripts/Meta/PlayerCollection.cs index a39c10d..69d9959 100644 --- a/Assets/Scripts/Meta/PlayerCollection.cs +++ b/Assets/Scripts/Meta/PlayerCollection.cs @@ -13,7 +13,6 @@ namespace KernelPanic.Meta private int featuredIndex; // TODO: Populate owned units from SaveService during bootstrap. - // TODO: Add newly unlocked units from GachaService rewards when pulls exist. public IReadOnlyList OwnedUnits => ownedUnits; public DistroDefinition FeaturedUnit => ownedUnits.Count == 0 ? null : ownedUnits[Math.Clamp(featuredIndex, 0, ownedUnits.Count - 1)]; @@ -21,7 +20,7 @@ namespace KernelPanic.Meta public void Add(DistroDefinition unit) { - if (unit == null || ownedUnits.Contains(unit)) + if (unit == null) { return; } @@ -32,6 +31,26 @@ namespace KernelPanic.Meta Changed?.Invoke(); } + public int GetOwnedCount(string unitId) + { + if (string.IsNullOrWhiteSpace(unitId)) + { + return 0; + } + + int count = 0; + for (int i = 0; i < ownedUnits.Count; i++) + { + DistroDefinition unit = ownedUnits[i]; + if (unit != null && string.Equals(unit.Id, unitId, StringComparison.OrdinalIgnoreCase)) + { + count++; + } + } + + return count; + } + public void SelectNextFeatured() { if (ownedUnits.Count < 2) diff --git a/Assets/Scripts/Meta/SaveService.cs b/Assets/Scripts/Meta/SaveService.cs index 3aa4ae2..62d5f8c 100644 --- a/Assets/Scripts/Meta/SaveService.cs +++ b/Assets/Scripts/Meta/SaveService.cs @@ -58,8 +58,13 @@ namespace KernelPanic.Meta public sealed class SaveData { public bool starterChosen; + public int entropyBalance; + public int rootCredits; + public int standardPullCurrency; + public int limitedPullCurrency; public List ownedUnitIds = new(); public List bannerPoolIds = new(); + public GachaBannerState beginnerBannerState = new(GachaService.BeginnerBannerId); public LastRunLoadoutSaveEntry lastRunLoadout = new(); public static SaveData CreateDefault() @@ -71,6 +76,9 @@ namespace KernelPanic.Meta { ownedUnitIds ??= new List(); bannerPoolIds ??= new List(); + beginnerBannerState ??= new GachaBannerState(GachaService.BeginnerBannerId); + beginnerBannerState.bannerId = GachaService.BeginnerBannerId; + beginnerBannerState.EnsureLists(); lastRunLoadout ??= new LastRunLoadoutSaveEntry(); lastRunLoadout.EnsureLists(); } diff --git a/Assets/Scripts/UI/CollectionScreenController.cs.meta b/Assets/Scripts/UI/CollectionScreenController.cs.meta new file mode 100644 index 0000000..6cf970f --- /dev/null +++ b/Assets/Scripts/UI/CollectionScreenController.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: c6c581de5a6bcbc73a451ce3906547bc \ No newline at end of file diff --git a/Assets/Scripts/UI/CommandKeyBindings.cs.meta b/Assets/Scripts/UI/CommandKeyBindings.cs.meta new file mode 100644 index 0000000..d3ce261 --- /dev/null +++ b/Assets/Scripts/UI/CommandKeyBindings.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 73880a4e893003d719622694aa5ffc02 \ No newline at end of file diff --git a/Assets/Scripts/UI/DistroPresentation.cs.meta b/Assets/Scripts/UI/DistroPresentation.cs.meta new file mode 100644 index 0000000..0d31d51 --- /dev/null +++ b/Assets/Scripts/UI/DistroPresentation.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 4b02ec0c6f7df1d3aa8211567c3ec2a3 \ No newline at end of file diff --git a/Assets/Scripts/UI/GachaScreenController.cs b/Assets/Scripts/UI/GachaScreenController.cs new file mode 100644 index 0000000..5f06901 --- /dev/null +++ b/Assets/Scripts/UI/GachaScreenController.cs @@ -0,0 +1,487 @@ +using System; +using System.Collections.Generic; +using KernelPanic.Data; +using KernelPanic.Meta; +using UnityEngine; +using UnityEngine.TextCore.Text; +using UnityEngine.UIElements; + +namespace KernelPanic.UI +{ + /// + /// Renders banner selection and pull controls for the gacha screen. + /// + [Serializable] + public sealed class GachaScreenController + { + private const string SelectedClassName = "selected"; + + private readonly List bannerRows = new(); + private readonly string[] bannerIds = + { + GachaService.BeginnerBannerId, + GachaService.StandardBannerId, + GachaService.LimitedBannerId + }; + + private VisualElement bannerList; + private VisualElement bannerDetail; + private DistroDatabase distroDatabase; + private FontAsset monospaceFont; + private GachaService gachaService; + private PlayerCollection playerCollection; + private EntropyWallet wallet; + private Action onChanged; + private Action requestRootCreditExchange; + private int selectedBannerIndex; + private int pendingPullCount; + private int pendingMissingTokens; + private bool hasOpened; + private string resultBannerId; + private string resultText; + + public void Bind(VisualElement root, DistroDatabase database, FontAsset artFont, GachaService service, PlayerCollection collection, EntropyWallet entropyWallet, Action changedCallback, Action rootCreditExchangeCallback) + { + distroDatabase = database; + monospaceFont = artFont; + gachaService = service; + playerCollection = collection; + wallet = entropyWallet; + onChanged = changedCallback; + requestRootCreditExchange = rootCreditExchangeCallback; + bannerList = root.Q("GachaBannerList"); + bannerDetail = root.Q("GachaBannerDetail"); + } + + public void Open() + { + if (!hasOpened) + { + selectedBannerIndex = 0; + hasOpened = true; + } + + Refresh(); + } + + public void Refresh() + { + if (bannerList == null || bannerDetail == null || gachaService == null) + { + return; + } + + bannerRows.Clear(); + bannerList.Clear(); + + for (int i = 0; i < bannerIds.Length; i++) + { + int index = i; + VisualElement row = BuildBannerRow(bannerIds[i]); + row.RegisterCallback(_ => SelectBanner(index)); + bannerList.Add(row); + bannerRows.Add(row); + } + + selectedBannerIndex = Mathf.Clamp(selectedBannerIndex, 0, bannerRows.Count - 1); + ApplySelectedBanner(); + } + + public void HandleKeyDown(KeyDownEvent evt) + { + // Pulls are deliberately click-only to avoid accidental currency spend. + } + + private VisualElement BuildBannerRow(string bannerId) + { + VisualElement row = new(); + row.AddToClassList("gacha-banner-row"); + + row.Add(new Label(">") { name = $"GachaBannerCursor_{bannerId}" }); + row.ElementAt(0).AddToClassList("command-cursor"); + + row.Add(new Label(GetBannerTitle(bannerId)) { name = $"GachaBannerName_{bannerId}" }); + row.ElementAt(1).AddToClassList("command-text"); + + row.Add(new Label(GetBannerStatus(bannerId)) { name = $"GachaBannerStatus_{bannerId}" }); + row.ElementAt(2).AddToClassList("command-description"); + + return row; + } + + private void SelectBanner(int index) + { + if (bannerRows.Count == 0) + { + return; + } + + selectedBannerIndex = (index + bannerRows.Count) % bannerRows.Count; + ApplySelectedBanner(); + } + + private void ApplySelectedBanner() + { + for (int i = 0; i < bannerRows.Count; i++) + { + bool selected = i == selectedBannerIndex; + bannerRows[i].EnableInClassList(SelectedClassName, selected); + bannerRows[i].Q