DEADSOFTWARE

Refactor menu
authorfredboy <fredboy@protonmail.com>
Sun, 29 Jun 2025 18:10:39 +0000 (01:10 +0700)
committerfredboy <fredboy@protonmail.com>
Sun, 29 Jun 2025 18:10:39 +0000 (01:10 +0700)
58 files changed:
android/src/main/kotlin/ru/deadsoftware/cavedroid/AndroidPreferencesStore.kt
assets/json/menu.json [new file with mode: 0644]
assets/json/menu_main_buttons.json [deleted file]
assets/json/menu_new_game_buttons.json [deleted file]
assets/json/menu_options_buttons.json [deleted file]
buildSrc/src/main/kotlin/DependencyHandlerExtentions.kt
core/build.gradle.kts
core/common/src/main/kotlin/ru/fredboy/cavedroid/common/CaveDroidConstants.kt [new file with mode: 0644]
core/common/src/main/kotlin/ru/fredboy/cavedroid/common/api/GameController.kt
core/common/src/main/kotlin/ru/fredboy/cavedroid/common/api/PreferencesStore.kt [moved from core/src/main/kotlin/ru/deadsoftware/cavedroid/prefs/PreferencesStore.kt with 75% similarity]
core/common/src/main/kotlin/ru/fredboy/cavedroid/common/di/MenuScope.kt [new file with mode: 0644]
core/data/configuration/src/main/kotlin/ru/fredboy/cavedroid/data/configuration/repository/GameContextRepositoryImpl.kt
core/data/menu/build.gradle.kts [new file with mode: 0644]
core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/di/DataMenuModule.kt [new file with mode: 0644]
core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/mapper/MenuButtonMapper.kt [new file with mode: 0644]
core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/model/MenuButtonDto.kt [new file with mode: 0644]
core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/model/MenuButtonVisibilityDto.kt [new file with mode: 0644]
core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/repository/MenuButtonRepositoryImpl.kt [new file with mode: 0644]
core/domain/menu/build.gradle.kts [new file with mode: 0644]
core/domain/menu/src/main/kotlin/ru/fredboy/cavedroid/domain/menu/model/MenuButton.kt [new file with mode: 0644]
core/domain/menu/src/main/kotlin/ru/fredboy/cavedroid/domain/menu/repository/MenuButtonRepository.kt [new file with mode: 0644]
core/src/main/java/ru/deadsoftware/cavedroid/MainConfig.java
core/src/main/java/ru/deadsoftware/cavedroid/menu/MenuComponent.java
core/src/main/java/ru/deadsoftware/cavedroid/menu/MenuProc.java [deleted file]
core/src/main/java/ru/deadsoftware/cavedroid/menu/MenuScope.java [deleted file]
core/src/main/java/ru/deadsoftware/cavedroid/menu/MenuScreen.java
core/src/main/java/ru/deadsoftware/cavedroid/menu/objects/Button.java [deleted file]
core/src/main/java/ru/deadsoftware/cavedroid/menu/objects/ButtonEventListener.java [deleted file]
core/src/main/java/ru/deadsoftware/cavedroid/menu/objects/ButtonRenderer.java [deleted file]
core/src/main/java/ru/deadsoftware/cavedroid/menu/submenus/Menu.java [deleted file]
core/src/main/java/ru/deadsoftware/cavedroid/menu/submenus/MenuMain.java [deleted file]
core/src/main/java/ru/deadsoftware/cavedroid/menu/submenus/MenuNewGame.java [deleted file]
core/src/main/java/ru/deadsoftware/cavedroid/misc/Assets.java [deleted file]
core/src/main/java/ru/deadsoftware/cavedroid/misc/Renderer.java [deleted file]
core/src/main/kotlin/ru/deadsoftware/cavedroid/CaveGame.kt
core/src/main/kotlin/ru/deadsoftware/cavedroid/MainComponent.kt
core/src/main/kotlin/ru/deadsoftware/cavedroid/menu/objects/BooleanOptionButton.kt [deleted file]
core/src/main/kotlin/ru/deadsoftware/cavedroid/menu/submenus/MenuOptions.kt [deleted file]
core/src/main/kotlin/ru/deadsoftware/cavedroid/menu/submenus/MenusFactory.kt [deleted file]
core/src/main/kotlin/ru/deadsoftware/cavedroid/misc/utils/AssetLoader.kt [deleted file]
core/zygote/build.gradle.kts [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/ExitGameAction.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/IMenuAction.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/LoadGameAction.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/NewGameCreativeAction.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/NewGameSurvivalAction.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/OpenMainMenuAction.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/OpenNewGameMenuAction.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/OpenOptionsMenuAction.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/annotation/BindsMenuAction.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/input/MenuInputProcessor.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/option/annotation/BindsMenuBooleanOption.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/option/bool/DynamicCameraMenuBooleanOption.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/option/bool/FullscreenMenuBooleanOption.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/option/bool/IMenuBooleanOption.kt [new file with mode: 0644]
core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/renderer/MenuRenderer.kt [new file with mode: 0644]
desktop/src/main/kotlin/ru/deadsoftware/cavedroid/desktop/DesktopPreferencesStore.kt
settings.gradle.kts

index 4b16659cf4e54c60395cb93c67a2496f2370d125..d334cfef9e32d48efd5142d3245b0836e72bb59d 100644 (file)
@@ -1,7 +1,7 @@
 package ru.deadsoftware.cavedroid
 
 import android.content.Context
-import ru.deadsoftware.cavedroid.prefs.PreferencesStore
+import ru.fredboy.cavedroid.common.api.PreferencesStore
 
 class AndroidPreferencesStore(
     private val context: Context
diff --git a/assets/json/menu.json b/assets/json/menu.json
new file mode 100644 (file)
index 0000000..974fb30
--- /dev/null
@@ -0,0 +1,55 @@
+{
+  "main": {
+    "new_game": {
+      "label": "New Game",
+      "actionKey": "new_game_action"
+    },
+    "load_game": {
+      "label": "Load Game",
+      "actionKey": "load_game_action"
+    },
+    "options": {
+      "label": "Settings",
+      "actionKey": "options_action"
+    },
+    "quit": {
+      "label": "Quit",
+      "actionKey": "exit_game_action"
+    }
+  },
+  "new_game": {
+    "creative": {
+      "label": "Creative",
+      "actionKey": "new_game_creative_action"
+    },
+    "survival": {
+      "label": "Survival",
+      "actionKey": "new_game_survival_action"
+    },
+    "back": {
+      "label": "Back",
+      "actionKey": "menu_main_action"
+    }
+  },
+  "options": {
+    "dyncam": {
+      "type": "boolean_option",
+      "label": "Dynamic Camera: %s",
+      "actionKey": "toggle_dyncam_action",
+      "options": ["dyncam"]
+    },
+    "fullscreen": {
+      "type": "boolean_option",
+      "label": "Fullscreen: %s",
+      "actionKey": "toggle_fullscreen_action",
+      "options": ["fullscreen"],
+      "visibility": {
+        "android": false
+      }
+    },
+    "back": {
+      "label": "Back",
+      "actionKey": "menu_main_action"
+    }
+  }
+}
\ No newline at end of file
diff --git a/assets/json/menu_main_buttons.json b/assets/json/menu_main_buttons.json
deleted file mode 100644 (file)
index 97d0938..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "new_game": {
-    "label": "New Game"
-  },
-  "load_game": {
-    "label": "Load Game",
-    "type": 0
-  },
-  "options": {
-    "label": "Settings"
-  },
-  "quit": {
-    "label": "Quit"
-  }
-}
\ No newline at end of file
diff --git a/assets/json/menu_new_game_buttons.json b/assets/json/menu_new_game_buttons.json
deleted file mode 100644 (file)
index ca4c404..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "creative": {
-    "label": "Creative"
-  },
-  "survival": {
-    "label": "Survival"
-  },
-  "back": {
-    "label": "Back"
-  }
-}
\ No newline at end of file
diff --git a/assets/json/menu_options_buttons.json b/assets/json/menu_options_buttons.json
deleted file mode 100644 (file)
index bb956cd..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "dyncam": {
-    "option_type": "boolean",
-    "label": "Dynamic Camera: %%value%%"
-  },
-  "fullscreen": {
-    "option_type": "boolean",
-    "label": "Fullscreen: %%value%%",
-    "visible_on_android": false
-  },
-  "back": {
-    "label": "Back"
-  }
-}
\ No newline at end of file
index 87a16b356850e6416d540079898feccccda6dc0b..030f783c753269264f0c0099431809efe5fed63c 100644 (file)
@@ -19,6 +19,7 @@ fun DependencyHandler.useDataModules() {
     useModule(":core:data:assets")
     useModule(":core:data:configuration")
     useModule(":core:data:items")
+    useModule(":core:data:menu")
     useModule(":core:data:save")
 }
 
@@ -27,6 +28,7 @@ fun DependencyHandler.useDomainModules() {
     useModule(":core:domain:configuration")
     useModule(":core:domain:items")
     useModule(":core:domain:save")
+    useModule(":core:domain:menu")
     useModule(":core:domain:world")
 }
 
@@ -50,6 +52,10 @@ fun DependencyHandler.useUxModules() {
     useModule(":core:ux:rendering")
 }
 
+fun DependencyHandler.useZygoteModule() {
+    useModule(":core:zygote")
+}
+
 fun DependencyHandler.useAutomultibind() {
     implementation(Dependencies.Automultibind.annotations)
     ksp(Dependencies.Automultibind.ksp)
index d6f312d4e004daf9152ab145aa41e89ddd1d2907..1dec1e4a7e31aa6493841dd39fee6743d22e3494 100644 (file)
@@ -28,6 +28,7 @@ dependencies {
     useEntityModules()
     useGameModules()
     useUxModules()
+    useZygoteModule()
 
     implementation(Dependencies.jetbrainsAnnotations)
 }
diff --git a/core/common/src/main/kotlin/ru/fredboy/cavedroid/common/CaveDroidConstants.kt b/core/common/src/main/kotlin/ru/fredboy/cavedroid/common/CaveDroidConstants.kt
new file mode 100644 (file)
index 0000000..180b694
--- /dev/null
@@ -0,0 +1,7 @@
+package ru.fredboy.cavedroid.common
+
+object CaveDroidConstants {
+
+    const val VERSION = "alpha 0.9.2"
+
+}
\ No newline at end of file
index 78f3e5707437b77e06f5de6c43aa0a49ce62d6b6..457448524b20bb79c003c7ee7494aa3f798b622a 100644 (file)
@@ -4,4 +4,12 @@ interface GameController {
 
     fun quitGame()
 
+    fun newGameCreative()
+
+    fun newGameSurvival()
+
+    fun loadGame()
+
+    fun exitGame()
+
 }
\ No newline at end of file
similarity index 75%
rename from core/src/main/kotlin/ru/deadsoftware/cavedroid/prefs/PreferencesStore.kt
rename to core/common/src/main/kotlin/ru/fredboy/cavedroid/common/api/PreferencesStore.kt
index edc95179977162c108882e80904ac55cbf579131..9b48604ce440acad4028f3359939e46e1ad3d8f5 100644 (file)
@@ -1,4 +1,4 @@
-package ru.deadsoftware.cavedroid.prefs
+package ru.fredboy.cavedroid.common.api
 
 interface PreferencesStore {
 
@@ -6,4 +6,4 @@ interface PreferencesStore {
 
     fun setPreference(key: String, value: String?)
 
-}
+}
\ No newline at end of file
diff --git a/core/common/src/main/kotlin/ru/fredboy/cavedroid/common/di/MenuScope.kt b/core/common/src/main/kotlin/ru/fredboy/cavedroid/common/di/MenuScope.kt
new file mode 100644 (file)
index 0000000..52de4fe
--- /dev/null
@@ -0,0 +1,7 @@
+package ru.fredboy.cavedroid.common.di
+
+import javax.inject.Scope
+
+@Scope
+@Retention(AnnotationRetention.RUNTIME)
+annotation class MenuScope
index fb7b2a54421f0b0ad497745cd45bd91e7ae24051..b3e2b127916472952db1fae33081ec0ff6f87b6c 100644 (file)
@@ -1,5 +1,6 @@
 package ru.fredboy.cavedroid.data.configuration.repository
 
+import com.badlogic.gdx.Gdx
 import ru.fredboy.cavedroid.common.model.Joystick
 import ru.fredboy.cavedroid.data.configuration.store.GameContextStore
 import ru.fredboy.cavedroid.domain.configuration.model.CameraContext
@@ -61,6 +62,11 @@ class GameContextRepositoryImpl @Inject constructor(
     }
 
     override fun setFullscreen(fullscreen: Boolean) {
+        if (fullscreen) {
+            Gdx.graphics.setFullscreenMode(Gdx.graphics.displayMode);
+        } else {
+            Gdx.graphics.setWindowedMode(getWidth().toInt(), getHeight().toInt());
+        }
         gameContextStore.isFullscreen = fullscreen
     }
 
diff --git a/core/data/menu/build.gradle.kts b/core/data/menu/build.gradle.kts
new file mode 100644 (file)
index 0000000..73fdbcc
--- /dev/null
@@ -0,0 +1,18 @@
+plugins {
+    kotlin
+    ksp
+    kotlinxSerialization
+}
+
+java.sourceCompatibility = ApplicationInfo.sourceCompatibility
+java.targetCompatibility = ApplicationInfo.sourceCompatibility
+
+dependencies {
+    useCommonModule()
+    useLibgdx()
+    useKotlinxSerializationJson()
+    useDagger()
+
+    useModule(":core:domain:assets")
+    useModule(":core:domain:menu")
+}
diff --git a/core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/di/DataMenuModule.kt b/core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/di/DataMenuModule.kt
new file mode 100644 (file)
index 0000000..621edeb
--- /dev/null
@@ -0,0 +1,14 @@
+package ru.fredboy.cavedroid.data.menu.di
+
+import dagger.Binds
+import dagger.Module
+import ru.fredboy.cavedroid.data.menu.repository.MenuButtonRepositoryImpl
+import ru.fredboy.cavedroid.domain.menu.repository.MenuButtonRepository
+
+@Module
+abstract class DataMenuModule {
+
+    @Binds
+    internal abstract fun bindMenuButtonsRepository(impl: MenuButtonRepositoryImpl): MenuButtonRepository
+
+}
diff --git a/core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/mapper/MenuButtonMapper.kt b/core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/mapper/MenuButtonMapper.kt
new file mode 100644 (file)
index 0000000..9bafcc9
--- /dev/null
@@ -0,0 +1,52 @@
+package ru.fredboy.cavedroid.data.menu.mapper
+
+import com.badlogic.gdx.Application
+import com.badlogic.gdx.Gdx
+import ru.fredboy.cavedroid.common.di.MenuScope
+import ru.fredboy.cavedroid.data.menu.model.MenuButtonDto
+import ru.fredboy.cavedroid.data.menu.model.MenuButtonVisibilityDto
+import ru.fredboy.cavedroid.domain.menu.model.MenuButton
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@MenuScope
+class MenuButtonMapper @Inject constructor() {
+
+    fun map(dto: MenuButtonDto): MenuButton {
+        return when (dto.type) {
+            "boolean_option" -> MenuButton.BooleanOption(
+                label = dto.label.toString(),
+                isVisible = mapVisibility(dto.visibility),
+                actionKey = dto.actionKey.orEmpty(),
+                optionKeys = dto.options.orEmpty(),
+                isEnabled = dto.enabled ?: true,
+            )
+
+            "default", null -> MenuButton.Simple(
+                label = dto.label.toString(),
+                isVisible = mapVisibility(dto.visibility),
+                actionKey = dto.actionKey.orEmpty(),
+                isEnabled = dto.enabled ?: true,
+            )
+
+            else ->
+                throw IllegalArgumentException("Unknown button type: ${dto.type}")
+        }
+    }
+
+    fun setButtonEnabled(button: MenuButton, isEnabled: Boolean): MenuButton {
+        return when (button) {
+            is MenuButton.Simple -> button.copy(isEnabled = isEnabled)
+            is MenuButton.BooleanOption -> button.copy(isEnabled = isEnabled)
+        }
+    }
+
+    private fun mapVisibility(dto: MenuButtonVisibilityDto?): Boolean {
+        dto ?: return true
+
+        return when (Gdx.app.type) {
+            Application.ApplicationType.Android -> dto.android
+            else -> dto.desktop
+        }
+    }
+}
\ No newline at end of file
diff --git a/core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/model/MenuButtonDto.kt b/core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/model/MenuButtonDto.kt
new file mode 100644 (file)
index 0000000..18819b1
--- /dev/null
@@ -0,0 +1,13 @@
+package ru.fredboy.cavedroid.data.menu.model
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class MenuButtonDto(
+    val label: String? = null,
+    val actionKey: String? = null,
+    val type: String? = null,
+    val enabled: Boolean? = null,
+    val visibility: MenuButtonVisibilityDto? = null,
+    val options: List<String>? = null,
+)
diff --git a/core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/model/MenuButtonVisibilityDto.kt b/core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/model/MenuButtonVisibilityDto.kt
new file mode 100644 (file)
index 0000000..3704d65
--- /dev/null
@@ -0,0 +1,9 @@
+package ru.fredboy.cavedroid.data.menu.model
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class MenuButtonVisibilityDto(
+    val android: Boolean = true,
+    val desktop: Boolean = true,
+)
diff --git a/core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/repository/MenuButtonRepositoryImpl.kt b/core/data/menu/src/main/kotlin/ru/fredboy/cavedroid/data/menu/repository/MenuButtonRepositoryImpl.kt
new file mode 100644 (file)
index 0000000..81b8a98
--- /dev/null
@@ -0,0 +1,88 @@
+package ru.fredboy.cavedroid.data.menu.repository
+
+import com.badlogic.gdx.Gdx
+import kotlinx.serialization.json.Json
+import ru.fredboy.cavedroid.common.di.MenuScope
+import ru.fredboy.cavedroid.data.menu.mapper.MenuButtonMapper
+import ru.fredboy.cavedroid.data.menu.model.MenuButtonDto
+import ru.fredboy.cavedroid.domain.menu.model.MenuButton
+import ru.fredboy.cavedroid.domain.menu.repository.MenuButtonRepository
+import javax.inject.Inject
+
+@MenuScope
+class MenuButtonRepositoryImpl @Inject constructor(
+    private val menuButtonMapper: MenuButtonMapper,
+) : MenuButtonRepository {
+
+    private var _initialized = false
+
+    private val menuMap = LinkedHashMap<String, MutableMap<String, MenuButton>>()
+
+    private var currentMenu = "main"
+
+    init {
+        initialize()
+    }
+
+    override fun initialize() {
+        if (_initialized) {
+            Gdx.app.debug(TAG, "Attempted to init when already initialized")
+            return
+        }
+
+        val jsonString = Gdx.files.internal("json/menu.json").readString()
+
+        JsonFormat.decodeFromString<Map<String, Map<String, MenuButtonDto>>>(jsonString)
+            .forEach { (key, value) ->
+                menuMap[key] = value.mapValues { (_, dto) -> menuButtonMapper.map(dto) }.toMutableMap()
+            }
+
+        _initialized = true
+    }
+
+    override fun getButtonsForMenu(menuKey: String): Map<String, MenuButton>? {
+        require(_initialized) { "$TAG was not initialized before access!" }
+
+        return menuMap[menuKey].also {
+            if (it == null) {
+                Gdx.app.debug(TAG, "No buttons for $menuKey menu found")
+            }
+        }
+    }
+
+    override fun setCurrentMenu(menuKey: String) {
+        currentMenu = menuKey
+    }
+
+    override fun getCurrentMenuButtons(): Map<String, MenuButton>? {
+        require(_initialized) { "$TAG was not initialized before access!" }
+
+        return menuMap[currentMenu]?.filterValues { button -> button.isVisible }
+    }
+
+    override fun setButtonEnabled(menuKey: String, buttonKey: String, enabled: Boolean) {
+        val menu = menuMap[menuKey] ?: run {
+            Gdx.app.error(TAG, "setButtonEnabled: menu with key '$menuKey' not found")
+            return
+        }
+
+        val button = menu[buttonKey] ?: run {
+            Gdx.app.error(TAG, "setButtonEnabled: button with key '$buttonKey' not found")
+            return
+        }
+
+        menu[buttonKey] = menuButtonMapper.setButtonEnabled(button, enabled)
+    }
+
+    override fun dispose() {
+        menuMap.clear()
+        _initialized = false
+    }
+
+    companion object {
+        private const val TAG = "MenuButtonsRepositoryImpl"
+
+        private val JsonFormat = Json { ignoreUnknownKeys = true }
+    }
+
+}
\ No newline at end of file
diff --git a/core/domain/menu/build.gradle.kts b/core/domain/menu/build.gradle.kts
new file mode 100644 (file)
index 0000000..9d3840d
--- /dev/null
@@ -0,0 +1,13 @@
+plugins {
+    kotlin
+    ksp
+}
+
+java.sourceCompatibility = ApplicationInfo.sourceCompatibility
+java.targetCompatibility = ApplicationInfo.sourceCompatibility
+
+dependencies {
+    useCommonModule()
+    useLibgdx()
+    useDagger()
+}
diff --git a/core/domain/menu/src/main/kotlin/ru/fredboy/cavedroid/domain/menu/model/MenuButton.kt b/core/domain/menu/src/main/kotlin/ru/fredboy/cavedroid/domain/menu/model/MenuButton.kt
new file mode 100644 (file)
index 0000000..63b4ec2
--- /dev/null
@@ -0,0 +1,25 @@
+package ru.fredboy.cavedroid.domain.menu.model
+
+sealed class MenuButton {
+
+    abstract val label: String
+    abstract val isVisible: Boolean
+    abstract val actionKey: String
+    abstract val isEnabled: Boolean
+
+
+    data class Simple(
+        override val label: String,
+        override val isVisible: Boolean,
+        override val actionKey: String,
+        override val isEnabled: Boolean,
+    ) : MenuButton()
+
+    data class BooleanOption(
+        override val label: String,
+        override val isVisible: Boolean,
+        override val actionKey: String,
+        override val isEnabled: Boolean,
+        val optionKeys: List<String>,
+    ) : MenuButton()
+}
diff --git a/core/domain/menu/src/main/kotlin/ru/fredboy/cavedroid/domain/menu/repository/MenuButtonRepository.kt b/core/domain/menu/src/main/kotlin/ru/fredboy/cavedroid/domain/menu/repository/MenuButtonRepository.kt
new file mode 100644 (file)
index 0000000..775643b
--- /dev/null
@@ -0,0 +1,18 @@
+package ru.fredboy.cavedroid.domain.menu.repository
+
+import com.badlogic.gdx.utils.Disposable
+import ru.fredboy.cavedroid.domain.menu.model.MenuButton
+
+interface MenuButtonRepository : Disposable {
+
+    fun initialize()
+
+    fun getButtonsForMenu(menuKey: String): Map<String, MenuButton>?
+
+    fun setCurrentMenu(menuKey: String)
+
+    fun getCurrentMenuButtons(): Map<String, MenuButton>?
+
+    fun setButtonEnabled(menuKey: String, buttonKey: String, enabled: Boolean)
+
+}
\ No newline at end of file
index 2e4078141df4f7ac63e2ba3460eb79917f1639a3..4f884c0c5020e2a421459834fe87a78bbdfacd8d 100644 (file)
@@ -1,37 +1,18 @@
 package ru.deadsoftware.cavedroid;
 
 import org.jetbrains.annotations.Nullable;
-import ru.deadsoftware.cavedroid.prefs.PreferencesStore;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
-import java.util.HashMap;
 
 @Singleton
 public class MainConfig {
 
-    private final HashMap<String, String> mPreferencesCache = new HashMap<>();
-
-    @Nullable
-    private FullscreenToggleListener mFullscreenToggleListener = null;
-
-    private final CaveGame mCaveGame;
-    private final PreferencesStore mPreferencesStore;
-
     @Nullable
     private MainComponent mMainComponent;
 
-    @Nullable
-    private String mAssetsPackPath = null;
-
     @Inject
-    public MainConfig(CaveGame caveGame, PreferencesStore preferencesStore) {
-        mCaveGame = caveGame;
-        mPreferencesStore = preferencesStore;
-    }
-
-    public CaveGame getCaveGame() {
-        return mCaveGame;
+    public MainConfig() {
     }
 
     public MainComponent getMainComponent() {
@@ -42,42 +23,4 @@ public class MainConfig {
     public void setMainComponent(MainComponent mainComponent) {
         mMainComponent = mainComponent;
     }
-
-    @Nullable
-    public String getAssetsPackPath() {
-        return mAssetsPackPath;
-    }
-
-    @Nullable
-    public String getPreference(String key) {
-        if (mPreferencesCache.containsKey(key)) {
-            return mPreferencesCache.get(key);
-        }
-
-        String value = mPreferencesStore.getPreference(key);
-        mPreferencesCache.put(key, value);
-
-        return value;
-    }
-
-    public void setPreference(String key, String value) {
-        mPreferencesCache.put(key, value);
-        mPreferencesStore.setPreference(key, value);
-
-        if (mFullscreenToggleListener != null && key.equals("fullscreen")) {
-            mFullscreenToggleListener.onFullscreenToggled(Boolean.parseBoolean(value));
-        }
-    }
-
-    public void setFullscreenToggleListener(@Nullable FullscreenToggleListener fullscreenToggleListener) {
-        mFullscreenToggleListener = fullscreenToggleListener;
-    }
-
-    public boolean isUseDynamicCamera() {
-        return Boolean.parseBoolean(getPreference("dyncam"));
-    }
-
-    public interface FullscreenToggleListener {
-        void onFullscreenToggled(boolean value);
-    }
 }
index d7b51dc2eea54a0d115d37f40a62a225c51ae235..9d7bec6604526296f94e7f3d1abef4a1285b1a1b 100644 (file)
@@ -2,12 +2,24 @@ package ru.deadsoftware.cavedroid.menu;
 
 import dagger.Component;
 import ru.deadsoftware.cavedroid.MainComponent;
+import ru.deadsoftware.cavedroid.generated.module.MenuActionsModule;
+import ru.fredboy.cavedroid.common.di.MenuScope;
+import ru.fredboy.cavedroid.data.menu.di.DataMenuModule;
+import ru.fredboy.cavedroid.domain.menu.repository.MenuButtonRepository;
 import ru.fredboy.cavedroid.game.controller.container.di.ControllerContainerModule;
 import ru.fredboy.cavedroid.game.controller.drop.di.ControllerDropModule;
+import ru.fredboy.cavedroid.zygote.menu.input.MenuInputProcessor;
+import ru.fredboy.cavedroid.zygote.menu.renderer.MenuRenderer;
+import ru.deadsoftware.cavedroid.generated.module.MenuBooleanOptionsModule;
 
 @MenuScope
 @Component(dependencies = MainComponent.class, modules = {ControllerContainerModule.class,
-        ControllerDropModule.class})
+        ControllerDropModule.class, DataMenuModule.class, MenuBooleanOptionsModule.class, MenuActionsModule.class})
 public interface MenuComponent {
-    MenuProc getMenuProc();
+
+    public MenuRenderer menuRenderer();
+
+    public MenuInputProcessor menuInputProcessor();
+
+    public MenuButtonRepository menuButtonsRepository();
 }
diff --git a/core/src/main/java/ru/deadsoftware/cavedroid/menu/MenuProc.java b/core/src/main/java/ru/deadsoftware/cavedroid/menu/MenuProc.java
deleted file mode 100644 (file)
index 5449437..0000000
+++ /dev/null
@@ -1,166 +0,0 @@
-package ru.deadsoftware.cavedroid.menu;
-
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.utils.ObjectMap;
-import ru.deadsoftware.cavedroid.CaveGame;
-import ru.deadsoftware.cavedroid.MainConfig;
-import ru.deadsoftware.cavedroid.menu.objects.Button;
-import ru.deadsoftware.cavedroid.menu.submenus.*;
-import ru.deadsoftware.cavedroid.misc.Renderer;
-import ru.fredboy.cavedroid.common.utils.RenderingUtilsKt;
-import ru.fredboy.cavedroid.domain.assets.usecase.GetFontUseCase;
-import ru.fredboy.cavedroid.domain.assets.usecase.GetStringHeightUseCase;
-import ru.fredboy.cavedroid.domain.assets.usecase.GetStringWidthUseCase;
-import ru.fredboy.cavedroid.domain.assets.usecase.GetTextureRegionByNameUseCase;
-import ru.fredboy.cavedroid.domain.configuration.repository.GameContextRepository;
-
-import javax.inject.Inject;
-
-import java.lang.reflect.Method;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-@MenuScope
-public class MenuProc extends Renderer {
-
-    public class Input {
-        private void startNewGame(int gameMode) {
-            mMainConfig.getCaveGame().newGame(gameMode);
-        }
-
-        public void newGameClicked() {
-            mCurrentMenu = mMenuNewGame;
-        }
-
-        public void loadGameClicked() {
-            mMainConfig.getCaveGame().loadGame();
-        }
-
-        public void optionsClicked() {
-            mCurrentMenu = mMenuOptions;
-        }
-
-        public void quitClicked() {
-            Gdx.app.exit();
-        }
-
-        public void survivalClicked() {
-            startNewGame(0);
-        }
-
-        public void creativeClicked() {
-            startNewGame(1);
-        }
-
-        public void backClicked() {
-            mCurrentMenu = mMenuMain;
-        }
-
-        public void setPreference(String key, Object value) {
-            mMainConfig.setPreference(key, value.toString());
-        }
-    }
-
-    private final MainConfig mMainConfig;
-
-    private final GameContextRepository mGameContextRepository;
-
-    private final MenuMain mMenuMain;
-    private final MenuNewGame mMenuNewGame;
-    private final MenuOptions mMenuOptions;
-
-    private final GetFontUseCase mGetFontUseCase;
-    private final GetStringWidthUseCase mGetStringWidthUseCase;
-    private final GetStringHeightUseCase mGetStringHeightUseCase;
-
-    private final GetTextureRegionByNameUseCase mGetTextureRegionByNameUseCase;
-
-    private Menu mCurrentMenu;
-
-    @Inject
-    public MenuProc(
-            MainConfig mainConfig,
-            GameContextRepository gameContextRepository,
-            MenusFactory menusFactory,
-            GetFontUseCase getFontUseCase,
-            GetStringWidthUseCase getStringWidthUseCase,
-            GetStringHeightUseCase getStringHeightUseCase,
-            GetTextureRegionByNameUseCase getTextureRegionByNameUseCase
-    ) {
-        super(gameContextRepository.getWidth(), gameContextRepository.getHeight());
-
-        mMainConfig = mainConfig;
-        mGameContextRepository = gameContextRepository;
-        mGetFontUseCase = getFontUseCase;
-        mGetStringWidthUseCase = getStringWidthUseCase;
-        mGetStringHeightUseCase = getStringHeightUseCase;
-        mGetTextureRegionByNameUseCase = getTextureRegionByNameUseCase;
-
-        Input menuInput = new Input();
-
-        mMenuMain = menusFactory.getMainMenu(getWidth(), getHeight(), this::drawButton, menuInput);
-        mMenuNewGame = menusFactory.getMenuNewGame(getWidth(), getHeight(), this::drawButton, menuInput);
-        mMenuOptions = menusFactory.getMenuOptions(getWidth(), getHeight(), this::drawButton, menuInput);
-
-        mCurrentMenu = mMenuMain;
-    }
-
-    private String processVariables(String raw) {
-        final Pattern pattern = Pattern.compile("%%([A-Za-z]+)%%", Pattern.CASE_INSENSITIVE);
-        final Matcher matcher = pattern.matcher(raw);
-        while (matcher.find()) {
-            for (int i = 0; i < matcher.groupCount(); i++) {
-                try {
-                    final String group = matcher.group(i);
-                    final String name = group.replaceAll("%%", "");
-                    final Method method = mMainConfig.getClass().getMethod(name);
-                    final String value = method.invoke(mMainConfig).toString();
-                    raw = raw.replace(group, value);
-                } catch (Exception e) {
-                    throw new RuntimeException(e);
-                }
-            }
-        }
-
-        return raw;
-    }
-
-    private void drawButton(Button button) {
-        spriter.draw(mGetTextureRegionByNameUseCase.get("button_" + button.getType()), button.getX(), button.getY());
-
-        String label = processVariables(button.getLabel());
-
-        RenderingUtilsKt.drawString(spriter, mGetFontUseCase.invoke(), label,
-                (button.getX() + button.getWidth() / 2) - mGetStringWidthUseCase.invoke(label) / 2,
-                (button.getY() + button.getHeight() / 2) - mGetStringHeightUseCase.invoke(label) / 2);
-    }
-
-    @Override
-    public boolean touchUp(int screenX, int screenY, int pointer, int mb) {
-        screenX *= getWidth() / Gdx.graphics.getWidth();
-        screenY *= getHeight() / Gdx.graphics.getHeight();
-        for (ObjectMap.Entry<String, Button> entry : mCurrentMenu.getButtons()) {
-            Button button = entry.value;
-            if (button.getRect().contains(screenX, screenY)) {
-                if (button.getType() > 0) {
-                    button.clicked();
-                }
-                break;
-            }
-        }
-        return false;
-    }
-
-    @Override
-    public void render(float delta) {
-        spriter.begin();
-        mCurrentMenu.draw(spriter);
-        RenderingUtilsKt.drawString(spriter, mGetFontUseCase.invoke(), "CaveDroid " + CaveGame.VERSION, 0,
-                getHeight() - mGetStringHeightUseCase.invoke("CaveDroid " + CaveGame.VERSION) * 1.5f);
-        spriter.end();
-    }
-
-    public void reset() {
-        mCurrentMenu = mMenuMain;
-    }
-}
diff --git a/core/src/main/java/ru/deadsoftware/cavedroid/menu/MenuScope.java b/core/src/main/java/ru/deadsoftware/cavedroid/menu/MenuScope.java
deleted file mode 100644 (file)
index 3198af6..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-package ru.deadsoftware.cavedroid.menu;
-
-import javax.inject.Scope;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-@Scope
-@Retention(RetentionPolicy.RUNTIME)
-public @interface MenuScope {
-}
index 4b9c5e34efa861992164a1e7098af91b7a17636b..cdb9733ce34ef00739542167c38ca939f721d399 100644 (file)
@@ -3,6 +3,9 @@ package ru.deadsoftware.cavedroid.menu;
 import com.badlogic.gdx.Gdx;
 import com.badlogic.gdx.Screen;
 import ru.deadsoftware.cavedroid.MainConfig;
+import ru.fredboy.cavedroid.domain.menu.repository.MenuButtonRepository;
+import ru.fredboy.cavedroid.zygote.menu.input.MenuInputProcessor;
+import ru.fredboy.cavedroid.zygote.menu.renderer.MenuRenderer;
 
 import javax.inject.Inject;
 import javax.inject.Singleton;
@@ -10,24 +13,34 @@ import javax.inject.Singleton;
 @Singleton
 public class MenuScreen implements Screen {
 
-    private final MenuProc mMenuProc;
+    private final MenuRenderer mMenuRenderer;
+
+    private final MenuInputProcessor mMenuInputProcessor;
+
+    private final MenuButtonRepository mMenuButtonsRepository;
 
     @Inject
     public MenuScreen(MainConfig mainConfig) {
         MenuComponent menuComponent = DaggerMenuComponent.builder()
                 .mainComponent(mainConfig.getMainComponent()).build();
-        mMenuProc = menuComponent.getMenuProc();
+
+        mMenuRenderer = menuComponent.menuRenderer();
+        mMenuInputProcessor = menuComponent.menuInputProcessor();
+        mMenuButtonsRepository = menuComponent.menuButtonsRepository();
+    }
+
+    public void resetMenu() {
+        mMenuButtonsRepository.setCurrentMenu("main");
     }
 
     @Override
     public void show() {
-        mMenuProc.reset();
-        Gdx.input.setInputProcessor(mMenuProc);
+        Gdx.input.setInputProcessor(mMenuInputProcessor);
     }
 
     @Override
     public void render(float delta) {
-        mMenuProc.render(delta);
+        mMenuRenderer.render(delta);
     }
 
     @Override
diff --git a/core/src/main/java/ru/deadsoftware/cavedroid/menu/objects/Button.java b/core/src/main/java/ru/deadsoftware/cavedroid/menu/objects/Button.java
deleted file mode 100644 (file)
index bc78f21..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-package ru.deadsoftware.cavedroid.menu.objects;
-
-import com.badlogic.gdx.math.Rectangle;
-
-public class Button {
-
-    public static final int WIDTH = 200;
-    public static final int HEIGHT = 20;
-
-    public static final int
-            DISABLED = 0,
-            NORMAL = 1,
-            SELECTED = 2;
-    private final Rectangle rect;
-    private final String label;
-    private ButtonEventListener listener;
-    private int type;
-
-    /**
-     * @param label Label to be shown on button
-     * @param type  Type of button where 0 - disabled,  1 - normal, 2 - selected.
-     *              You should use these constants
-     *              {@link #DISABLED} {@link #NORMAL} {@link #SELECTED}
-     */
-    public Button(String label, int x, int y, int type, ButtonEventListener listener) {
-        this.label = label;
-        rect = new Rectangle(x, y, WIDTH, HEIGHT);
-        this.type = type;
-        this.listener = listener;
-    }
-
-    public Rectangle getRect() {
-        return rect;
-    }
-
-    public String getLabel() {
-        return label;
-    }
-
-    public float getX() {
-        return rect.x;
-    }
-
-    public float getY() {
-        return rect.y;
-    }
-
-    public float getWidth() {
-        return rect.width;
-    }
-
-    public float getHeight() {
-        return rect.height;
-    }
-
-    public int getType() {
-        return type;
-    }
-
-    public void setType(int type) {
-        this.type = type;
-    }
-
-    public void draw(ButtonRenderer drawer) {
-        drawer.draw(this);
-    }
-
-    public void clicked() {
-        listener.buttonClicked();
-    }
-
-}
diff --git a/core/src/main/java/ru/deadsoftware/cavedroid/menu/objects/ButtonEventListener.java b/core/src/main/java/ru/deadsoftware/cavedroid/menu/objects/ButtonEventListener.java
deleted file mode 100644 (file)
index 3797295..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-package ru.deadsoftware.cavedroid.menu.objects;
-
-/**
- * A {@link Button} event listener. Should be sent as lambda to Button's constructor.
- */
-public interface ButtonEventListener {
-
-    /**
-     * Will be called by {@link Button} when clicked
-     */
-    void buttonClicked();
-
-}
diff --git a/core/src/main/java/ru/deadsoftware/cavedroid/menu/objects/ButtonRenderer.java b/core/src/main/java/ru/deadsoftware/cavedroid/menu/objects/ButtonRenderer.java
deleted file mode 100644 (file)
index 6a429f2..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-package ru.deadsoftware.cavedroid.menu.objects;
-
-public interface ButtonRenderer {
-
-    void draw(Button button);
-
-}
diff --git a/core/src/main/java/ru/deadsoftware/cavedroid/menu/submenus/Menu.java b/core/src/main/java/ru/deadsoftware/cavedroid/menu/submenus/Menu.java
deleted file mode 100644 (file)
index 5f48fa4..0000000
+++ /dev/null
@@ -1,152 +0,0 @@
-package ru.deadsoftware.cavedroid.menu.submenus;
-
-import com.badlogic.gdx.Application;
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.files.FileHandle;
-import com.badlogic.gdx.graphics.g2d.SpriteBatch;
-import com.badlogic.gdx.graphics.g2d.TextureRegion;
-import com.badlogic.gdx.utils.ArrayMap;
-import com.badlogic.gdx.utils.JsonValue;
-import ru.deadsoftware.cavedroid.MainConfig;
-import ru.deadsoftware.cavedroid.menu.MenuProc;
-import ru.deadsoftware.cavedroid.menu.objects.BooleanOptionButton;
-import ru.deadsoftware.cavedroid.menu.objects.Button;
-import ru.deadsoftware.cavedroid.menu.objects.ButtonEventListener;
-import ru.deadsoftware.cavedroid.menu.objects.ButtonRenderer;
-import ru.deadsoftware.cavedroid.misc.Assets;
-import ru.deadsoftware.cavedroid.misc.utils.AssetLoader;
-import ru.fredboy.cavedroid.domain.assets.usecase.GetTextureRegionByNameUseCase;
-
-import java.util.HashMap;
-
-public abstract class Menu {
-
-    protected final MainConfig mMainConfig;
-    protected final MenuProc.Input mMenuInput;
-    protected final AssetLoader mAssetLoader;
-
-    protected final GetTextureRegionByNameUseCase mGetTextureRegionByNameUseCase;
-
-    private final ButtonRenderer mButtonRenderer;
-
-    private final float mWidth;
-    private final float mHeight;
-
-    /**
-     * {@link ArrayMap} of {@link Button Buttons} of this menu screen
-     */
-    private ArrayMap<String, Button> buttons;
-
-    /**
-     * @param width          Viewport width
-     * @param height         Viewport height
-     * @param buttonRenderer {@link ButtonRenderer} that will draw the buttons of this menu
-     */
-    Menu(float width,
-         float height,
-         ButtonRenderer buttonRenderer,
-         MainConfig mainConfig,
-         MenuProc.Input menuInput,
-         AssetLoader assetLoader,
-         GetTextureRegionByNameUseCase getTextureRegionByNameUseCase) {
-        mWidth = width;
-        mHeight = height;
-        mButtonRenderer = buttonRenderer;
-        mMainConfig = mainConfig;
-        mMenuInput = menuInput;
-        mAssetLoader = assetLoader;
-        mGetTextureRegionByNameUseCase = getTextureRegionByNameUseCase;
-    }
-
-    final void init() {
-        initButtons();
-    }
-
-    /**
-     * If you are loading buttons from json,
-     * override this method and create a HashMap with buttons' keys from json as keys
-     * and {@link ButtonEventListener ButtonEventListeners} as values.
-     *
-     * @return empty HashMap if not overridden
-     */
-    protected HashMap<String, ButtonEventListener> getButtonEventListeners() {
-        return new HashMap<>();
-    }
-
-    /**
-     * You can call this from {@link #initButtons()} to load buttons from json
-     *
-     * @param jsonFile A {@link FileHandle} to json file
-     */
-    void loadButtonsFromJson(FileHandle jsonFile) {
-        if (buttons == null) {
-            buttons = new ArrayMap<>();
-        }
-        HashMap<String, ButtonEventListener> eventListeners = getButtonEventListeners();
-        JsonValue json = Assets.jsonReader.parse(jsonFile);
-        int y = (int) mHeight / 4;
-        for (JsonValue key = json.child(); key != null; key = key.next(), y += Button.HEIGHT + 10) {
-
-            if (Gdx.app.getType() == Application.ApplicationType.Android &&
-                    !Assets.getBooleanFromJson(key, "visible_on_android", true)) {
-                continue;
-            }
-
-            String optionType = Assets.getStringFromJson(key, "option_type", "");
-            String label = Assets.getStringFromJson(key, "label", "");
-            int x = (int) mWidth / 2 - Button.WIDTH / 2;
-            int type = Assets.getIntFromJson(key, "type", Button.NORMAL);
-            String defaultValue = Assets.getStringFromJson(key, "default_value", "");
-
-
-            Button button = switch (optionType) {
-                case "boolean" ->
-                    new BooleanOptionButton(mMainConfig, key.name(), Boolean.parseBoolean(defaultValue), label, x, y, type);
-                default ->
-                    new Button(label, x, y, type, eventListeners.containsKey(key.name()) ? eventListeners.get(key.name()) : () -> {});
-            };
-
-            buttons.put(key.name(), button);
-        }
-    }
-
-    /**
-     * Draws the menu with background, logo and it's buttons
-     *
-     * @param spriter {@link SpriteBatch} that will draw it. Should be already started.
-     */
-    public void draw(SpriteBatch spriter) {
-        TextureRegion background = mGetTextureRegionByNameUseCase.get("background");
-        TextureRegion gamelogo = mGetTextureRegionByNameUseCase.get("gamelogo");
-
-        for (int x = 0; x <= mWidth / 16; x++) {
-            for (int y = 0; y <= mHeight / 16; y++) {
-                spriter.draw(background, x * 16, y * 16);
-            }
-        }
-        spriter.draw(gamelogo, mWidth / 2 - (float) gamelogo.getRegionWidth() / 2, 8);
-
-        float inputX = Gdx.input.getX() * mWidth / Gdx.graphics.getWidth();
-        float inputY = Gdx.input.getY() * mHeight / Gdx.graphics.getHeight();
-        for (Button button : buttons.values()) {
-            if (button.getType() > 0) {
-                if (button.getRect().contains(inputX, inputY) && (/*!CaveGame.TOUCH || */Gdx.input.isTouched())) {
-                    button.setType(2);
-                } else {
-                    button.setType(1);
-                }
-            }
-            button.draw(mButtonRenderer);
-        }
-    }
-
-    public ArrayMap<String, Button> getButtons() {
-        return buttons;
-    }
-
-    /**
-     * This method is called from constructor and should initialize {@link #buttons} <br>
-     * You can run {@link #loadButtonsFromJson(FileHandle)} from it
-     */
-    protected abstract void initButtons();
-}
diff --git a/core/src/main/java/ru/deadsoftware/cavedroid/menu/submenus/MenuMain.java b/core/src/main/java/ru/deadsoftware/cavedroid/menu/submenus/MenuMain.java
deleted file mode 100644 (file)
index 24dc1da..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-package ru.deadsoftware.cavedroid.menu.submenus;
-
-import ru.deadsoftware.cavedroid.MainConfig;
-import ru.deadsoftware.cavedroid.menu.MenuProc;
-import ru.deadsoftware.cavedroid.menu.objects.Button;
-import ru.deadsoftware.cavedroid.menu.objects.ButtonEventListener;
-import ru.deadsoftware.cavedroid.menu.objects.ButtonRenderer;
-import ru.deadsoftware.cavedroid.misc.utils.AssetLoader;
-import ru.fredboy.cavedroid.domain.assets.usecase.GetTextureRegionByNameUseCase;
-import ru.fredboy.cavedroid.domain.configuration.repository.GameContextRepository;
-import ru.fredboy.cavedroid.domain.save.repository.SaveDataRepository;
-
-import java.util.HashMap;
-
-public class MenuMain extends Menu {
-
-    private final SaveDataRepository mSaveDataRepository;
-
-    private final GameContextRepository mGameContextRepository;
-
-    public MenuMain(float width,
-                    float height,
-                    ButtonRenderer buttonRenderer,
-                    MainConfig mainConfig,
-                    MenuProc.Input menuInput,
-                    AssetLoader assetLoader,
-                    GetTextureRegionByNameUseCase getTextureRegionByNameUseCase,
-                    SaveDataRepository saveDataRepository,
-                    GameContextRepository gameContextRepository) {
-        super(width, height, buttonRenderer, mainConfig, menuInput, assetLoader, getTextureRegionByNameUseCase);
-        mSaveDataRepository = saveDataRepository;
-        mGameContextRepository = gameContextRepository;
-    }
-
-    @Override
-    protected HashMap<String, ButtonEventListener> getButtonEventListeners() {
-        HashMap<String, ButtonEventListener> map = new HashMap<>();
-        map.put("new_game", mMenuInput::newGameClicked);
-        map.put("load_game", mMenuInput::loadGameClicked);
-        map.put("options", mMenuInput::optionsClicked);
-        map.put("quit", mMenuInput::quitClicked);
-        return map;
-    }
-
-    @Override
-    protected void initButtons() {
-        loadButtonsFromJson(mAssetLoader.getAssetHandle("json/menu_main_buttons.json"));
-        if (mSaveDataRepository.exists(mGameContextRepository.getGameDirectory())) {
-            getButtons().get("load_game").setType(Button.NORMAL);
-        }
-    }
-
-}
diff --git a/core/src/main/java/ru/deadsoftware/cavedroid/menu/submenus/MenuNewGame.java b/core/src/main/java/ru/deadsoftware/cavedroid/menu/submenus/MenuNewGame.java
deleted file mode 100644 (file)
index e5ee093..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-package ru.deadsoftware.cavedroid.menu.submenus;
-
-import ru.deadsoftware.cavedroid.MainConfig;
-import ru.deadsoftware.cavedroid.menu.MenuProc;
-import ru.deadsoftware.cavedroid.menu.objects.ButtonEventListener;
-import ru.deadsoftware.cavedroid.menu.objects.ButtonRenderer;
-import ru.deadsoftware.cavedroid.misc.utils.AssetLoader;
-import ru.fredboy.cavedroid.domain.assets.usecase.GetTextureRegionByNameUseCase;
-
-import java.util.HashMap;
-
-public class MenuNewGame extends Menu {
-
-    public MenuNewGame(float width,
-                       float height,
-                       ButtonRenderer buttonRenderer,
-                       MainConfig mainConfig,
-                       MenuProc.Input menuInput,
-                       AssetLoader assetLoader,
-                       GetTextureRegionByNameUseCase getTextureRegionByNameUseCase) {
-        super(width, height, buttonRenderer, mainConfig, menuInput, assetLoader, getTextureRegionByNameUseCase);
-    }
-
-    @Override
-    protected HashMap<String, ButtonEventListener> getButtonEventListeners() {
-        HashMap<String, ButtonEventListener> map = new HashMap<>();
-        map.put("survival", mMenuInput::survivalClicked);
-        map.put("creative", mMenuInput::creativeClicked);
-        map.put("back", mMenuInput::backClicked);
-        return map;
-    }
-
-    @Override
-    protected void initButtons() {
-        loadButtonsFromJson(mAssetLoader.getAssetHandle("json/menu_new_game_buttons.json"));
-    }
-
-}
diff --git a/core/src/main/java/ru/deadsoftware/cavedroid/misc/Assets.java b/core/src/main/java/ru/deadsoftware/cavedroid/misc/Assets.java
deleted file mode 100644 (file)
index 063fe30..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package ru.deadsoftware.cavedroid.misc;
-
-import com.badlogic.gdx.utils.JsonReader;
-import com.badlogic.gdx.utils.JsonValue;
-
-
-public class Assets {
-
-
-    public static final JsonReader jsonReader = new JsonReader();
-
-
-    public static int getIntFromJson(JsonValue json, String name, int defaultValue) {
-        return json.has(name) ? json.getInt(name) : defaultValue;
-    }
-
-
-    public static String getStringFromJson(JsonValue json, String name, String defaultValue) {
-        return json.has(name) ? json.getString(name) : defaultValue;
-    }
-
-    public static boolean getBooleanFromJson(JsonValue json, String name, boolean defaultValue) {
-        return json.has(name) ? json.getBoolean(name) : defaultValue;
-    }
-
-}
diff --git a/core/src/main/java/ru/deadsoftware/cavedroid/misc/Renderer.java b/core/src/main/java/ru/deadsoftware/cavedroid/misc/Renderer.java
deleted file mode 100644 (file)
index b74c3bf..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-package ru.deadsoftware.cavedroid.misc;
-
-import com.badlogic.gdx.Gdx;
-import com.badlogic.gdx.InputProcessor;
-import com.badlogic.gdx.graphics.OrthographicCamera;
-import com.badlogic.gdx.graphics.g2d.SpriteBatch;
-import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
-import com.badlogic.gdx.math.Rectangle;
-
-public abstract class Renderer implements InputProcessor {
-
-    protected final ShapeRenderer shaper;
-    protected final SpriteBatch spriter;
-    private final OrthographicCamera camera;
-    private final Rectangle mCameraViewport;
-
-    protected Renderer() {
-        this(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
-    }
-
-    protected Renderer(float width, float height) {
-        camera = new OrthographicCamera();
-        camera.setToOrtho(true, width, height);
-        shaper = new ShapeRenderer();
-        shaper.setProjectionMatrix(camera.combined);
-        spriter = new SpriteBatch();
-        spriter.setProjectionMatrix(camera.combined);
-
-        mCameraViewport =
-                new Rectangle(camera.position.x, camera.position.y, camera.viewportWidth, camera.viewportHeight);
-    }
-
-    public float getWidth() {
-        return camera.viewportWidth;
-    }
-
-    public float getHeight() {
-        return camera.viewportHeight;
-    }
-
-    public float getCamX() {
-        return camera.position.x;
-    }
-
-    public float getCamY() {
-        return camera.position.y;
-    }
-
-    public void setCamPos(float x, float y) {
-        camera.position.set(x, y, 0);
-        mCameraViewport.x = x;
-        mCameraViewport.y = y;
-    }
-
-    public OrthographicCamera getCamera() {
-        return camera;
-    }
-
-    public Rectangle getCameraViewport() {
-        return mCameraViewport;
-    }
-
-    public abstract void render(float delta);
-
-    @Override
-    public boolean keyDown(int keycode) {
-        return false;
-    }
-
-    @Override
-    public boolean keyUp(int keycode) {
-        return false;
-    }
-
-    @Override
-    public boolean keyTyped(char character) {
-        return false;
-    }
-
-    @Override
-    public boolean touchDown(int screenX, int screenY, int pointer, int button) {
-        return false;
-    }
-
-    @Override
-    public boolean touchUp(int screenX, int screenY, int pointer, int button) {
-        return false;
-    }
-
-    @Override
-    public boolean touchDragged(int screenX, int screenY, int pointer) {
-        return false;
-    }
-
-    @Override
-    public boolean mouseMoved(int screenX, int screenY) {
-        return false;
-    }
-
-    @Override
-    public boolean scrolled(float amountX, float amountY) {
-        return false;
-    }
-
-    @Override
-    public boolean touchCancelled(int i, int i1, int i2, int i3) {
-        return false;
-    }
-}
index 07c6e8fb2204474751618f721b72da5d431d0d0c..7c1fcbad8577e4f627b12d65bcffeec4c543e495 100644 (file)
@@ -4,8 +4,7 @@ import com.badlogic.gdx.Application
 import com.badlogic.gdx.Gdx
 import com.badlogic.gdx.graphics.OrthographicCamera
 import com.badlogic.gdx.math.Rectangle
-import ru.deadsoftware.cavedroid.misc.utils.AssetLoader
-import ru.deadsoftware.cavedroid.prefs.PreferencesStore
+import ru.fredboy.cavedroid.common.api.PreferencesStore
 import ru.fredboy.cavedroid.common.utils.ratio
 import ru.fredboy.cavedroid.domain.configuration.model.CameraContext
 import ru.fredboy.cavedroid.domain.configuration.repository.GameContextRepository
@@ -22,8 +21,6 @@ class CaveGame(
 
     private val mGameContextRepository: GameContextRepository
 
-    private val assetLoader: AssetLoader
-
     init {
         mainComponent = DaggerMainComponent.builder()
             .caveGame(this)
@@ -31,7 +28,6 @@ class CaveGame(
             .build()
 
         mainConfig = mainComponent.mainConfig
-        assetLoader = mainComponent.assetLoader
         mGameContextRepository = mainComponent.gameContextRepository
     }
 
@@ -59,27 +55,31 @@ class CaveGame(
         }
 
         Gdx.app.logLevel = if (isDebug) Application.LOG_DEBUG else Application.LOG_ERROR
-
-        mainConfig.setFullscreenToggleListener { isFullscreen ->
-            if (isFullscreen) {
-                Gdx.graphics.setFullscreenMode(Gdx.graphics.displayMode);
-            } else {
-                Gdx.graphics.setWindowedMode(width.toInt(), height.toInt());
-            }
-        }
     }
 
     fun newGame(gameMode: Int) {
         setScreen(mainComponent.gameScreen.apply { newGame(gameMode) })
     }
 
-    fun loadGame() {
+    override fun newGameCreative() {
+        newGame(1)
+    }
+
+    override fun newGameSurvival() {
+        newGame(0)
+    }
+
+    override fun loadGame() {
         setScreen(mainComponent.gameScreen.apply { loadGame() })
     }
 
     override fun quitGame() {
         screen?.dispose()
-        setScreen(mainComponent.menuScreen)
+        setScreen(mainComponent.menuScreen.apply { resetMenu() })
+    }
+
+    override fun exitGame() {
+        Gdx.app.exit()
     }
 
     override fun create() {
@@ -99,8 +99,6 @@ class CaveGame(
     companion object {
         private const val TAG = "CaveGame"
         private const val DEFAULT_VIEWPORT_WIDTH = 480f
-
-        const val VERSION = "alpha 0.9.2"
     }
 
 }
\ No newline at end of file
index b528e15c2519377f48f22d131100b378931925c2..54481183dd0a72821301a05aa0be925398a24b9a 100644 (file)
@@ -3,8 +3,7 @@ package ru.deadsoftware.cavedroid
 import dagger.Component
 import ru.deadsoftware.cavedroid.game.GameScreen
 import ru.deadsoftware.cavedroid.menu.MenuScreen
-import ru.deadsoftware.cavedroid.misc.utils.AssetLoader
-import ru.deadsoftware.cavedroid.prefs.PreferencesStore
+import ru.fredboy.cavedroid.common.api.PreferencesStore
 import ru.fredboy.cavedroid.common.api.GameController
 import ru.fredboy.cavedroid.data.assets.di.DataAssetsModule
 import ru.fredboy.cavedroid.data.configuration.di.DataConfigurationModule
@@ -31,8 +30,6 @@ interface MainComponent {
 
     val mainConfig: MainConfig
 
-    val assetLoader: AssetLoader
-
     val initializeAssetsUseCase: InitializeAssetsUseCase
 
     val disposeAssetsUseCase: DisposeAssetsUseCase
diff --git a/core/src/main/kotlin/ru/deadsoftware/cavedroid/menu/objects/BooleanOptionButton.kt b/core/src/main/kotlin/ru/deadsoftware/cavedroid/menu/objects/BooleanOptionButton.kt
deleted file mode 100644 (file)
index 56329d5..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-package ru.deadsoftware.cavedroid.menu.objects
-
-import ru.deadsoftware.cavedroid.MainConfig
-
-class BooleanOptionButton(
-    private val mainConfig: MainConfig,
-    private val optionKey: String,
-    private val defaultValue: Boolean,
-    label: String,
-    x: Int,
-    y: Int,
-    type: Int,
-) : Button(
-    label,
-    x,
-    y,
-    type,
-    {
-        val current = (mainConfig.getPreference(optionKey)?.toBooleanStrictOrNull()) ?: defaultValue
-        mainConfig.setPreference(optionKey, (!current).toString())
-    }
-) {
-
-    override fun getLabel(): String {
-        val value = (mainConfig.getPreference(optionKey)?.toBooleanStrictOrNull()) ?: defaultValue
-        return super.getLabel().replace("%%value%%", value.toString())
-    }
-
-}
\ No newline at end of file
diff --git a/core/src/main/kotlin/ru/deadsoftware/cavedroid/menu/submenus/MenuOptions.kt b/core/src/main/kotlin/ru/deadsoftware/cavedroid/menu/submenus/MenuOptions.kt
deleted file mode 100644 (file)
index 9ccc019..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-package ru.deadsoftware.cavedroid.menu.submenus
-
-import ru.deadsoftware.cavedroid.MainConfig
-import ru.deadsoftware.cavedroid.menu.MenuProc
-import ru.deadsoftware.cavedroid.menu.objects.ButtonEventListener
-import ru.deadsoftware.cavedroid.menu.objects.ButtonRenderer
-import ru.deadsoftware.cavedroid.misc.utils.AssetLoader
-import ru.fredboy.cavedroid.domain.assets.usecase.GetTextureRegionByNameUseCase
-
-class MenuOptions(
-    width: Float,
-    height: Float,
-    buttonRenderer: ButtonRenderer,
-    mainConfig: MainConfig,
-    menuInput: MenuProc.Input,
-    assetLoader: AssetLoader,
-    getTextureRegionByName: GetTextureRegionByNameUseCase,
-) : Menu(width, height, buttonRenderer, mainConfig, menuInput, assetLoader, getTextureRegionByName) {
-
-    override fun getButtonEventListeners(): HashMap<String, ButtonEventListener> {
-        val map = HashMap<String, ButtonEventListener>()
-        map["back"] = ButtonEventListener { mMenuInput.backClicked() }
-        return map
-    }
-
-    override fun initButtons() {
-        loadButtonsFromJson(mAssetLoader.getAssetHandle("json/menu_options_buttons.json"))
-    }
-}
\ No newline at end of file
diff --git a/core/src/main/kotlin/ru/deadsoftware/cavedroid/menu/submenus/MenusFactory.kt b/core/src/main/kotlin/ru/deadsoftware/cavedroid/menu/submenus/MenusFactory.kt
deleted file mode 100644 (file)
index 85abca9..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-package ru.deadsoftware.cavedroid.menu.submenus
-
-import ru.deadsoftware.cavedroid.MainConfig
-import ru.deadsoftware.cavedroid.menu.MenuProc
-import ru.deadsoftware.cavedroid.menu.MenuScope
-import ru.deadsoftware.cavedroid.menu.objects.ButtonRenderer
-import ru.deadsoftware.cavedroid.misc.utils.AssetLoader
-import ru.fredboy.cavedroid.domain.assets.usecase.GetTextureRegionByNameUseCase
-import ru.fredboy.cavedroid.domain.configuration.repository.GameContextRepository
-import ru.fredboy.cavedroid.domain.save.repository.SaveDataRepository
-import javax.inject.Inject
-
-@MenuScope
-class MenusFactory @Inject constructor(
-    private val mainConfig: MainConfig,
-    private val assetLoader: AssetLoader,
-    private val getTextureRegionByName: GetTextureRegionByNameUseCase,
-    private val saveDataRepository: SaveDataRepository,
-    private val gameContextRepository: GameContextRepository,
-) {
-
-    fun getMainMenu(
-        width: Float,
-        height: Float,
-        buttonRenderer: ButtonRenderer,
-        menuInput: MenuProc.Input,
-    ): MenuMain {
-        return MenuMain(
-            width,
-            height,
-            buttonRenderer,
-            mainConfig,
-            menuInput,
-            assetLoader,
-            getTextureRegionByName,
-            saveDataRepository,
-            gameContextRepository,
-        ).apply { init() }
-    }
-
-    fun getMenuNewGame(
-        width: Float,
-        height: Float,
-        buttonRenderer: ButtonRenderer,
-        menuInput: MenuProc.Input,
-    ): MenuNewGame {
-        return MenuNewGame(
-            width,
-            height,
-            buttonRenderer,
-            mainConfig,
-            menuInput,
-            assetLoader,
-            getTextureRegionByName
-        ).apply { init() }
-    }
-
-    fun getMenuOptions(
-        width: Float,
-        height: Float,
-        buttonRenderer: ButtonRenderer,
-        menuInput: MenuProc.Input,
-    ): MenuOptions {
-        return MenuOptions(
-            width,
-            height,
-            buttonRenderer,
-            mainConfig,
-            menuInput,
-            assetLoader,
-            getTextureRegionByName
-        ).apply { init() }
-    }
-
-}
\ No newline at end of file
diff --git a/core/src/main/kotlin/ru/deadsoftware/cavedroid/misc/utils/AssetLoader.kt b/core/src/main/kotlin/ru/deadsoftware/cavedroid/misc/utils/AssetLoader.kt
deleted file mode 100644 (file)
index 2e82ee1..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-package ru.deadsoftware.cavedroid.misc.utils
-
-import com.badlogic.gdx.Gdx
-import com.badlogic.gdx.files.FileHandle
-import ru.deadsoftware.cavedroid.MainConfig
-import java.io.File
-import javax.inject.Inject
-import javax.inject.Singleton
-
-@Singleton
-class AssetLoader @Inject constructor(
-    private val mainConfig: MainConfig,
-) {
-
-    fun getAssetHandle(path: String): FileHandle {
-        val texturePackPath =
-            mainConfig.assetsPackPath?.let { if (!it.endsWith(File.separator)) "$it${File.separator}" else it }
-
-        return if (texturePackPath == null) {
-            Gdx.files.internal(path)
-        } else {
-            Gdx.files.absolute("$texturePackPath$path")
-        }
-    }
-
-}
diff --git a/core/zygote/build.gradle.kts b/core/zygote/build.gradle.kts
new file mode 100644 (file)
index 0000000..26490ee
--- /dev/null
@@ -0,0 +1,21 @@
+plugins {
+    kotlin
+    ksp
+}
+
+java.sourceCompatibility = ApplicationInfo.sourceCompatibility
+java.targetCompatibility = ApplicationInfo.sourceCompatibility
+
+dependencies {
+    useAutomultibind()
+    useLibgdx()
+    useDagger()
+
+    useCommonModule()
+    useDomainModules()
+    useEntityModules()
+    useGameModules()
+    useUxModules()
+
+    useModule(":core:domain:menu")
+}
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/ExitGameAction.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/ExitGameAction.kt
new file mode 100644 (file)
index 0000000..c84556c
--- /dev/null
@@ -0,0 +1,21 @@
+package ru.fredboy.cavedroid.zygote.menu.action
+
+import ru.fredboy.cavedroid.common.api.GameController
+import ru.fredboy.cavedroid.common.di.MenuScope
+import ru.fredboy.cavedroid.zygote.menu.action.annotation.BindsMenuAction
+import javax.inject.Inject
+
+@MenuScope
+@BindsMenuAction(stringKey = ExitGameAction.KEY)
+class ExitGameAction @Inject constructor(
+    private val gameController: GameController,
+) : IMenuAction {
+
+    override fun perform() {
+        gameController.exitGame()
+    }
+
+    companion object {
+        const val KEY = "exit_game_action"
+    }
+}
\ No newline at end of file
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/IMenuAction.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/IMenuAction.kt
new file mode 100644 (file)
index 0000000..da754fb
--- /dev/null
@@ -0,0 +1,9 @@
+package ru.fredboy.cavedroid.zygote.menu.action
+
+interface IMenuAction {
+
+    fun perform()
+
+    fun canPerform(): Boolean = true
+
+}
\ No newline at end of file
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/LoadGameAction.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/LoadGameAction.kt
new file mode 100644 (file)
index 0000000..52d3411
--- /dev/null
@@ -0,0 +1,29 @@
+package ru.fredboy.cavedroid.zygote.menu.action
+
+import ru.fredboy.cavedroid.common.api.GameController
+import ru.fredboy.cavedroid.common.di.MenuScope
+import ru.fredboy.cavedroid.domain.configuration.repository.GameContextRepository
+import ru.fredboy.cavedroid.domain.save.repository.SaveDataRepository
+import ru.fredboy.cavedroid.zygote.menu.action.annotation.BindsMenuAction
+import javax.inject.Inject
+
+@MenuScope
+@BindsMenuAction(stringKey = LoadGameAction.KEY)
+class LoadGameAction @Inject constructor(
+    private val gameController: GameController,
+    private val saveDataRepository: SaveDataRepository,
+    private val gameContextRepository: GameContextRepository,
+) : IMenuAction {
+
+    override fun perform() {
+        gameController.loadGame()
+    }
+
+    override fun canPerform(): Boolean {
+        return saveDataRepository.exists(gameContextRepository.getGameDirectory())
+    }
+
+    companion object {
+        const val KEY = "load_game_action"
+    }
+}
\ No newline at end of file
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/NewGameCreativeAction.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/NewGameCreativeAction.kt
new file mode 100644 (file)
index 0000000..5e309b4
--- /dev/null
@@ -0,0 +1,21 @@
+package ru.fredboy.cavedroid.zygote.menu.action
+
+import ru.fredboy.cavedroid.common.api.GameController
+import ru.fredboy.cavedroid.common.di.MenuScope
+import ru.fredboy.cavedroid.zygote.menu.action.annotation.BindsMenuAction
+import javax.inject.Inject
+
+@MenuScope
+@BindsMenuAction(stringKey = NewGameCreativeAction.KEY)
+class NewGameCreativeAction @Inject constructor(
+    private val gameController: GameController,
+) : IMenuAction {
+
+    override fun perform() {
+        gameController.newGameCreative()
+    }
+
+    companion object {
+        const val KEY = "new_game_creative_action"
+    }
+}
\ No newline at end of file
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/NewGameSurvivalAction.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/NewGameSurvivalAction.kt
new file mode 100644 (file)
index 0000000..13890bd
--- /dev/null
@@ -0,0 +1,21 @@
+package ru.fredboy.cavedroid.zygote.menu.action
+
+import ru.fredboy.cavedroid.common.api.GameController
+import ru.fredboy.cavedroid.common.di.MenuScope
+import ru.fredboy.cavedroid.zygote.menu.action.annotation.BindsMenuAction
+import javax.inject.Inject
+
+@MenuScope
+@BindsMenuAction(stringKey = NewGameSurvivalAction.KEY)
+class NewGameSurvivalAction @Inject constructor(
+    private val gameController: GameController,
+) : IMenuAction {
+
+    override fun perform() {
+        gameController.newGameSurvival()
+    }
+
+    companion object {
+        const val KEY = "new_game_survival_action"
+    }
+}
\ No newline at end of file
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/OpenMainMenuAction.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/OpenMainMenuAction.kt
new file mode 100644 (file)
index 0000000..3fc2eaf
--- /dev/null
@@ -0,0 +1,21 @@
+package ru.fredboy.cavedroid.zygote.menu.action
+
+import ru.fredboy.cavedroid.common.di.MenuScope
+import ru.fredboy.cavedroid.domain.menu.repository.MenuButtonRepository
+import ru.fredboy.cavedroid.zygote.menu.action.annotation.BindsMenuAction
+import javax.inject.Inject
+
+@MenuScope
+@BindsMenuAction(OpenMainMenuAction.KEY)
+class OpenMainMenuAction @Inject constructor(
+    private val menuButtonRepository: MenuButtonRepository,
+) : IMenuAction {
+
+    override fun perform() {
+        menuButtonRepository.setCurrentMenu("main")
+    }
+
+    companion object {
+        const val KEY = "menu_main_action"
+    }
+}
\ No newline at end of file
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/OpenNewGameMenuAction.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/OpenNewGameMenuAction.kt
new file mode 100644 (file)
index 0000000..7aaafe4
--- /dev/null
@@ -0,0 +1,21 @@
+package ru.fredboy.cavedroid.zygote.menu.action
+
+import ru.fredboy.cavedroid.common.di.MenuScope
+import ru.fredboy.cavedroid.domain.menu.repository.MenuButtonRepository
+import ru.fredboy.cavedroid.zygote.menu.action.annotation.BindsMenuAction
+import javax.inject.Inject
+
+@MenuScope
+@BindsMenuAction(OpenNewGameMenuAction.KEY)
+class OpenNewGameMenuAction @Inject constructor(
+    private val menuButtonRepository: MenuButtonRepository,
+) : IMenuAction {
+
+    override fun perform() {
+        menuButtonRepository.setCurrentMenu("new_game")
+    }
+
+    companion object {
+        const val KEY = "new_game_action"
+    }
+}
\ No newline at end of file
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/OpenOptionsMenuAction.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/OpenOptionsMenuAction.kt
new file mode 100644 (file)
index 0000000..9cb0490
--- /dev/null
@@ -0,0 +1,21 @@
+package ru.fredboy.cavedroid.zygote.menu.action
+
+import ru.fredboy.cavedroid.common.di.MenuScope
+import ru.fredboy.cavedroid.domain.menu.repository.MenuButtonRepository
+import ru.fredboy.cavedroid.zygote.menu.action.annotation.BindsMenuAction
+import javax.inject.Inject
+
+@MenuScope
+@BindsMenuAction(OpenOptionsMenuAction.KEY)
+class OpenOptionsMenuAction @Inject constructor(
+    private val menuButtonRepository: MenuButtonRepository,
+) : IMenuAction {
+
+    override fun perform() {
+        menuButtonRepository.setCurrentMenu("options")
+    }
+
+    companion object {
+        const val KEY = "options_action"
+    }
+}
\ No newline at end of file
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/annotation/BindsMenuAction.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/action/annotation/BindsMenuAction.kt
new file mode 100644 (file)
index 0000000..1a21e85
--- /dev/null
@@ -0,0 +1,12 @@
+package ru.fredboy.cavedroid.zygote.menu.action.annotation
+
+import ru.fredboy.automultibind.annotations.BindsIntoMapStringKey
+import ru.fredboy.cavedroid.common.automultibind.MultibindingConfig
+import ru.fredboy.cavedroid.zygote.menu.action.IMenuAction
+
+@BindsIntoMapStringKey(
+    interfaceClass = IMenuAction::class,
+    modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE,
+    moduleName = "MenuActionsModule",
+)
+annotation class BindsMenuAction(val stringKey: String)
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/input/MenuInputProcessor.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/input/MenuInputProcessor.kt
new file mode 100644 (file)
index 0000000..b78bc21
--- /dev/null
@@ -0,0 +1,120 @@
+package ru.fredboy.cavedroid.zygote.menu.input
+
+import com.badlogic.gdx.Gdx
+import com.badlogic.gdx.InputProcessor
+import com.badlogic.gdx.math.Rectangle
+import ru.fredboy.cavedroid.common.di.MenuScope
+import ru.fredboy.cavedroid.domain.configuration.repository.GameContextRepository
+import ru.fredboy.cavedroid.domain.menu.model.MenuButton
+import ru.fredboy.cavedroid.domain.menu.repository.MenuButtonRepository
+import ru.fredboy.cavedroid.zygote.menu.action.IMenuAction
+import ru.fredboy.cavedroid.zygote.menu.option.bool.IMenuBooleanOption
+import javax.inject.Inject
+
+@MenuScope
+class MenuInputProcessor @Inject constructor(
+    private val gameContextRepository: GameContextRepository,
+    private val menuButtonRepository: MenuButtonRepository,
+    private val menuButtonActions: Map<String, @JvmSuppressWildcards IMenuAction>,
+    private val menuButtonBooleanOption: Map<String, @JvmSuppressWildcards IMenuBooleanOption>,
+) : InputProcessor {
+
+    override fun touchUp(
+        screenX: Int,
+        screenY: Int,
+        pointer: Int,
+        button: Int
+    ): Boolean {
+        val cameraContext = gameContextRepository.getCameraContext() ?: return false
+
+        val (touchX, touchY) = cameraContext.getViewportCoordinates(screenX, screenY)
+
+        menuButtonRepository.getCurrentMenuButtons()?.values?.forEachIndexed { index, button ->
+            if (!button.isEnabled) {
+                return@forEachIndexed
+            }
+
+            // TODO: Fix magic numbers
+            val rect = Rectangle(
+                /* x = */ gameContextRepository.getWidth() / 2 - 100,
+                /* y = */ gameContextRepository.getHeight() / 4 + index * 30,
+                /* width = */ 200f,
+                /* height = */ 20f
+            )
+
+            if (rect.contains(touchX, touchY)) {
+                when (button) {
+                    is MenuButton.Simple -> {
+                        val action = menuButtonActions[button.actionKey] ?: run {
+                            Gdx.app.error(TAG, "Menu handler for action '${button.actionKey}' not found")
+                            return@forEachIndexed
+                        }
+
+                        if (action.canPerform()) {
+                            action.perform()
+                        } else {
+                            Gdx.app.debug(TAG, "Can't perform action ${button.actionKey}")
+                        }
+                    }
+
+                    is MenuButton.BooleanOption -> {
+                        button.optionKeys.forEach { optionKey ->
+                            menuButtonBooleanOption[optionKey]?.toggleOption() ?: run {
+                                Gdx.app.error(TAG, "Menu option handler for option '$optionKey' not found")
+                            }
+                        }
+                    }
+                }
+
+            }
+        }
+
+        return true
+    }
+
+    override fun keyDown(keycode: Int): Boolean {
+        return false
+    }
+
+    override fun keyUp(keycode: Int): Boolean {
+        return false
+    }
+
+    override fun keyTyped(character: Char): Boolean {
+        return false
+    }
+
+    override fun touchDown(
+        screenX: Int,
+        screenY: Int,
+        pointer: Int,
+        button: Int
+    ): Boolean {
+        return false
+    }
+
+    override fun touchCancelled(
+        screenX: Int,
+        screenY: Int,
+        pointer: Int,
+        button: Int
+    ): Boolean {
+        return false
+    }
+
+    override fun touchDragged(screenX: Int, screenY: Int, pointer: Int): Boolean {
+        return false
+    }
+
+    override fun mouseMoved(screenX: Int, screenY: Int): Boolean {
+        return false
+    }
+
+    override fun scrolled(amountX: Float, amountY: Float): Boolean {
+        return false
+    }
+
+    companion object {
+        private const val TAG = "MenuInputProcessor"
+    }
+}
\ No newline at end of file
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/option/annotation/BindsMenuBooleanOption.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/option/annotation/BindsMenuBooleanOption.kt
new file mode 100644 (file)
index 0000000..685caa3
--- /dev/null
@@ -0,0 +1,12 @@
+package ru.fredboy.cavedroid.zygote.menu.option.annotation
+
+import ru.fredboy.automultibind.annotations.BindsIntoMapStringKey
+import ru.fredboy.cavedroid.common.automultibind.MultibindingConfig
+import ru.fredboy.cavedroid.zygote.menu.option.bool.IMenuBooleanOption
+
+@BindsIntoMapStringKey(
+    interfaceClass = IMenuBooleanOption::class,
+    modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE,
+    moduleName = "MenuBooleanOptionsModule",
+)
+annotation class BindsMenuBooleanOption(val stringKey: String)
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/option/bool/DynamicCameraMenuBooleanOption.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/option/bool/DynamicCameraMenuBooleanOption.kt
new file mode 100644 (file)
index 0000000..2a137f2
--- /dev/null
@@ -0,0 +1,25 @@
+package ru.fredboy.cavedroid.zygote.menu.option.bool
+
+import ru.fredboy.cavedroid.common.di.MenuScope
+import ru.fredboy.cavedroid.domain.configuration.repository.GameContextRepository
+import ru.fredboy.cavedroid.zygote.menu.option.annotation.BindsMenuBooleanOption
+import javax.inject.Inject
+
+@MenuScope
+@BindsMenuBooleanOption(DynamicCameraMenuBooleanOption.KEY)
+class DynamicCameraMenuBooleanOption @Inject constructor(
+    private val gameContextRepository: GameContextRepository,
+) : IMenuBooleanOption {
+
+    override fun getOption(): Boolean {
+        return gameContextRepository.useDynamicCamera()
+    }
+
+    override fun toggleOption() {
+        gameContextRepository.setUseDynamicCamera(!getOption())
+    }
+
+    companion object {
+        const val KEY = "dyncam"
+    }
+}
\ No newline at end of file
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/option/bool/FullscreenMenuBooleanOption.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/option/bool/FullscreenMenuBooleanOption.kt
new file mode 100644 (file)
index 0000000..3036ee0
--- /dev/null
@@ -0,0 +1,25 @@
+package ru.fredboy.cavedroid.zygote.menu.option.bool
+
+import ru.fredboy.cavedroid.common.di.MenuScope
+import ru.fredboy.cavedroid.domain.configuration.repository.GameContextRepository
+import ru.fredboy.cavedroid.zygote.menu.option.annotation.BindsMenuBooleanOption
+import javax.inject.Inject
+
+@MenuScope
+@BindsMenuBooleanOption(FullscreenMenuBooleanOption.KEY)
+class FullscreenMenuBooleanOption @Inject constructor(
+    private val gameContextRepository: GameContextRepository,
+) : IMenuBooleanOption {
+
+    override fun getOption(): Boolean {
+        return gameContextRepository.isFullscreen()
+    }
+
+    override fun toggleOption() {
+        gameContextRepository.setFullscreen(!getOption())
+    }
+
+    companion object {
+        const val KEY = "fullscreen"
+    }
+}
\ No newline at end of file
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/option/bool/IMenuBooleanOption.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/option/bool/IMenuBooleanOption.kt
new file mode 100644 (file)
index 0000000..ba6e30a
--- /dev/null
@@ -0,0 +1,9 @@
+package ru.fredboy.cavedroid.zygote.menu.option.bool
+
+interface IMenuBooleanOption {
+
+    fun getOption(): Boolean
+
+    fun toggleOption()
+
+}
\ No newline at end of file
diff --git a/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/renderer/MenuRenderer.kt b/core/zygote/src/main/kotlin/ru/fredboy/cavedroid/zygote/menu/renderer/MenuRenderer.kt
new file mode 100644 (file)
index 0000000..6d36e45
--- /dev/null
@@ -0,0 +1,155 @@
+package ru.fredboy.cavedroid.zygote.menu.renderer
+
+import com.badlogic.gdx.Gdx
+import com.badlogic.gdx.graphics.g2d.SpriteBatch
+import com.badlogic.gdx.math.Rectangle
+import ru.fredboy.cavedroid.common.CaveDroidConstants
+import ru.fredboy.cavedroid.common.di.MenuScope
+import ru.fredboy.cavedroid.common.utils.drawString
+import ru.fredboy.cavedroid.domain.assets.usecase.GetFontUseCase
+import ru.fredboy.cavedroid.domain.assets.usecase.GetStringHeightUseCase
+import ru.fredboy.cavedroid.domain.assets.usecase.GetStringWidthUseCase
+import ru.fredboy.cavedroid.domain.assets.usecase.GetTextureRegionByNameUseCase
+import ru.fredboy.cavedroid.domain.configuration.repository.GameContextRepository
+import ru.fredboy.cavedroid.domain.menu.model.MenuButton
+import ru.fredboy.cavedroid.domain.menu.repository.MenuButtonRepository
+import ru.fredboy.cavedroid.zygote.menu.action.IMenuAction
+import ru.fredboy.cavedroid.zygote.menu.option.bool.IMenuBooleanOption
+import javax.inject.Inject
+
+@MenuScope
+class MenuRenderer @Inject constructor(
+    private val menuButtonRepository: MenuButtonRepository,
+    private val gameContextRepository: GameContextRepository,
+    private val getTextureRegionByName: GetTextureRegionByNameUseCase,
+    private val menuButtonActions: Map<String, @JvmSuppressWildcards IMenuAction>,
+    private val buttonBooleanOptions: Map<String, @JvmSuppressWildcards IMenuBooleanOption>,
+    private val getFont: GetFontUseCase,
+    private val getStringWidth: GetStringWidthUseCase,
+    private val getStringHeight: GetStringHeightUseCase,
+) {
+    private val spriter = SpriteBatch()
+
+    init {
+        val cameraContext = requireNotNull(gameContextRepository.getCameraContext()) {
+            "$TAG: CameraContext was not set"
+        }
+
+        spriter.projectionMatrix = cameraContext.camera.combined
+    }
+
+    private fun getButtonTextureRegionKey(button: MenuButton): String {
+        val buttonAction = menuButtonActions[button.actionKey]
+
+        if (buttonAction?.canPerform() != true) {
+            return KEY_BUTTON_DISABLED_TEXTURE
+        }
+
+        return KEY_BUTTON_ENABLED_TEXTURE.takeIf { button.isEnabled } ?: KEY_BUTTON_DISABLED_TEXTURE
+    }
+
+    private fun renderButton(button: MenuButton, position: Int) {
+        val textureRegion = getTextureRegionByName[getButtonTextureRegionKey(button)] ?: run {
+            Gdx.app.error(TAG, "Couldn't render button because region not found")
+            return
+        }
+
+        val label = when (button) {
+            is MenuButton.Simple -> button.label
+            is MenuButton.BooleanOption -> String.format(
+                button.label,
+                button.optionKeys.map { key -> buttonBooleanOptions[key]?.getOption().toString() }
+            )
+        }
+
+        val buttonX = gameContextRepository.getWidth() / 2 - textureRegion.regionWidth / 2
+        val buttonY = gameContextRepository.getHeight() / 4 + position.toFloat() * 30
+
+        val buttonRect = Rectangle(
+            /* x = */ buttonX,
+            /* y = */ buttonY,
+            /* width = */ textureRegion.regionWidth.toFloat(),
+            /* height = */ textureRegion.regionHeight.toFloat(),
+        )
+
+        val inputCoordinates = gameContextRepository.getCameraContext()?.getViewportCoordinates(
+            x = Gdx.input.x,
+            y = Gdx.input.y,
+        )
+
+        spriter.draw(
+            if (button.isEnabled && inputCoordinates != null && buttonRect.contains(
+                    /* x = */ inputCoordinates.first,
+                    /* y = */ inputCoordinates.second
+                )
+            ) {
+                getTextureRegionByName[KEY_BUTTON_SELECTED_TEXTURE] ?: textureRegion
+            } else {
+                textureRegion
+            },
+            /* x = */ buttonX,
+            /* y = */ buttonY,
+        )
+
+        spriter.drawString(
+            font = getFont(),
+            str = label,
+            x = buttonX + textureRegion.regionWidth / 2 - getStringWidth(label) / 2,
+            y = buttonY + textureRegion.regionHeight / 2 - getStringHeight(label),
+        )
+    }
+
+    private fun drawBackground() {
+        val backgroundRegion = getTextureRegionByName["background"] ?: return
+        val gameLogo = getTextureRegionByName["gamelogo"] ?: return
+
+        val backgroundRegionWidth = backgroundRegion.regionWidth
+        val backgroundRegionHeight = backgroundRegion.regionWidth
+
+        for (x in 0 .. gameContextRepository.getWidth().toInt() / backgroundRegionWidth) {
+            for (y in 0 .. gameContextRepository.getHeight().toInt() / backgroundRegionHeight) {
+                spriter.draw(
+                    /* region = */ backgroundRegion,
+                    /* x = */ x * backgroundRegionWidth.toFloat(),
+                    /* y = */ y * backgroundRegionHeight.toFloat(),
+                )
+            }
+        }
+
+        spriter.draw(
+            /* region = */ gameLogo,
+            /* x = */ gameContextRepository.getWidth() / 2 - gameLogo.regionWidth.toFloat() / 2,
+            /* y = */ 8f,
+        )
+    }
+
+    fun render(delta: Float) {
+        spriter.begin()
+        drawBackground()
+
+        menuButtonRepository.getCurrentMenuButtons()?.values
+            ?.forEachIndexed { position, button -> renderButton(button, position) }
+
+        spriter.drawString(
+            font = getFont(),
+            str = "CaveDroid " + CaveDroidConstants.VERSION,
+            x = 0f,
+            y = gameContextRepository.getHeight() - getStringHeight("CaveDroid " + CaveDroidConstants.VERSION) * 1.5f,
+        );
+        spriter.end()
+
+    }
+
+    fun dispose() {
+        spriter.dispose()
+    }
+
+    companion object {
+        private const val TAG = "MenuRenderer"
+
+        private const val KEY_BUTTON_SELECTED_TEXTURE = "button_2"
+        private const val KEY_BUTTON_ENABLED_TEXTURE = "button_1"
+        private const val KEY_BUTTON_DISABLED_TEXTURE = "button_0"
+    }
+
+}
\ No newline at end of file
index 03591bbc1d31e7be34b7e302ca9302ff0e108b23..951330b05afe2a66cc906126056d33d4e80d926c 100644 (file)
@@ -1,6 +1,6 @@
 package ru.deadsoftware.cavedroid.desktop
 
-import ru.deadsoftware.cavedroid.prefs.PreferencesStore
+import ru.fredboy.cavedroid.common.api.PreferencesStore
 import java.util.prefs.Preferences
 
 class DesktopPreferencesStore : PreferencesStore {
index e5070d7337ef21f76ffd2765aaab62989c92c83c..f38be2914e3d76e2e2c8991523a615ea3ae81983 100644 (file)
@@ -13,6 +13,7 @@ include("core:common")
 include("core:data:assets")
 include("core:data:configuration")
 include("core:data:items")
+include("core:data:menu")
 include("core:data:save")
 
 /**
@@ -21,6 +22,7 @@ include("core:data:save")
 include("core:domain:assets")
 include("core:domain:configuration")
 include("core:domain:items")
+include("core:domain:menu")
 include("core:domain:world")
 include("core:domain:save")
 
@@ -53,3 +55,8 @@ include("core:game:world")
 include("core:ux:controls")
 include("core:ux:physics")
 include("core:ux:rendering")
+
+/**
+ * Zygote module: initialization, menu, screens...
+ */
+include("core:zygote")