From 2fc8a05617806b4e181a24ca4927f59036e05021 Mon Sep 17 00:00:00 2001 From: fretuks Date: Fri, 3 Jul 2026 13:59:00 +0200 Subject: [PATCH] implement main screen --- Assets/Scenes/GameScene.unity | 231 +++++++++ Assets/Scenes/GameScene.unity.meta | 7 + ...{SampleScene.unity => MainMenuScene.unity} | 132 ++--- ...ne.unity.meta => MainMenuScene.unity.meta} | 0 Assets/Scripts/Core/SceneLoader.cs | 30 ++ Assets/Scripts/Core/SceneLoader.cs.meta | 11 + Assets/Scripts/Data/DistroDefinition.cs | 4 + Assets/Scripts/Meta/GachaService.cs | 2 + Assets/Scripts/Meta/IEventBannerSource.cs | 27 ++ .../Scripts/Meta/IEventBannerSource.cs.meta | 11 + Assets/Scripts/UI.meta | 8 + Assets/Scripts/UI/BootLogCopy.cs | 22 + Assets/Scripts/UI/BootLogCopy.cs.meta | 11 + Assets/Scripts/UI/FeaturedUnitPanel.cs | 108 +++++ Assets/Scripts/UI/FeaturedUnitPanel.cs.meta | 11 + Assets/Scripts/UI/MainMenuController.cs | 454 ++++++++++++++++++ Assets/Scripts/UI/MainMenuController.cs.meta | 11 + Assets/Scripts/UI/UIPreferences.cs | 10 + Assets/Scripts/UI/UIPreferences.cs.meta | 11 + Assets/UI.meta | 8 + Assets/UI/CollectionScreen.uxml | 10 + Assets/UI/CollectionScreen.uxml.meta | 10 + Assets/UI/GachaScreen.uxml | 9 + Assets/UI/GachaScreen.uxml.meta | 10 + Assets/UI/MainMenu.uss | 356 ++++++++++++++ Assets/UI/MainMenu.uss.meta | 12 + Assets/UI/MainMenu.uxml | 111 +++++ Assets/UI/MainMenu.uxml.meta | 10 + Assets/UI/MainMenuPanelSettings.asset | 43 ++ Assets/UI/MainMenuPanelSettings.asset.meta | 8 + Assets/UI/SettingsScreen.uxml | 10 + Assets/UI/SettingsScreen.uxml.meta | 10 + Assets/UI/UnityDefaultRuntimeTheme.tss | 2 + Assets/UI/UnityDefaultRuntimeTheme.tss.meta | 11 + ProjectSettings/EditorBuildSettings.asset | 5 +- 35 files changed, 1637 insertions(+), 89 deletions(-) create mode 100644 Assets/Scenes/GameScene.unity create mode 100644 Assets/Scenes/GameScene.unity.meta rename Assets/Scenes/{SampleScene.unity => MainMenuScene.unity} (72%) rename Assets/Scenes/{SampleScene.unity.meta => MainMenuScene.unity.meta} (100%) create mode 100644 Assets/Scripts/Core/SceneLoader.cs create mode 100644 Assets/Scripts/Core/SceneLoader.cs.meta create mode 100644 Assets/Scripts/Meta/IEventBannerSource.cs create mode 100644 Assets/Scripts/Meta/IEventBannerSource.cs.meta create mode 100644 Assets/Scripts/UI.meta create mode 100644 Assets/Scripts/UI/BootLogCopy.cs create mode 100644 Assets/Scripts/UI/BootLogCopy.cs.meta create mode 100644 Assets/Scripts/UI/FeaturedUnitPanel.cs create mode 100644 Assets/Scripts/UI/FeaturedUnitPanel.cs.meta create mode 100644 Assets/Scripts/UI/MainMenuController.cs create mode 100644 Assets/Scripts/UI/MainMenuController.cs.meta create mode 100644 Assets/Scripts/UI/UIPreferences.cs create mode 100644 Assets/Scripts/UI/UIPreferences.cs.meta create mode 100644 Assets/UI.meta create mode 100644 Assets/UI/CollectionScreen.uxml create mode 100644 Assets/UI/CollectionScreen.uxml.meta create mode 100644 Assets/UI/GachaScreen.uxml create mode 100644 Assets/UI/GachaScreen.uxml.meta create mode 100644 Assets/UI/MainMenu.uss create mode 100644 Assets/UI/MainMenu.uss.meta create mode 100644 Assets/UI/MainMenu.uxml create mode 100644 Assets/UI/MainMenu.uxml.meta create mode 100644 Assets/UI/MainMenuPanelSettings.asset create mode 100644 Assets/UI/MainMenuPanelSettings.asset.meta create mode 100644 Assets/UI/SettingsScreen.uxml create mode 100644 Assets/UI/SettingsScreen.uxml.meta create mode 100644 Assets/UI/UnityDefaultRuntimeTheme.tss create mode 100644 Assets/UI/UnityDefaultRuntimeTheme.tss.meta diff --git a/Assets/Scenes/GameScene.unity b/Assets/Scenes/GameScene.unity new file mode 100644 index 0000000..68730bc --- /dev/null +++ b/Assets/Scenes/GameScene.unity @@ -0,0 +1,231 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 3 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 0} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 0 + m_EnableRealtimeLightmaps: 0 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + maxJobWorkers: 0 + preserveTilesOutsideBounds: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &100000 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 100004} + - component: {fileID: 100003} + - component: {fileID: 100001} + - component: {fileID: 100002} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &100001 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 100000} + m_Enabled: 1 +--- !u!114 &100002 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: a79441f348de89743a2939f4d699eac1, type: 3} + m_Name: + m_EditorClassIdentifier: + m_RenderShadows: 1 + m_RequiresDepthTextureOption: 2 + m_RequiresOpaqueTextureOption: 2 + m_CameraType: 0 + m_Cameras: [] + m_RendererIndex: -1 + m_VolumeLayerMask: + serializedVersion: 2 + m_Bits: 1 + m_VolumeTrigger: {fileID: 0} + m_RenderPostProcessing: 0 + m_Antialiasing: 0 + m_AntialiasingQuality: 2 + m_StopNaN: 0 + m_Dithering: 0 + m_ClearDepth: 1 + m_AllowXRRendering: 1 + m_RequiresDepthTexture: 0 + m_RequiresColorTexture: 0 + m_Version: 2 +--- !u!20 &100003 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 100000} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 2 + m_BackGroundColor: {r: 0.031, g: 0.047, b: 0.059, a: 0} + m_projectionMatrixMode: 1 + m_GateFitMode: 2 + m_FOVAxisMode: 0 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 34 + orthographic: 1 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 0 + m_HDR: 1 + m_AllowMSAA: 0 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 0 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &100004 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 100000} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!1 &200000 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 200001} + m_Layer: 0 + m_Name: GameRoot + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &200001 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 200000} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/Assets/Scenes/GameScene.unity.meta b/Assets/Scenes/GameScene.unity.meta new file mode 100644 index 0000000..5d550b1 --- /dev/null +++ b/Assets/Scenes/GameScene.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e4259fa62d854e27af3cc2a10fb210c8 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scenes/SampleScene.unity b/Assets/Scenes/MainMenuScene.unity similarity index 72% rename from Assets/Scenes/SampleScene.unity rename to Assets/Scenes/MainMenuScene.unity index 7b420f6..39bacd8 100644 --- a/Assets/Scenes/SampleScene.unity +++ b/Assets/Scenes/MainMenuScene.unity @@ -84,8 +84,8 @@ LightmapSettings: m_PVRDenoiserTypeIndirect: 1 m_PVRDenoiserTypeAO: 1 m_PVRFilterTypeDirect: 0 - m_PVRFilterTypeIndirect: 0 - m_PVRFilterTypeAO: 0 + m_PVRFilterTypeIndirect: 5 + m_PVRFilterTypeAO: 2 m_PVREnvironmentMIS: 1 m_PVRCulling: 1 m_PVRFilteringGaussRadiusDirect: 1 @@ -192,7 +192,7 @@ Camera: m_Enabled: 1 serializedVersion: 2 m_ClearFlags: 2 - m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_BackGroundColor: {r: 0.031, g: 0.047, b: 0.059, a: 0} m_projectionMatrixMode: 1 m_GateFitMode: 2 m_FOVAxisMode: 0 @@ -232,6 +232,7 @@ Transform: m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 519420028} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: -10} m_LocalScale: {x: 1, y: 1, z: 1} @@ -240,7 +241,7 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &619394800 +--- !u!1 &1100000000 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -248,100 +249,24 @@ GameObject: m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - - component: {fileID: 619394802} - - component: {fileID: 619394801} - m_Layer: 0 - m_Name: Global Light 2D + - component: {fileID: 1100000001} + - component: {fileID: 1100000002} + - component: {fileID: 1100000003} + m_Layer: 5 + m_Name: MainMenuUI m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!114 &619394801 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 619394800} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 073797afb82c5a1438f328866b10b3f0, type: 3} - m_Name: - m_EditorClassIdentifier: - m_ComponentVersion: 1 - m_LightType: 4 - m_BlendStyleIndex: 0 - m_FalloffIntensity: 0.5 - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_Intensity: 1 - m_LightVolumeIntensity: 1 - m_LightVolumeIntensityEnabled: 0 - m_ApplyToSortingLayers: 00000000 - m_LightCookieSprite: {fileID: 0} - m_DeprecatedPointLightCookieSprite: {fileID: 0} - m_LightOrder: 0 - m_OverlapOperation: 0 - m_NormalMapDistance: 3 - m_NormalMapQuality: 2 - m_UseNormalMap: 0 - m_ShadowIntensityEnabled: 0 - m_ShadowIntensity: 0.75 - m_ShadowVolumeIntensityEnabled: 0 - m_ShadowVolumeIntensity: 0.75 - m_Vertices: - - position: {x: 0.9985302, y: 0.9985302, z: 0} - color: {r: 0.70710677, g: 0.70710677, b: 0, a: 0} - uv: {x: 0, y: 0} - - position: {x: 0.9985302, y: 0.9985302, z: 0} - color: {r: 0, g: 0, b: 0, a: 1} - uv: {x: 0, y: 0} - - position: {x: -0.9985302, y: 0.9985302, z: 0} - color: {r: -0.70710677, g: 0.70710677, b: 0, a: 0} - uv: {x: 0, y: 0} - - position: {x: -0.9985302, y: 0.9985302, z: 0} - color: {r: 0, g: 0, b: 0, a: 1} - uv: {x: 0, y: 0} - - position: {x: -0.99853003, y: -0.9985304, z: 0} - color: {r: -0.70710665, g: -0.7071069, b: 0, a: 0} - uv: {x: 0, y: 0} - - position: {x: -0.99853003, y: -0.9985304, z: 0} - color: {r: 0, g: 0, b: 0, a: 1} - uv: {x: 0, y: 0} - - position: {x: 0.99853003, y: -0.9985304, z: 0} - color: {r: 0.70710665, g: -0.7071069, b: 0, a: 0} - uv: {x: 0, y: 0} - - position: {x: 0.99853003, y: -0.9985304, z: 0} - color: {r: 0, g: 0, b: 0, a: 1} - uv: {x: 0, y: 0} - - position: {x: 0, y: 0, z: 0} - color: {r: 0, g: 0, b: 0, a: 1} - uv: {x: 0, y: 0} - m_Triangles: 030001000800020000000100030002000100050003000800040002000300050004000300070005000800060004000500070006000500010007000800000006000700010000000700 - m_LocalBounds: - m_Center: {x: 0, y: -0.00000011920929, z: 0} - m_Extent: {x: 0.9985302, y: 0.99853027, z: 0} - m_PointLightInnerAngle: 360 - m_PointLightOuterAngle: 360 - m_PointLightInnerRadius: 0 - m_PointLightOuterRadius: 1 - m_ShapeLightParametricSides: 5 - m_ShapeLightParametricAngleOffset: 0 - m_ShapeLightParametricRadius: 1 - m_ShapeLightFalloffSize: 0.5 - m_ShapeLightFalloffOffset: {x: 0, y: 0} - m_ShapePath: - - {x: -0.5, y: -0.5, z: 0} - - {x: 0.5, y: -0.5, z: 0} - - {x: 0.5, y: 0.5, z: 0} - - {x: -0.5, y: 0.5, z: 0} ---- !u!4 &619394802 +--- !u!4 &1100000001 Transform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 619394800} + m_GameObject: {fileID: 1100000000} + serializedVersion: 2 m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} @@ -350,3 +275,34 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 1 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!114 &1100000002 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1100000000} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 19102, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_PanelSettings: {fileID: 11400000, guid: 7d68bd7978394c8295debbd403a39d80, type: 2} + m_ParentUI: {fileID: 0} + sourceAsset: {fileID: 9197481963319205126, guid: a720a33f8c2b4dfe9d8197772dc0ab21, type: 3} + m_SortingOrder: 0 +--- !u!114 &1100000003 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1100000000} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 27a7f29e93cb4c55beac52f1e32a1bf5, type: 3} + m_Name: + m_EditorClassIdentifier: + monospaceFont: {fileID: 0} + featuredUnitPanel: + featuredUnits: [] diff --git a/Assets/Scenes/SampleScene.unity.meta b/Assets/Scenes/MainMenuScene.unity.meta similarity index 100% rename from Assets/Scenes/SampleScene.unity.meta rename to Assets/Scenes/MainMenuScene.unity.meta diff --git a/Assets/Scripts/Core/SceneLoader.cs b/Assets/Scripts/Core/SceneLoader.cs new file mode 100644 index 0000000..0f36ef2 --- /dev/null +++ b/Assets/Scripts/Core/SceneLoader.cs @@ -0,0 +1,30 @@ +using UnityEngine.SceneManagement; + +namespace KernelPanic.Core +{ + /// + /// Provides scene navigation entry points for the runtime shell. + /// + public static class SceneLoader + { + public const string MainMenuSceneName = "MainMenuScene"; + public const string GameSceneName = "GameScene"; + + public static void LoadMainMenu() + { + LoadScene(MainMenuSceneName); + } + + public static void LoadGame() + { + LoadScene(GameSceneName); + } + + // Static for now because menu navigation has no instance state; a loading-screen service can replace this hook later. + private static void LoadScene(string sceneName) + { + // TODO: Route async progress into a loading screen once the UI shell has one. + SceneManager.LoadSceneAsync(sceneName); + } + } +} diff --git a/Assets/Scripts/Core/SceneLoader.cs.meta b/Assets/Scripts/Core/SceneLoader.cs.meta new file mode 100644 index 0000000..519c755 --- /dev/null +++ b/Assets/Scripts/Core/SceneLoader.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0d860bbf8e7f4df2a91e2e1e9892d904 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/Data/DistroDefinition.cs b/Assets/Scripts/Data/DistroDefinition.cs index 43e0a83..ff6f480 100644 --- a/Assets/Scripts/Data/DistroDefinition.cs +++ b/Assets/Scripts/Data/DistroDefinition.cs @@ -13,6 +13,8 @@ namespace KernelPanic.Data [SerializeField] private string displayName; [SerializeField] private Language primaryLanguage; [SerializeField] private Language secondaryLanguage; + [SerializeField] private string passiveName; + [SerializeField] private Color accentColor = new(0.36f, 1f, 0.57f); [SerializeField] private int baseUptime; [SerializeField] private int baseRam; [SerializeField] private int baseCyclesPerTurn; @@ -22,6 +24,8 @@ namespace KernelPanic.Data public string DisplayName => displayName; public Language PrimaryLanguage => primaryLanguage; public Language SecondaryLanguage => secondaryLanguage; + public string PassiveName => passiveName; + public Color AccentColor => accentColor; public int BaseUptime => baseUptime; public int BaseRam => baseRam; public int BaseCyclesPerTurn => baseCyclesPerTurn; diff --git a/Assets/Scripts/Meta/GachaService.cs b/Assets/Scripts/Meta/GachaService.cs index ced3450..3c16949 100644 --- a/Assets/Scripts/Meta/GachaService.cs +++ b/Assets/Scripts/Meta/GachaService.cs @@ -7,6 +7,8 @@ namespace KernelPanic.Meta /// public sealed class GachaService { + public int PullTokens => 0; // TODO: Replace with the real pull-token wallet when that meta system exists. + public GachaPullResult PerformPull(EntropyWallet wallet, int cost) { throw new NotImplementedException(); diff --git a/Assets/Scripts/Meta/IEventBannerSource.cs b/Assets/Scripts/Meta/IEventBannerSource.cs new file mode 100644 index 0000000..c2c02d9 --- /dev/null +++ b/Assets/Scripts/Meta/IEventBannerSource.cs @@ -0,0 +1,27 @@ +using System; + +namespace KernelPanic.Meta +{ + /// + /// Provides optional live-event banner copy for shell surfaces. + /// + public interface IEventBannerSource + { + EventBannerContent GetBanner(); + } + + /// + /// Describes an optional event banner message and remaining duration. + /// + public sealed class EventBannerContent + { + public EventBannerContent(string text, TimeSpan? remainingTime) + { + Text = text; + RemainingTime = remainingTime; + } + + public string Text { get; } + public TimeSpan? RemainingTime { get; } + } +} diff --git a/Assets/Scripts/Meta/IEventBannerSource.cs.meta b/Assets/Scripts/Meta/IEventBannerSource.cs.meta new file mode 100644 index 0000000..6e0db88 --- /dev/null +++ b/Assets/Scripts/Meta/IEventBannerSource.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 542dd3144a914ea5b1e0c0e21db5ec6b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI.meta b/Assets/Scripts/UI.meta new file mode 100644 index 0000000..649c90c --- /dev/null +++ b/Assets/Scripts/UI.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 84a74d1de7c84009a2cf84394e8a9fa2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/BootLogCopy.cs b/Assets/Scripts/UI/BootLogCopy.cs new file mode 100644 index 0000000..7d3ba5f --- /dev/null +++ b/Assets/Scripts/UI/BootLogCopy.cs @@ -0,0 +1,22 @@ +namespace KernelPanic.UI +{ + /// + /// Contains cosmetic terminal boot-log copy for the main menu shell. + /// + public static class BootLogCopy + { + public static readonly string[] Lines = + { + "[ 0.000000] kernel-panic: booting userland shell", + "[ 0.071004] cpu: isolating run scheduler", + "[ 0.184331] entropy: wallet device mounted readonly", + "[ 0.264700] tty1: spawning command menu", + "[ 0.391226] units: probing installed distros", + "[ 0.447801] collection: no render pass requested", + "[ 0.521332] gacha: token api unavailable", + "[ 0.684012] events: banner source disconnected", + "[ 0.812445] ui: reduced motion preference loaded", + "[ 1.000000] shell: ready" + }; + } +} diff --git a/Assets/Scripts/UI/BootLogCopy.cs.meta b/Assets/Scripts/UI/BootLogCopy.cs.meta new file mode 100644 index 0000000..9499cb7 --- /dev/null +++ b/Assets/Scripts/UI/BootLogCopy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e05527a70e234c16af2f9089012721b8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Scripts/UI/FeaturedUnitPanel.cs b/Assets/Scripts/UI/FeaturedUnitPanel.cs new file mode 100644 index 0000000..3b3a0ed --- /dev/null +++ b/Assets/Scripts/UI/FeaturedUnitPanel.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using KernelPanic.Data; +using UnityEngine; +using UnityEngine.UIElements; + +namespace KernelPanic.UI +{ + /// + /// Renders the main menu's neofetch-style featured unit panel. + /// + [Serializable] + public sealed class FeaturedUnitPanel + { + private const string EmptyAccent = "5cff91"; + private const string EmptyAscii = " _\n | |\n ___| |__\n / __| '_ \\\n \\__ \\ | | |\n |___/_| |_|"; + + [SerializeField] private List featuredUnits = new(); + + private VisualElement panel; + private Label titleLabel; + private Label asciiLabel; + private Label unitNameLabel; + private Label languagesLabel; + private Label passiveLabel; + private Label bestWaveLabel; + private Label emptyTitleLabel; + private Label emptyHintLabel; + private VisualElement populatedState; + private VisualElement emptyState; + private int selectedIndex; + + public void Bind(VisualElement root) + { + panel = root.Q("FeaturedUnitPanel"); + titleLabel = root.Q