From 19b878cb64fd7153355fbdf748707726765a434a Mon Sep 17 00:00:00 2001 From: fredboy Date: Mon, 13 May 2024 20:31:34 +0700 Subject: [PATCH 01/16] Add preferences --- android/assets/json/menu_options_buttons.json | 8 +++- .../cavedroid/AndroidLauncher.java | 3 +- .../cavedroid/AndroidPreferencesStore.kt | 26 +++++++++++ .../ru/deadsoftware/cavedroid/CaveGame.java | 21 ++++++++- .../deadsoftware/cavedroid/MainComponent.java | 3 +- .../ru/deadsoftware/cavedroid/MainConfig.java | 44 ++++++++++++++++--- .../handler/mouse/CursorMouseInputHandler.kt | 13 +++++- .../deadsoftware/cavedroid/menu/MenuProc.java | 6 +-- .../menu/objects/BooleanOptionButton.kt | 29 ++++++++++++ .../cavedroid/menu/submenus/Menu.java | 31 ++++++++++--- .../cavedroid/menu/submenus/MenuOptions.kt | 1 - .../cavedroid/prefs/PreferencesStore.kt | 9 ++++ .../cavedroid/desktop/DesktopLauncher.java | 3 +- .../desktop/DesktopPreferencesStore.kt | 18 ++++++++ 14 files changed, 189 insertions(+), 26 deletions(-) create mode 100644 android/src/ru/deadsoftware/cavedroid/AndroidPreferencesStore.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/menu/objects/BooleanOptionButton.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/prefs/PreferencesStore.kt create mode 100644 desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopPreferencesStore.kt diff --git a/android/assets/json/menu_options_buttons.json b/android/assets/json/menu_options_buttons.json index ebe1bf7..bb956cd 100644 --- a/android/assets/json/menu_options_buttons.json +++ b/android/assets/json/menu_options_buttons.json @@ -1,6 +1,12 @@ { "dyncam": { - "label": "Dynamic Camera: %%isUseDynamicCamera%%" + "option_type": "boolean", + "label": "Dynamic Camera: %%value%%" + }, + "fullscreen": { + "option_type": "boolean", + "label": "Fullscreen: %%value%%", + "visible_on_android": false }, "back": { "label": "Back" diff --git a/android/src/ru/deadsoftware/cavedroid/AndroidLauncher.java b/android/src/ru/deadsoftware/cavedroid/AndroidLauncher.java index e7aad50..3f38ad4 100644 --- a/android/src/ru/deadsoftware/cavedroid/AndroidLauncher.java +++ b/android/src/ru/deadsoftware/cavedroid/AndroidLauncher.java @@ -18,7 +18,8 @@ public class AndroidLauncher extends AndroidApplication { e.printStackTrace(); exit(); } - CaveGame caveGame = new CaveGame(gameFolder, true, null); + CaveGame caveGame = new CaveGame(gameFolder, true, + new AndroidPreferencesStore(getApplicationContext()), null); caveGame.setDebug(BuildConfig.DEBUG); initialize(caveGame, config); } diff --git a/android/src/ru/deadsoftware/cavedroid/AndroidPreferencesStore.kt b/android/src/ru/deadsoftware/cavedroid/AndroidPreferencesStore.kt new file mode 100644 index 0000000..4b16659 --- /dev/null +++ b/android/src/ru/deadsoftware/cavedroid/AndroidPreferencesStore.kt @@ -0,0 +1,26 @@ +package ru.deadsoftware.cavedroid + +import android.content.Context +import ru.deadsoftware.cavedroid.prefs.PreferencesStore + +class AndroidPreferencesStore( + private val context: Context +) : PreferencesStore { + + private val sharedPreferences by lazy { context.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE) } + + override fun getPreference(key: String): String? { + return sharedPreferences.getString(key, null) + } + + override fun setPreference(key: String, value: String?) { + with(sharedPreferences.edit()) { + putString(key, value) + apply() + } + } + + private companion object { + private const val SHARED_PREFS_NAME = "cavedroid_prefs" + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/CaveGame.java b/core/src/ru/deadsoftware/cavedroid/CaveGame.java index 9340552..9ca34b8 100644 --- a/core/src/ru/deadsoftware/cavedroid/CaveGame.java +++ b/core/src/ru/deadsoftware/cavedroid/CaveGame.java @@ -3,9 +3,11 @@ package ru.deadsoftware.cavedroid; import com.badlogic.gdx.Application; import com.badlogic.gdx.Game; import com.badlogic.gdx.Gdx; +import com.badlogic.gdx.Graphics; import ru.deadsoftware.cavedroid.game.GameScreen; import ru.deadsoftware.cavedroid.misc.Assets; import ru.deadsoftware.cavedroid.misc.utils.AssetLoader; +import ru.deadsoftware.cavedroid.prefs.PreferencesStore; import javax.annotation.Nullable; @@ -26,12 +28,19 @@ public class CaveGame extends Game { @Nullable private final String mAssetsPackPath; - public CaveGame(String gameFolder, boolean touch, @Nullable String assetsPackPath) { + public CaveGame(String gameFolder, + boolean touch, + PreferencesStore preferencesStore, + @Nullable String assetsPackPath) { mGameFolder = gameFolder; mTouch = touch; mAssetsPackPath = assetsPackPath; - mMainComponent = DaggerMainComponent.builder().caveGame(this).build(); + mMainComponent = DaggerMainComponent + .builder() + .caveGame(this) + .preferencesStore(preferencesStore) + .build(); mMainConfig = mMainComponent.getMainConfig(); mAssetLoader = mMainComponent.getAssetLoader(); @@ -58,6 +67,14 @@ public class CaveGame extends Game { } else { Gdx.app.setLogLevel(Application.LOG_ERROR); } + + mMainConfig.setFullscreenToggleListener((value) -> { + if (value) { + Gdx.graphics.setFullscreenMode(Gdx.graphics.getDisplayMode()); + } else { + Gdx.graphics.setWindowedMode(width, height); + } + }); } public void newGame(int gameMode) { diff --git a/core/src/ru/deadsoftware/cavedroid/MainComponent.java b/core/src/ru/deadsoftware/cavedroid/MainComponent.java index c640fb6..b487c6d 100644 --- a/core/src/ru/deadsoftware/cavedroid/MainComponent.java +++ b/core/src/ru/deadsoftware/cavedroid/MainComponent.java @@ -4,11 +4,12 @@ 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 javax.inject.Singleton; @Singleton -@Component(dependencies = CaveGame.class) +@Component(dependencies = {CaveGame.class, PreferencesStore.class}) public interface MainComponent { GameScreen getGameScreen(); diff --git a/core/src/ru/deadsoftware/cavedroid/MainConfig.java b/core/src/ru/deadsoftware/cavedroid/MainConfig.java index 64950f2..3ffb506 100644 --- a/core/src/ru/deadsoftware/cavedroid/MainConfig.java +++ b/core/src/ru/deadsoftware/cavedroid/MainConfig.java @@ -2,16 +2,24 @@ package ru.deadsoftware.cavedroid; import ru.deadsoftware.cavedroid.game.GameUiWindow; import ru.deadsoftware.cavedroid.game.input.Joystick; +import ru.deadsoftware.cavedroid.prefs.PreferencesStore; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; +import java.util.HashMap; @Singleton public class MainConfig { + private final HashMap mPreferencesCache = new HashMap<>(); + + @CheckForNull + private FullscreenToggleListener mFullscreenToggleListener = null; + private final CaveGame mCaveGame; + private final PreferencesStore mPreferencesStore; @CheckForNull private MainComponent mMainComponent; @@ -29,14 +37,13 @@ public class MainConfig { private float mWidth; private float mHeight; - private boolean mUseDynamicCamera = true; - @Nullable private String mAssetsPackPath = null; @Inject - public MainConfig(CaveGame caveGame) { + public MainConfig(CaveGame caveGame, PreferencesStore preferencesStore) { mCaveGame = caveGame; + mPreferencesStore = preferencesStore; mGameUiWindow = GameUiWindow.NONE; mGameFolder = ""; @@ -129,11 +136,36 @@ public class MainConfig { mJoystick = joystick; } + @CheckForNull + 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 mUseDynamicCamera; + return Boolean.parseBoolean(getPreference("dyncam")); } - public void setUseDynamicCamera(boolean useDynamicCamera) { - mUseDynamicCamera = useDynamicCamera; + public interface FullscreenToggleListener { + void onFullscreenToggled(boolean value); } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt index 585a5ab..454337e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt @@ -71,7 +71,7 @@ class CursorMouseInputHandler @Inject constructor( } private fun getPlayerHeadRotation(mouseWorldX: Float, mouseWorldY: Float): Float { - val h = mouseWorldX - player.x + val h = mouseWorldX - (player.x + player.width / 2) val v = mouseWorldY - player.y return MathUtils.atan(v / h) * MathUtils.radDeg @@ -88,6 +88,12 @@ class CursorMouseInputHandler @Inject constructor( player.cursorY = worldY.bl player.headRotation = getPlayerHeadRotation(worldX, worldY) + + if (worldX < player.x + player.width / 2) { + player.setDir(Mob.Direction.LEFT) + } else { + player.setDir(Mob.Direction.RIGHT) + } } private fun getCreativeTooltip(action: MouseInputAction): String? { @@ -125,7 +131,10 @@ class CursorMouseInputHandler @Inject constructor( } player.checkCursorBounds(gameWorld) - setPlayerDirectionToCursor() + + if (player.controlMode == Player.ControlMode.WALK && mainConfig.isTouch) { + setPlayerDirectionToCursor() + } if (player.cursorX != pastCursorX || player.cursorY != pastCursorY) { player.blockDamage = 0f diff --git a/core/src/ru/deadsoftware/cavedroid/menu/MenuProc.java b/core/src/ru/deadsoftware/cavedroid/menu/MenuProc.java index 5314809..aa3888a 100644 --- a/core/src/ru/deadsoftware/cavedroid/menu/MenuProc.java +++ b/core/src/ru/deadsoftware/cavedroid/menu/MenuProc.java @@ -10,9 +10,7 @@ import ru.deadsoftware.cavedroid.misc.Renderer; import javax.inject.Inject; -import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -54,8 +52,8 @@ public class MenuProc extends Renderer { mCurrentMenu = mMenuMain; } - public void toggleDynamicCamera() { - mMainConfig.setUseDynamicCamera(!mMainConfig.isUseDynamicCamera()); + public void setPreference(String key, Object value) { + mMainConfig.setPreference(key, value.toString()); } } diff --git a/core/src/ru/deadsoftware/cavedroid/menu/objects/BooleanOptionButton.kt b/core/src/ru/deadsoftware/cavedroid/menu/objects/BooleanOptionButton.kt new file mode 100644 index 0000000..56329d5 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/menu/objects/BooleanOptionButton.kt @@ -0,0 +1,29 @@ +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/ru/deadsoftware/cavedroid/menu/submenus/Menu.java b/core/src/ru/deadsoftware/cavedroid/menu/submenus/Menu.java index 587d0f6..7e793b7 100644 --- a/core/src/ru/deadsoftware/cavedroid/menu/submenus/Menu.java +++ b/core/src/ru/deadsoftware/cavedroid/menu/submenus/Menu.java @@ -1,13 +1,16 @@ 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 kotlin.text.StringsKt; 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; @@ -76,13 +79,27 @@ public abstract class Menu { 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) { - buttons.put(key.name(), - new Button(Assets.getStringFromJson(key, "label", ""), - (int) mWidth / 2 - Button.WIDTH / 2, - Assets.getIntFromJson(key, "y", y), - Assets.getIntFromJson(key, "type", Button.NORMAL), - eventListeners.containsKey(key.name()) ? eventListeners.get(key.name()) : () -> { - })); + + 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); } } diff --git a/core/src/ru/deadsoftware/cavedroid/menu/submenus/MenuOptions.kt b/core/src/ru/deadsoftware/cavedroid/menu/submenus/MenuOptions.kt index 2b72bd6..7cc8a90 100644 --- a/core/src/ru/deadsoftware/cavedroid/menu/submenus/MenuOptions.kt +++ b/core/src/ru/deadsoftware/cavedroid/menu/submenus/MenuOptions.kt @@ -17,7 +17,6 @@ class MenuOptions( override fun getButtonEventListeners(): HashMap { val map = HashMap() - map["dyncam"] = ButtonEventListener { mMenuInput.toggleDynamicCamera() } map["back"] = ButtonEventListener { mMenuInput.backClicked() } return map } diff --git a/core/src/ru/deadsoftware/cavedroid/prefs/PreferencesStore.kt b/core/src/ru/deadsoftware/cavedroid/prefs/PreferencesStore.kt new file mode 100644 index 0000000..edc9517 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/prefs/PreferencesStore.kt @@ -0,0 +1,9 @@ +package ru.deadsoftware.cavedroid.prefs + +interface PreferencesStore { + + fun getPreference(key: String): String? + + fun setPreference(key: String, value: String?) + +} diff --git a/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopLauncher.java b/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopLauncher.java index fe78235..146d52a 100644 --- a/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopLauncher.java +++ b/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopLauncher.java @@ -34,7 +34,8 @@ class DesktopLauncher { } } - CaveGame caveGame = new CaveGame(System.getProperty("user.home") + "/.cavedroid", touch, assetsPath); + CaveGame caveGame = new CaveGame(System.getProperty("user.home") + "/.cavedroid", touch, + new DesktopPreferencesStore(), assetsPath); caveGame.setDebug(debug); new Lwjgl3Application(caveGame, config); diff --git a/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopPreferencesStore.kt b/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopPreferencesStore.kt new file mode 100644 index 0000000..03591bb --- /dev/null +++ b/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopPreferencesStore.kt @@ -0,0 +1,18 @@ +package ru.deadsoftware.cavedroid.desktop + +import ru.deadsoftware.cavedroid.prefs.PreferencesStore +import java.util.prefs.Preferences + +class DesktopPreferencesStore : PreferencesStore { + + private val prefs = Preferences.userNodeForPackage(DesktopPreferencesStore::class.java) + + override fun getPreference(key: String): String? { + return prefs.get(key, null) + } + + override fun setPreference(key: String, value: String?) { + prefs.put(key, value) + } + +} \ No newline at end of file -- 2.29.2 From 9c3388a824844afa4b28b973049eaae75a21b05a Mon Sep 17 00:00:00 2001 From: fredboy Date: Tue, 14 May 2024 18:26:34 +0700 Subject: [PATCH 02/16] Move dependencies inside module scripts --- android/build.gradle | 19 +++++++++++++++++ build.gradle | 51 ++------------------------------------------ core/build.gradle | 16 +++++++++++--- desktop/build.gradle | 15 ++++++++++--- 4 files changed, 46 insertions(+), 55 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 80d010c..bf1af00 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,4 +1,9 @@ +buildscript { + configurations { natives } +} + plugins { + id "com.android.application" id "kotlin-android" } @@ -123,4 +128,18 @@ task run(type: Exec) { def adb = path + "/platform-tools/adb" commandLine "$adb", 'shell', 'am', 'start', '-n', 'ru.deadsoftware.cavedroid/ru.deadsoftware.cavedroid.AndroidLauncher' +} + +dependencies { + implementation project(":core") + implementation platform("org.jetbrains.kotlin:kotlin-bom:$kotlinVersion") + api "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion" + natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a" + natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-arm64-v8a" + natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86" + natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64" + + configurations.implementation { + exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8' + } } \ No newline at end of file diff --git a/build.gradle b/build.gradle index 2a9831a..e782b87 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,11 @@ buildscript { - ext { appName = "CaveDroid" gdxVersion = '1.12.0' guavaVersion = '28.1' daggerVersion = '2.51.1' - kotlinVersion = '1.9.23' + kotlinVersion = '1.9.24' + kspVersion = '1.9.24-1.0.20' kotlinSerializationVersion = '1.6.3' } @@ -24,7 +24,6 @@ buildscript { } allprojects { - version = 'alpha0.9.2' repositories { @@ -36,49 +35,3 @@ allprojects { maven { url "https://jitpack.io" } } } - -project(":desktop") { - apply plugin: "java-library" - - dependencies { - implementation project(":core") - implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinSerializationVersion" - api "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion" - api "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" - } -} - -project(":android") { - apply plugin: "android" - - configurations { natives } - - dependencies { - implementation project(":core") - implementation platform("org.jetbrains.kotlin:kotlin-bom:1.9.23") - api "com.badlogicgames.gdx:gdx-backend-android:$gdxVersion" - natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-armeabi-v7a" - natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-arm64-v8a" - natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86" - natives "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-x86_64" - - configurations.implementation { - exclude group: 'org.jetbrains.kotlin', module: 'kotlin-stdlib-jdk8' - } - } -} - -project(":core") { - apply plugin: "java-library" - - - dependencies { - api "com.badlogicgames.gdx:gdx:$gdxVersion" - api "com.google.guava:guava:$guavaVersion-android" - api "com.google.dagger:dagger:$daggerVersion" - implementation 'org.jetbrains:annotations:23.1.0' - implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" - implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinSerializationVersion" - annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" - } -} \ No newline at end of file diff --git a/core/build.gradle b/core/build.gradle index cdf2ee7..4837be7 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -1,12 +1,22 @@ plugins { + id "java-library" id "org.jetbrains.kotlin.jvm" id "kotlin" id "idea" id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlinVersion" } -sourceCompatibility = 17 +java.targetCompatibility = JavaVersion.VERSION_17 +java.sourceCompatibility = JavaVersion.VERSION_17 -sourceSets.main.java.srcDirs = [ "src/" ] +sourceSets.main.java.srcDirs = ["src/"] -java.targetCompatibility = JavaVersion.VERSION_17 \ No newline at end of file +dependencies { + api "com.badlogicgames.gdx:gdx:$gdxVersion" + api "com.google.guava:guava:$guavaVersion-android" + api "com.google.dagger:dagger:$daggerVersion" + implementation 'org.jetbrains:annotations:23.1.0' + implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" + implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinSerializationVersion" + annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" +} \ No newline at end of file diff --git a/desktop/build.gradle b/desktop/build.gradle index 70a63ba..04317e4 100644 --- a/desktop/build.gradle +++ b/desktop/build.gradle @@ -1,10 +1,13 @@ plugins { + id 'java-library' id 'kotlin' id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlinVersion" } -sourceCompatibility = 17 -sourceSets.main.java.srcDirs = [ "src/" ] +java.targetCompatibility = JavaVersion.VERSION_17 +java.sourceCompatibility = JavaVersion.VERSION_1_8 + +sourceSets.main.java.srcDirs = ["src/"] sourceSets.main.resources.srcDirs = ["../android/assets"] project.ext.mainClassName = "ru.deadsoftware.cavedroid.desktop.DesktopLauncher" @@ -48,5 +51,11 @@ task dist(type: Jar) { with jar } +dist.dependsOn classes -dist.dependsOn classes \ No newline at end of file +dependencies { + implementation project(":core") + implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinSerializationVersion" + api "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion" + api "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop" +} -- 2.29.2 From 5883a846d9cb1e2fa225fc7ac9e1e59d5805c7f0 Mon Sep 17 00:00:00 2001 From: fredboy Date: Tue, 14 May 2024 18:27:03 +0700 Subject: [PATCH 03/16] Add ksp module --- dagger-multibind-ksp/build.gradle | 12 ++++++++++++ settings.gradle | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 dagger-multibind-ksp/build.gradle diff --git a/dagger-multibind-ksp/build.gradle b/dagger-multibind-ksp/build.gradle new file mode 100644 index 0000000..ea5375f --- /dev/null +++ b/dagger-multibind-ksp/build.gradle @@ -0,0 +1,12 @@ +plugins { + id 'kotlin' + id 'com.google.devtools.ksp' version "$kspVersion" +} + +repositories { + mavenCentral() +} + +kotlin { + jvmToolchain(17) +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 77ae463..257dfd5 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1 +1,7 @@ -include 'desktop', 'android', 'core' \ No newline at end of file +plugins { + id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0' +} + +include 'desktop', 'android', 'core' +include 'dagger-multibind-ksp' + -- 2.29.2 From 4e63a1e672fcf47fab405eb660f7020b6f5c0283 Mon Sep 17 00:00:00 2001 From: fredboy Date: Tue, 14 May 2024 19:42:52 +0700 Subject: [PATCH 04/16] Add module code gen --- build.gradle | 6 ++ core/build.gradle | 2 + dagger-multibind-annotations/build.gradle | 7 ++ .../actions/PlaceBlockAction.kt | 5 ++ .../actions/UpdateBlockAction.kt | 5 ++ .../actions/UseBlockAction.kt | 5 ++ .../actions/UseItemAction.kt | 5 ++ .../input/KeyboardInputHandler.kt | 5 ++ .../input/MouseInputHandler.kt | 5 ++ .../render/Renderer.kt | 5 ++ dagger-multibind-ksp/build.gradle | 12 ++-- .../ksp/processor/RendererSymbolProcessor.kt | 66 +++++++++++++++++++ .../ksp/processor/SymbolProcessorUtils.kt | 17 +++++ .../RendererSymbolProcessorProvider.kt | 16 +++++ ...ols.ksp.processing.SymbolProcessorProvider | 1 + settings.gradle | 1 + 16 files changed, 158 insertions(+), 5 deletions(-) create mode 100644 dagger-multibind-annotations/build.gradle create mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/PlaceBlockAction.kt create mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UpdateBlockAction.kt create mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseBlockAction.kt create mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseItemAction.kt create mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/KeyboardInputHandler.kt create mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/MouseInputHandler.kt create mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/render/Renderer.kt create mode 100644 dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/RendererSymbolProcessor.kt create mode 100644 dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/SymbolProcessorUtils.kt create mode 100644 dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/RendererSymbolProcessorProvider.kt create mode 100644 dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider diff --git a/build.gradle b/build.gradle index e782b87..1e317b0 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,18 @@ buildscript { ext { appName = "CaveDroid" + gdxVersion = '1.12.0' + guavaVersion = '28.1' + daggerVersion = '2.51.1' + kotlinVersion = '1.9.24' kspVersion = '1.9.24-1.0.20' kotlinSerializationVersion = '1.6.3' + + kotlinpoetKspVersion = '1.16.0' } repositories { diff --git a/core/build.gradle b/core/build.gradle index 4837be7..c160724 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -4,6 +4,7 @@ plugins { id "kotlin" id "idea" id 'org.jetbrains.kotlin.plugin.serialization' version "$kotlinVersion" + id 'com.google.devtools.ksp' version "$kspVersion" } java.targetCompatibility = JavaVersion.VERSION_17 @@ -19,4 +20,5 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinSerializationVersion" annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" + ksp project(':dagger-multibind-ksp') } \ No newline at end of file diff --git a/dagger-multibind-annotations/build.gradle b/dagger-multibind-annotations/build.gradle new file mode 100644 index 0000000..27133f0 --- /dev/null +++ b/dagger-multibind-annotations/build.gradle @@ -0,0 +1,7 @@ +plugins { + id 'kotlin' +} + +kotlin { + jvmToolchain(17) +} diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/PlaceBlockAction.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/PlaceBlockAction.kt new file mode 100644 index 0000000..2d3046e --- /dev/null +++ b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/PlaceBlockAction.kt @@ -0,0 +1,5 @@ +package ru.fredboy.cavedroid.ksp.annotations.actions + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.SOURCE) +annotation class PlaceBlockAction(val actionKey: String) diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UpdateBlockAction.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UpdateBlockAction.kt new file mode 100644 index 0000000..1ba6b87 --- /dev/null +++ b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UpdateBlockAction.kt @@ -0,0 +1,5 @@ +package ru.fredboy.cavedroid.ksp.annotations.actions + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.SOURCE) +annotation class UpdateBlockAction(val blockKey: String) diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseBlockAction.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseBlockAction.kt new file mode 100644 index 0000000..4e53819 --- /dev/null +++ b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseBlockAction.kt @@ -0,0 +1,5 @@ +package ru.fredboy.cavedroid.ksp.annotations.actions + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.SOURCE) +annotation class UseBlockAction(val blockKey: String) diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseItemAction.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseItemAction.kt new file mode 100644 index 0000000..fc47677 --- /dev/null +++ b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseItemAction.kt @@ -0,0 +1,5 @@ +package ru.fredboy.cavedroid.ksp.annotations.actions + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.SOURCE) +annotation class UseItemAction(val actionKey: String) diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/KeyboardInputHandler.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/KeyboardInputHandler.kt new file mode 100644 index 0000000..311a050 --- /dev/null +++ b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/KeyboardInputHandler.kt @@ -0,0 +1,5 @@ +package ru.fredboy.cavedroid.ksp.annotations.input + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.SOURCE) +annotation class KeyboardInputHandler diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/MouseInputHandler.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/MouseInputHandler.kt new file mode 100644 index 0000000..d3a630e --- /dev/null +++ b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/MouseInputHandler.kt @@ -0,0 +1,5 @@ +package ru.fredboy.cavedroid.ksp.annotations.input + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.SOURCE) +annotation class MouseInputHandler diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/render/Renderer.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/render/Renderer.kt new file mode 100644 index 0000000..8a813df --- /dev/null +++ b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/render/Renderer.kt @@ -0,0 +1,5 @@ +package ru.fredboy.cavedroid.ksp.annotations.render + +@Target(AnnotationTarget.CLASS) +@Retention(AnnotationRetention.SOURCE) +annotation class Renderer diff --git a/dagger-multibind-ksp/build.gradle b/dagger-multibind-ksp/build.gradle index ea5375f..e73405d 100644 --- a/dagger-multibind-ksp/build.gradle +++ b/dagger-multibind-ksp/build.gradle @@ -3,10 +3,12 @@ plugins { id 'com.google.devtools.ksp' version "$kspVersion" } -repositories { - mavenCentral() -} - kotlin { jvmToolchain(17) -} \ No newline at end of file +} + +dependencies { + implementation project(':dagger-multibind-annotations') + implementation "com.squareup:kotlinpoet-ksp:$kotlinpoetKspVersion" + implementation "com.google.devtools.ksp:symbol-processing-api:$kspVersion" +} diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/RendererSymbolProcessor.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/RendererSymbolProcessor.kt new file mode 100644 index 0000000..d97c2ab --- /dev/null +++ b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/RendererSymbolProcessor.kt @@ -0,0 +1,66 @@ +package ru.fredboy.cavedroid.ksp.processor + +import com.google.devtools.ksp.processing.CodeGenerator +import com.google.devtools.ksp.processing.Dependencies +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.processing.SymbolProcessor +import com.google.devtools.ksp.symbol.KSAnnotated +import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.squareup.kotlinpoet.* +import com.squareup.kotlinpoet.ksp.toClassName +import com.squareup.kotlinpoet.ksp.writeTo +import ru.fredboy.cavedroid.ksp.annotations.render.Renderer +import java.lang.reflect.Type + +internal class RendererSymbolProcessor( + private val codeGenerator: CodeGenerator, +) : SymbolProcessor { + + private fun generateModule(renderers: List): FileSpec? { + if (renderers.isEmpty()) { + return null + } + + val bindings = renderers.map { renderer -> + FunSpec.builder("bind${renderer.simpleName}") + .addAnnotation(ClassName("dagger", "Binds")) + .addAnnotation(ClassName("dagger", "IntoSet")) + .addAnnotations(renderer.annotations) + .addParameter(ParameterSpec("renderer", renderer)) + .returns(IGameRendererType) + .beginControlFlow("return renderer") + .build() + } + + val moduleObject = TypeSpec.objectBuilder(MODULE_NAME) + .addAnnotation(ClassName("dagger", "Module")) + .addFunctions(bindings) + .build() + + return FileSpec.builder(MODULE_PACKAGE, MODULE_NAME) +// .addImport("dagger", "Binds", "Module", "IntoSet") +// .addImport("ru.deadsoftware.cavedroid.game", "GameScope") + .addType(moduleObject) + .build() + + } + + override fun process(resolver: Resolver): List { + generateModule( + resolver.getAnnotatedClasses(MODULE_PACKAGE, Renderer::class) + .map(KSClassDeclaration::toClassName) + .toList() + )?.writeTo(codeGenerator, Dependencies(true)) + + return emptyList() + } + + private object IGameRendererType : Type { + override fun getTypeName(): String = "IGameRenderer" + } + + companion object { + private const val MODULE_PACKAGE = "ru.deadsoftware.cavedroid.game.render" + private const val MODULE_NAME = "RenderModule" + } +} \ No newline at end of file diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/SymbolProcessorUtils.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/SymbolProcessorUtils.kt new file mode 100644 index 0000000..0b0e0b9 --- /dev/null +++ b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/SymbolProcessorUtils.kt @@ -0,0 +1,17 @@ +package ru.fredboy.cavedroid.ksp.processor + +import com.google.devtools.ksp.processing.Resolver +import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.google.devtools.ksp.symbol.KSNode +import com.google.devtools.ksp.validate +import kotlin.reflect.KClass + +internal fun Resolver.getAnnotatedClasses( + packageName: String, + annotationClass: KClass<*> +): Sequence { + return getSymbolsWithAnnotation(annotationClass.qualifiedName.orEmpty()) + .filterIsInstance() + .filter { it.packageName.getShortName() == packageName } + .filter(KSNode::validate) +} \ No newline at end of file diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/RendererSymbolProcessorProvider.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/RendererSymbolProcessorProvider.kt new file mode 100644 index 0000000..eedf89b --- /dev/null +++ b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/RendererSymbolProcessorProvider.kt @@ -0,0 +1,16 @@ +package ru.fredboy.cavedroid.ksp.provider + +import com.google.devtools.ksp.processing.SymbolProcessor +import com.google.devtools.ksp.processing.SymbolProcessorEnvironment +import com.google.devtools.ksp.processing.SymbolProcessorProvider +import ru.fredboy.cavedroid.ksp.processor.RendererSymbolProcessor + +internal class RendererSymbolProcessorProvider : SymbolProcessorProvider { + + override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { + return RendererSymbolProcessor( + codeGenerator = environment.codeGenerator, + ) + } + +} \ No newline at end of file diff --git a/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider new file mode 100644 index 0000000..a8a853f --- /dev/null +++ b/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider @@ -0,0 +1 @@ +ru.fredboy.cavedroid.ksp.provider.RendererSymbolProcessorProvider diff --git a/settings.gradle b/settings.gradle index 257dfd5..c441146 100644 --- a/settings.gradle +++ b/settings.gradle @@ -3,5 +3,6 @@ plugins { } include 'desktop', 'android', 'core' +include 'dagger-multibind-annotations' include 'dagger-multibind-ksp' -- 2.29.2 From f50a0d30230d2e6dbb8dbc0587a2dd8950761ae5 Mon Sep 17 00:00:00 2001 From: fredboy Date: Tue, 14 May 2024 20:37:29 +0700 Subject: [PATCH 05/16] Add RenderModule code generation --- .gitignore | 2 + core/build.gradle | 4 +- .../game/render/BackgroundBlocksRenderer.kt | 1 + .../cavedroid/game/render/DebugRenderer.kt | 2 +- .../cavedroid/game/render/DropsRenderer.kt | 1 + .../game/render/ForegroundBlocksRenderer.kt | 1 + .../cavedroid/game/render/GameRenderer.kt | 10 +++ .../cavedroid/game/render/HudRenderer.kt | 1 + .../cavedroid/game/render/MobsRenderer.kt | 1 + .../cavedroid/game/render/RenderModule.kt | 59 -------------- .../game/render/TouchControlsRenderer.kt | 1 + .../cavedroid/game/render/WindowsRenderer.kt | 1 + .../GenerateSetMultibindingsModule.kt | 11 +++ .../actions/PlaceBlockAction.kt | 5 -- .../actions/UpdateBlockAction.kt | 5 -- .../actions/UseBlockAction.kt | 5 -- .../actions/UseItemAction.kt | 5 -- .../input/KeyboardInputHandler.kt | 5 -- .../input/MouseInputHandler.kt | 5 -- .../render/Renderer.kt | 5 -- ...GenerateSetMultibindingsSymbolProcessor.kt | 81 +++++++++++++++++++ .../ksp/processor/RendererSymbolProcessor.kt | 66 --------------- .../ksp/processor/SymbolProcessorUtils.kt | 9 ++- ...etMultibindingsSymbolProcessorProvider.kt} | 7 +- ...ols.ksp.processing.SymbolProcessorProvider | 2 +- desktop/build.gradle | 4 +- 26 files changed, 127 insertions(+), 172 deletions(-) create mode 100644 core/src/ru/deadsoftware/cavedroid/game/render/GameRenderer.kt delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/render/RenderModule.kt create mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateSetMultibindingsModule.kt delete mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/PlaceBlockAction.kt delete mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UpdateBlockAction.kt delete mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseBlockAction.kt delete mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseItemAction.kt delete mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/KeyboardInputHandler.kt delete mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/MouseInputHandler.kt delete mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/render/Renderer.kt create mode 100644 dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateSetMultibindingsSymbolProcessor.kt delete mode 100644 dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/RendererSymbolProcessor.kt rename dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/{RendererSymbolProcessorProvider.kt => GenerateSetMultibindingsSymbolProcessorProvider.kt} (59%) diff --git a/.gitignore b/.gitignore index e03f558..b24a8ed 100644 --- a/.gitignore +++ b/.gitignore @@ -119,3 +119,5 @@ Thumbs.db release-*/ keystore.properties + +*/build/ diff --git a/core/build.gradle b/core/build.gradle index c160724..0cff94f 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -13,6 +13,9 @@ java.sourceCompatibility = JavaVersion.VERSION_17 sourceSets.main.java.srcDirs = ["src/"] dependencies { + implementation project(':dagger-multibind-annotations') + ksp project(':dagger-multibind-ksp') + api "com.badlogicgames.gdx:gdx:$gdxVersion" api "com.google.guava:guava:$guavaVersion-android" api "com.google.dagger:dagger:$daggerVersion" @@ -20,5 +23,4 @@ dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinSerializationVersion" annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" - ksp project(':dagger-multibind-ksp') } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/BackgroundBlocksRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/BackgroundBlocksRenderer.kt index aae4f98..e86450c 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/BackgroundBlocksRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/BackgroundBlocksRenderer.kt @@ -12,6 +12,7 @@ import ru.deadsoftware.cavedroid.misc.utils.forEachBlockInArea import javax.inject.Inject @GameScope +@GameRenderer class BackgroundBlocksRenderer @Inject constructor( gameWorld: GameWorld, mobsController: MobsController diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/DebugRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/DebugRenderer.kt index 03f6253..d1a1d16 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/DebugRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/DebugRenderer.kt @@ -10,13 +10,13 @@ import ru.deadsoftware.cavedroid.game.debug.DebugInfoStringsProvider import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.block.Block import ru.deadsoftware.cavedroid.game.world.GameWorld -import ru.deadsoftware.cavedroid.misc.Assets import ru.deadsoftware.cavedroid.misc.utils.bl import ru.deadsoftware.cavedroid.misc.utils.drawString import ru.deadsoftware.cavedroid.misc.utils.forEachBlockInArea import ru.deadsoftware.cavedroid.misc.utils.px import javax.inject.Inject +@GameRenderer @GameScope class DebugRenderer @Inject constructor( private val mainConfig: MainConfig, diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt index f14d36b..5e1da4a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt @@ -12,6 +12,7 @@ import ru.deadsoftware.cavedroid.misc.utils.px import javax.inject.Inject @GameScope +@GameRenderer class DropsRenderer @Inject constructor( private val dropController: DropController, private val gameWorld: GameWorld, diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/ForegroundBlocksRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/ForegroundBlocksRenderer.kt index ef8be71..0bb4001 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/ForegroundBlocksRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/ForegroundBlocksRenderer.kt @@ -10,6 +10,7 @@ import ru.deadsoftware.cavedroid.misc.utils.forEachBlockInArea import javax.inject.Inject @GameScope +@GameRenderer class ForegroundBlocksRenderer @Inject constructor( gameWorld: GameWorld, mobsController: MobsController diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/GameRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/GameRenderer.kt new file mode 100644 index 0000000..7e40f17 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/render/GameRenderer.kt @@ -0,0 +1,10 @@ +package ru.deadsoftware.cavedroid.game.render + +import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule + +@GenerateSetMultibindingsModule( + interfaceClass = IGameRenderer::class, + modulePackage = "ru.deadsoftware.cavedroid.game.render", + moduleName = "RenderModule" +) +annotation class GameRenderer diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt index a2570e2..cb70e16 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt @@ -15,6 +15,7 @@ import ru.deadsoftware.cavedroid.misc.utils.px import javax.inject.Inject @GameScope +@GameRenderer class HudRenderer @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/MobsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/MobsRenderer.kt index 6d388bb..ab1dd01 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/MobsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/MobsRenderer.kt @@ -12,6 +12,7 @@ import ru.deadsoftware.cavedroid.misc.utils.px import javax.inject.Inject @GameScope +@GameRenderer class MobsRenderer @Inject constructor( private val mobsController: MobsController, private val gameWorld: GameWorld, diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/RenderModule.kt b/core/src/ru/deadsoftware/cavedroid/game/render/RenderModule.kt deleted file mode 100644 index 9ae3b46..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/render/RenderModule.kt +++ /dev/null @@ -1,59 +0,0 @@ -package ru.deadsoftware.cavedroid.game.render - -import dagger.Binds -import dagger.Module -import dagger.multibindings.IntoSet -import ru.deadsoftware.cavedroid.game.GameScope - -@Module -object RenderModule { - - @Binds - @IntoSet - @GameScope - fun bindBackGroundBlocksRenderer(renderer: BackgroundBlocksRenderer): IGameRenderer = renderer - - @Binds - @IntoSet - @GameScope - fun bindForegroundBlocksRenderer(renderer: ForegroundBlocksRenderer): IGameRenderer = renderer - - @Binds - @IntoSet - @GameScope - fun bindMobsRenderer(renderer: MobsRenderer): IGameRenderer = renderer - - @Binds - @IntoSet - @GameScope - fun bindDropsRenderer(renderer: DropsRenderer): IGameRenderer = renderer - - @Binds - @IntoSet - @GameScope - fun bindHudRenderer(renderer: HudRenderer): IGameRenderer = renderer - - @Binds - @IntoSet - @GameScope - fun bindWindowsRenderer(renderer: WindowsRenderer): IGameRenderer = renderer - - @Binds - @IntoSet - @GameScope - fun bindTouchControlsRenderer(renderer: TouchControlsRenderer): IGameRenderer = renderer - - @Binds - @IntoSet - @GameScope - fun bindDebugRenderer(renderer: DebugRenderer): IGameRenderer = renderer - -// @Provides -// @GameScope -// fun provideGameRenderers(renderers: Set<@JvmSuppressWildcards IGameRenderer>): List { -// return renderers.asSequence() -// .sortedWith(Comparator.comparingInt(IGameRenderer::renderLayer)) -// .toList() -// } - -} diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt index 63aa09f..29702ae 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt @@ -17,6 +17,7 @@ import ru.deadsoftware.cavedroid.misc.utils.drawSprite import javax.inject.Inject @GameScope +@GameRenderer class TouchControlsRenderer @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt index fa37f8d..4e65b41 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt @@ -11,6 +11,7 @@ import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject @GameScope +@GameRenderer class WindowsRenderer @Inject constructor( private val creativeWindowRenderer: CreativeWindowRenderer, private val survivalWindowRenderer: SurvivalWindowRenderer, diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateSetMultibindingsModule.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateSetMultibindingsModule.kt new file mode 100644 index 0000000..2fb4915 --- /dev/null +++ b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateSetMultibindingsModule.kt @@ -0,0 +1,11 @@ +package ru.fredboy.cavedroid.ksp.annotations + +import kotlin.reflect.KClass + +@Target(AnnotationTarget.ANNOTATION_CLASS) +@Retention(AnnotationRetention.SOURCE) +annotation class GenerateSetMultibindingsModule( + val interfaceClass: KClass<*>, + val modulePackage: String, + val moduleName: String, +) diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/PlaceBlockAction.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/PlaceBlockAction.kt deleted file mode 100644 index 2d3046e..0000000 --- a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/PlaceBlockAction.kt +++ /dev/null @@ -1,5 +0,0 @@ -package ru.fredboy.cavedroid.ksp.annotations.actions - -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.SOURCE) -annotation class PlaceBlockAction(val actionKey: String) diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UpdateBlockAction.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UpdateBlockAction.kt deleted file mode 100644 index 1ba6b87..0000000 --- a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UpdateBlockAction.kt +++ /dev/null @@ -1,5 +0,0 @@ -package ru.fredboy.cavedroid.ksp.annotations.actions - -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.SOURCE) -annotation class UpdateBlockAction(val blockKey: String) diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseBlockAction.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseBlockAction.kt deleted file mode 100644 index 4e53819..0000000 --- a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseBlockAction.kt +++ /dev/null @@ -1,5 +0,0 @@ -package ru.fredboy.cavedroid.ksp.annotations.actions - -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.SOURCE) -annotation class UseBlockAction(val blockKey: String) diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseItemAction.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseItemAction.kt deleted file mode 100644 index fc47677..0000000 --- a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/actions/UseItemAction.kt +++ /dev/null @@ -1,5 +0,0 @@ -package ru.fredboy.cavedroid.ksp.annotations.actions - -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.SOURCE) -annotation class UseItemAction(val actionKey: String) diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/KeyboardInputHandler.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/KeyboardInputHandler.kt deleted file mode 100644 index 311a050..0000000 --- a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/KeyboardInputHandler.kt +++ /dev/null @@ -1,5 +0,0 @@ -package ru.fredboy.cavedroid.ksp.annotations.input - -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.SOURCE) -annotation class KeyboardInputHandler diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/MouseInputHandler.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/MouseInputHandler.kt deleted file mode 100644 index d3a630e..0000000 --- a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/input/MouseInputHandler.kt +++ /dev/null @@ -1,5 +0,0 @@ -package ru.fredboy.cavedroid.ksp.annotations.input - -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.SOURCE) -annotation class MouseInputHandler diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/render/Renderer.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/render/Renderer.kt deleted file mode 100644 index 8a813df..0000000 --- a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/render/Renderer.kt +++ /dev/null @@ -1,5 +0,0 @@ -package ru.fredboy.cavedroid.ksp.annotations.render - -@Target(AnnotationTarget.CLASS) -@Retention(AnnotationRetention.SOURCE) -annotation class Renderer diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateSetMultibindingsSymbolProcessor.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateSetMultibindingsSymbolProcessor.kt new file mode 100644 index 0000000..18cd3c9 --- /dev/null +++ b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateSetMultibindingsSymbolProcessor.kt @@ -0,0 +1,81 @@ +package ru.fredboy.cavedroid.ksp.processor + +import com.google.devtools.ksp.processing.* +import com.google.devtools.ksp.symbol.KSAnnotated +import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.google.devtools.ksp.symbol.KSType +import com.squareup.kotlinpoet.* +import com.squareup.kotlinpoet.ksp.toClassName +import com.squareup.kotlinpoet.ksp.writeTo +import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule + +class GenerateSetMultibindingsSymbolProcessor( + private val codeGenerator: CodeGenerator, + private val logger: KSPLogger, +) : SymbolProcessor { + + private fun generateModule( + interfaceName: ClassName, + moduleName: ClassName, + classes: List + ): FileSpec? { + if (classes.isEmpty()) { + return null + } + + val bindings = classes.map { clazz -> + FunSpec.builder("bind${clazz.simpleName}") + .addAnnotation(ClassName("dagger", "Binds")) + .addAnnotation(ClassName("dagger.multibindings", "IntoSet")) + .addParameter(ParameterSpec("impl", clazz)) + .returns(interfaceName) + .addCode("return impl") + .build() + } + + val moduleObject = TypeSpec.objectBuilder(moduleName) + .addAnnotation(ClassName("dagger", "Module")) + .addFunctions(bindings) + .build() + + return FileSpec.builder(moduleName) + .addType(moduleObject) + .build() + + } + + private fun processAnnotation(resolver: Resolver, annotation: KSClassDeclaration) { + val args = annotation.annotations.first { + it.shortName.getShortName() == "GenerateSetMultibindingsModule" + }.arguments.takeIf { it.size == 3 } ?: run { + logger.error("GenerateSetMultibindingsModule should have 3 arguments") + throw IllegalArgumentException() + } + + val interfaceName = args.first { it.name?.getShortName() == "interfaceClass" }.value as KSType + val modulePackage = args.first { it.name?.getShortName() == "modulePackage" }.value as String + val moduleName = args.first { it.name?.getShortName() == "moduleName" }.value as String + + val moduleClassName = ClassName(modulePackage, moduleName) + val elements = resolver.getSymbolsWithAnnotation(annotation.qualifiedName!!.asString()) + .filterIsInstance() + .map(KSClassDeclaration::toClassName) + .toList() + + logger.info("Found elements: ${elements.joinToString()}") + + generateModule( + interfaceName = interfaceName.toClassName(), + moduleName = moduleClassName, + classes = elements + )?.writeTo(codeGenerator, Dependencies(true)) + } + + override fun process(resolver: Resolver): List { + val annotations = resolver.getAnnotatedClasses(GenerateSetMultibindingsModule::class.qualifiedName!!, logger) + logger.info("Found annotations: ${annotations.joinToString { it.qualifiedName!!.asString() }}") + annotations.forEach { processAnnotation(resolver, it) } + return emptyList() + } + +} \ No newline at end of file diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/RendererSymbolProcessor.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/RendererSymbolProcessor.kt deleted file mode 100644 index d97c2ab..0000000 --- a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/RendererSymbolProcessor.kt +++ /dev/null @@ -1,66 +0,0 @@ -package ru.fredboy.cavedroid.ksp.processor - -import com.google.devtools.ksp.processing.CodeGenerator -import com.google.devtools.ksp.processing.Dependencies -import com.google.devtools.ksp.processing.Resolver -import com.google.devtools.ksp.processing.SymbolProcessor -import com.google.devtools.ksp.symbol.KSAnnotated -import com.google.devtools.ksp.symbol.KSClassDeclaration -import com.squareup.kotlinpoet.* -import com.squareup.kotlinpoet.ksp.toClassName -import com.squareup.kotlinpoet.ksp.writeTo -import ru.fredboy.cavedroid.ksp.annotations.render.Renderer -import java.lang.reflect.Type - -internal class RendererSymbolProcessor( - private val codeGenerator: CodeGenerator, -) : SymbolProcessor { - - private fun generateModule(renderers: List): FileSpec? { - if (renderers.isEmpty()) { - return null - } - - val bindings = renderers.map { renderer -> - FunSpec.builder("bind${renderer.simpleName}") - .addAnnotation(ClassName("dagger", "Binds")) - .addAnnotation(ClassName("dagger", "IntoSet")) - .addAnnotations(renderer.annotations) - .addParameter(ParameterSpec("renderer", renderer)) - .returns(IGameRendererType) - .beginControlFlow("return renderer") - .build() - } - - val moduleObject = TypeSpec.objectBuilder(MODULE_NAME) - .addAnnotation(ClassName("dagger", "Module")) - .addFunctions(bindings) - .build() - - return FileSpec.builder(MODULE_PACKAGE, MODULE_NAME) -// .addImport("dagger", "Binds", "Module", "IntoSet") -// .addImport("ru.deadsoftware.cavedroid.game", "GameScope") - .addType(moduleObject) - .build() - - } - - override fun process(resolver: Resolver): List { - generateModule( - resolver.getAnnotatedClasses(MODULE_PACKAGE, Renderer::class) - .map(KSClassDeclaration::toClassName) - .toList() - )?.writeTo(codeGenerator, Dependencies(true)) - - return emptyList() - } - - private object IGameRendererType : Type { - override fun getTypeName(): String = "IGameRenderer" - } - - companion object { - private const val MODULE_PACKAGE = "ru.deadsoftware.cavedroid.game.render" - private const val MODULE_NAME = "RenderModule" - } -} \ No newline at end of file diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/SymbolProcessorUtils.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/SymbolProcessorUtils.kt index 0b0e0b9..1ac8a6a 100644 --- a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/SymbolProcessorUtils.kt +++ b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/SymbolProcessorUtils.kt @@ -1,5 +1,6 @@ package ru.fredboy.cavedroid.ksp.processor +import com.google.devtools.ksp.processing.KSPLogger import com.google.devtools.ksp.processing.Resolver import com.google.devtools.ksp.symbol.KSClassDeclaration import com.google.devtools.ksp.symbol.KSNode @@ -7,11 +8,11 @@ import com.google.devtools.ksp.validate import kotlin.reflect.KClass internal fun Resolver.getAnnotatedClasses( - packageName: String, - annotationClass: KClass<*> + annotation: String, + logger: KSPLogger, ): Sequence { - return getSymbolsWithAnnotation(annotationClass.qualifiedName.orEmpty()) + logger.info("Resolving annotation $annotation") + return getSymbolsWithAnnotation(annotation) .filterIsInstance() - .filter { it.packageName.getShortName() == packageName } .filter(KSNode::validate) } \ No newline at end of file diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/RendererSymbolProcessorProvider.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateSetMultibindingsSymbolProcessorProvider.kt similarity index 59% rename from dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/RendererSymbolProcessorProvider.kt rename to dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateSetMultibindingsSymbolProcessorProvider.kt index eedf89b..c8f4e15 100644 --- a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/RendererSymbolProcessorProvider.kt +++ b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateSetMultibindingsSymbolProcessorProvider.kt @@ -3,13 +3,14 @@ package ru.fredboy.cavedroid.ksp.provider import com.google.devtools.ksp.processing.SymbolProcessor import com.google.devtools.ksp.processing.SymbolProcessorEnvironment import com.google.devtools.ksp.processing.SymbolProcessorProvider -import ru.fredboy.cavedroid.ksp.processor.RendererSymbolProcessor +import ru.fredboy.cavedroid.ksp.processor.GenerateSetMultibindingsSymbolProcessor -internal class RendererSymbolProcessorProvider : SymbolProcessorProvider { +internal class GenerateSetMultibindingsSymbolProcessorProvider : SymbolProcessorProvider { override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { - return RendererSymbolProcessor( + return GenerateSetMultibindingsSymbolProcessor( codeGenerator = environment.codeGenerator, + logger = environment.logger, ) } diff --git a/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider index a8a853f..293ff25 100644 --- a/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +++ b/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider @@ -1 +1 @@ -ru.fredboy.cavedroid.ksp.provider.RendererSymbolProcessorProvider +ru.fredboy.cavedroid.ksp.provider.GenerateSetMultibindingsSymbolProcessorProvider diff --git a/desktop/build.gradle b/desktop/build.gradle index 04317e4..58553a3 100644 --- a/desktop/build.gradle +++ b/desktop/build.gradle @@ -46,12 +46,12 @@ task dist(type: Jar) { attributes 'Main-Class': project.mainClassName } from { - configurations.compileClasspath.collect { it.isDirectory() ? it : zipTree(it) } + configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) } } with jar } -dist.dependsOn classes +dist.dependsOn build dependencies { implementation project(":core") -- 2.29.2 From ca67da5ca90819bdbf2f0cda78d28456a2b58d76 Mon Sep 17 00:00:00 2001 From: fredboy Date: Tue, 14 May 2024 23:16:13 +0700 Subject: [PATCH 06/16] Move IGameRenderer --- .../cavedroid/game/render/GameRenderer.kt | 18 +++++++++++++++++ .../cavedroid/game/render/IGameRenderer.kt | 20 ------------------- 2 files changed, 18 insertions(+), 20 deletions(-) delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/render/IGameRenderer.kt diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/GameRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/GameRenderer.kt index 7e40f17..c0ded1e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/GameRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/GameRenderer.kt @@ -1,5 +1,8 @@ package ru.deadsoftware.cavedroid.game.render +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import com.badlogic.gdx.graphics.glutils.ShapeRenderer +import com.badlogic.gdx.math.Rectangle import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule @GenerateSetMultibindingsModule( @@ -8,3 +11,18 @@ import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule moduleName = "RenderModule" ) annotation class GameRenderer + +interface IGameRenderer { + + val renderLayer: Int + + /** + * When called, [spriteBatch] is beginned! + */ + fun draw( + spriteBatch: SpriteBatch, + shapeRenderer: ShapeRenderer, + viewport: Rectangle, + delta: Float + ) +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/IGameRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/IGameRenderer.kt deleted file mode 100644 index 88b5744..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/render/IGameRenderer.kt +++ /dev/null @@ -1,20 +0,0 @@ -package ru.deadsoftware.cavedroid.game.render - -import com.badlogic.gdx.graphics.g2d.SpriteBatch -import com.badlogic.gdx.graphics.glutils.ShapeRenderer -import com.badlogic.gdx.math.Rectangle - -interface IGameRenderer { - - val renderLayer: Int - - /** - * When called, [spriteBatch] is beginned! - */ - fun draw( - spriteBatch: SpriteBatch, - shapeRenderer: ShapeRenderer, - viewport: Rectangle, - delta: Float - ) -} \ No newline at end of file -- 2.29.2 From ef72467133765381894c3af625e8644f96439642 Mon Sep 17 00:00:00 2001 From: fredboy Date: Tue, 14 May 2024 23:35:57 +0700 Subject: [PATCH 07/16] Input handler modules code generation --- .../cavedroid/game/GameRenderer.java | 15 +- .../cavedroid/game/input/GameInputHandler.kt | 40 +++++ .../cavedroid/game/input/IGameInputHandler.kt | 19 --- .../game/input/KeyboardInputHandlersModule.kt | 139 ------------------ .../game/input/MouseInputHandlersModule.kt | 97 ------------ .../CloseGameWindowKeyboardInputHandler.kt | 6 +- .../keyboard/DropItemKeyboardInputHandler.kt | 6 +- .../keyboard/FlyDownKeyboardInputHandler.kt | 6 +- .../keyboard/FlyUpKeyboardInputHandler.kt | 6 +- .../keyboard/GoLeftKeyboardInputHandler.kt | 6 +- .../keyboard/GoRightKeyboardInputHandler.kt | 6 +- .../keyboard/JumpKeyboardInputHandler.kt | 6 +- ...eCursorControlsModeKeyboardInputHandler.kt | 6 +- .../OpenInventoryKeyboardInputHandler.kt | 6 +- .../keyboard/PauseGameKeyboardInputHandler.kt | 6 +- .../SelectHotbarSlotKeyboardInputHandler.kt | 6 +- .../keyboard/StopSwimKeyboardInputHandler.kt | 6 +- .../keyboard/SwimUpKeyboardInputHandler.kt | 6 +- .../ToggleControlsModeKeyboardInputHandler.kt | 6 +- .../ToggleDebugInfoKeyboardInputHandler.kt | 6 +- .../ToggleGameModeKeyboardInputHandler.kt | 6 +- .../ToggleMinimapKeyboardInputHandler.kt | 6 +- .../TurnOnFlyModeKeyboardInputHandler.kt | 6 +- ...AbstractInventoryItemsMouseInputHandler.kt | 4 +- .../handler/mouse/AttackMouseInputHandler.kt | 6 +- .../mouse/CloseGameWindowMouseInputHandler.kt | 6 +- ...reativeInventoryScrollMouseInputHandler.kt | 6 +- .../handler/mouse/CursorMouseInputHandler.kt | 6 +- .../handler/mouse/HotbarMouseInputHandler.kt | 6 +- ...lectChestInventoryItemMouseInputHandler.kt | 2 + ...tCraftingInventoryItemMouseInputHandler.kt | 2 + ...tCreativeInventoryItemMouseInputHandler.kt | 6 +- ...ctFurnaceInventoryItemMouseInputHandler.kt | 2 + ...tSurvivalInventoryItemMouseInputHandler.kt | 2 + .../handler/mouse/UseItemMouseInputHandler.kt | 6 +- .../handler/touch/JoystickInputHandler.kt | 7 +- desktop/build.gradle | 17 +-- 37 files changed, 164 insertions(+), 332 deletions(-) create mode 100644 core/src/ru/deadsoftware/cavedroid/game/input/GameInputHandler.kt delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/input/IGameInputHandler.kt delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/input/KeyboardInputHandlersModule.kt delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java index 2ae4756..0dcbefc 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java @@ -9,7 +9,8 @@ import com.badlogic.gdx.math.Vector2; import com.badlogic.gdx.utils.ObjectMap; import com.badlogic.gdx.utils.TimeUtils; import ru.deadsoftware.cavedroid.MainConfig; -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler; +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler; +import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler; import ru.deadsoftware.cavedroid.game.input.Joystick; import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction; import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction; @@ -51,8 +52,8 @@ public class GameRenderer extends Renderer { private final CursorMouseInputHandler mCursorMouseInputHandler; private final MouseInputActionMapper mMouseInputActionMapper; private final KeyboardInputActionMapper mKeyboardInputActionMapper; - private final Set> mMouseInputHandlers; - private final Set> mKeyboardInputHandlers; + private final Set mMouseInputHandlers; + private final Set mKeyboardInputHandlers; private final GameWindowsManager mGameWindowsManager; private final TooltipManager mTooltipManager; @@ -71,8 +72,8 @@ public class GameRenderer extends Renderer { CursorMouseInputHandler cursorMouseInputHandler, MouseInputActionMapper mouseInputActionMapper, KeyboardInputActionMapper keyboardInputActionMapper, - Set> mouseInputHandlers, - Set> keyboardInputHandlers, + Set mouseInputHandlers, + Set keyboardInputHandlers, GameWindowsManager gameWindowsManager, TooltipManager tooltipManager) { super(mainConfig.getWidth(), mainConfig.getHeight()); @@ -224,7 +225,7 @@ public class GameRenderer extends Renderer { boolean anyProcessed = false; - for (IGameInputHandler handler : mMouseInputHandlers) { + for (IMouseInputHandler handler : mMouseInputHandlers) { final boolean conditions = handler.checkConditions(action); if (conditions) { anyProcessed = true; @@ -338,7 +339,7 @@ public class GameRenderer extends Renderer { boolean anyProcessed = false; - for (IGameInputHandler handler : mKeyboardInputHandlers) { + for (IKeyboardInputHandler handler : mKeyboardInputHandlers) { final boolean conditions = handler.checkConditions(action); if (conditions) { anyProcessed = true; diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/GameInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/GameInputHandler.kt new file mode 100644 index 0000000..55dc618 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/GameInputHandler.kt @@ -0,0 +1,40 @@ +package ru.deadsoftware.cavedroid.game.input + +import ru.deadsoftware.cavedroid.game.input.action.IGameInputAction +import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction +import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule + +@GenerateSetMultibindingsModule( + interfaceClass = IKeyboardInputHandler::class, + modulePackage = "ru.deadsoftware.cavedroid.game.input", + moduleName = "KeyboardInputHandlersModule" +) +annotation class KeyboardInputHandler + +@GenerateSetMultibindingsModule( + interfaceClass = IMouseInputHandler::class, + modulePackage = "ru.deadsoftware.cavedroid.game.input", + moduleName = "MouseInputHandlersModule" +) +annotation class MouseInputHandler + +interface IKeyboardInputHandler : IGameInputHandler + +interface IMouseInputHandler : IGameInputHandler + +interface IGameInputHandler { + + /** + * Implementation should check if conditions for handling an input are satisfied + * For example - inventory input handler should return false if inventory is closed + */ + fun checkConditions(action: A): Boolean + + /** + * Handle given input action. + * This will not be called if [checkConditions] returned false + */ + fun handle(action: A) + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/IGameInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/IGameInputHandler.kt deleted file mode 100644 index a8eaad1..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/input/IGameInputHandler.kt +++ /dev/null @@ -1,19 +0,0 @@ -package ru.deadsoftware.cavedroid.game.input - -import ru.deadsoftware.cavedroid.game.input.action.IGameInputAction - -interface IGameInputHandler { - - /** - * Implementation should check if conditions for handling an input are satisfied - * For example - inventory input handler should return false if inventory is closed - */ - fun checkConditions(action: A): Boolean - - /** - * Handle given input action. - * This will not be called if [checkConditions] returned false - */ - fun handle(action: A) - -} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/KeyboardInputHandlersModule.kt b/core/src/ru/deadsoftware/cavedroid/game/input/KeyboardInputHandlersModule.kt deleted file mode 100644 index a58e522..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/input/KeyboardInputHandlersModule.kt +++ /dev/null @@ -1,139 +0,0 @@ -package ru.deadsoftware.cavedroid.game.input - -import dagger.Binds -import dagger.Module -import dagger.multibindings.IntoSet -import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction -import ru.deadsoftware.cavedroid.game.input.handler.keyboard.* - -@Module -object KeyboardInputHandlersModule { - - @Binds - @IntoSet - @GameScope - fun bindGoLeftKeyboardInputHandler(handler: GoLeftKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindGoRightKeyboardInputHandler(handler: GoRightKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindJumpKeyboardActionHandler(handler: JumpKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindFlyUpKeyboardActionHandler(handler: FlyUpKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindTurnOnFlyModeKeyboardActionHandler(handler: TurnOnFlyModeKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindFlyDownKeyboardActionHandler(handler: FlyDownKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindOpenInventoryKeyboardInputHandler(handler: OpenInventoryKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindCloseGameWindowKeyboardInputHandler(handler: CloseGameWindowKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindToggleDebugInfoKeyboardInputHandler(handler: ToggleDebugInfoKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindToggleMinimapKeyboardInputHandler(handler: ToggleMinimapKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindToggleGameModeKeyboardInputHandler(handler: ToggleGameModeKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindPauseGameKeyboardInputHandler(handler: PauseGameKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindToggleControlsModeKeyboardInputHandler(handler: ToggleControlsModeKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindMoveCursorControlsModeKeyboardInputHandler(handler: MoveCursorControlsModeKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindOpenCraftingKeyboardInputHandler(handler: DropItemKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindSwimUpKeyboardInputHandler(handler: SwimUpKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindStopSwimKeyboardInputHandler(handler: StopSwimKeyboardInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindSelectHotbarSlotKeyboardInputHandler(handler: SelectHotbarSlotKeyboardInputHandler): IGameInputHandler { - return handler - } - -} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt b/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt deleted file mode 100644 index f0c3b3b..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt +++ /dev/null @@ -1,97 +0,0 @@ -package ru.deadsoftware.cavedroid.game.input - -import dagger.Binds -import dagger.Module -import dagger.multibindings.IntoSet -import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction -import ru.deadsoftware.cavedroid.game.input.handler.touch.JoystickInputHandler -import ru.deadsoftware.cavedroid.game.input.handler.mouse.* - -@Module -object MouseInputHandlersModule { - - @Binds - @IntoSet - @GameScope - fun bindCursorMouseInputHandler(handler: CursorMouseInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindHoldHotbarMouseInputHandler(handler: HotbarMouseInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindCloseGameWindowMouseActionHandler(handler: CloseGameWindowMouseInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindCreativeInventoryScrollMouseInputHandler(handler: CreativeInventoryScrollMouseInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindSelectCreativeInventoryItemMouseActionHandler(handler: SelectCreativeInventoryItemMouseInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindAttackMouseInputHandler(handler: AttackMouseInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindUseItemMouseInputActionHandler(handler: UseItemMouseInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindSelectSurvivalInventoryItemMouseInputHandler(handler: SelectSurvivalInventoryItemMouseInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindSelectCraftingInventoryItemMouseInputHandler(handler: SelectCraftingInventoryItemMouseInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindSelectFurnaceInventoryItemMouseInputHandler(handler: SelectFurnaceInventoryItemMouseInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindJoystickInputHandler(handler: JoystickInputHandler): IGameInputHandler { - return handler - } - - @Binds - @IntoSet - @GameScope - fun bindSelectChestInventoryItemMouseInputHandler(handler: SelectChestInventoryItemMouseInputHandler): IGameInputHandler { - return handler - } -} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt index 89a7b69..cbc254e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt @@ -2,7 +2,8 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController @@ -11,11 +12,12 @@ import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject @GameScope +@KeyboardInputHandler class CloseGameWindowKeyboardInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, private val dropController: DropController, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.OpenInventory && diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt index 04f5520..01a0c1f 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt @@ -2,7 +2,8 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController @@ -13,11 +14,12 @@ import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject @GameScope +@KeyboardInputHandler class DropItemKeyboardInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, private val dropController: DropController, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.DropItem && diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyDownKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyDownKeyboardInputHandler.kt index 0bb0a77..8e41dfe 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyDownKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyDownKeyboardInputHandler.kt @@ -2,7 +2,8 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController @@ -10,10 +11,11 @@ import ru.deadsoftware.cavedroid.game.mobs.player.Player import javax.inject.Inject @GameScope +@KeyboardInputHandler class FlyDownKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.Down && diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyUpKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyUpKeyboardInputHandler.kt index bf12c1a..976b069 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyUpKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyUpKeyboardInputHandler.kt @@ -2,7 +2,8 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController @@ -10,10 +11,11 @@ import ru.deadsoftware.cavedroid.game.mobs.player.Player import javax.inject.Inject @GameScope +@KeyboardInputHandler class FlyUpKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.Up && diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoLeftKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoLeftKeyboardInputHandler.kt index 421e47e..8234476 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoLeftKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoLeftKeyboardInputHandler.kt @@ -2,7 +2,8 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.Mob @@ -11,10 +12,11 @@ import ru.deadsoftware.cavedroid.game.mobs.player.Player import javax.inject.Inject @GameScope +@KeyboardInputHandler class GoLeftKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.Left && diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoRightKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoRightKeyboardInputHandler.kt index e3f5bf9..3139a17 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoRightKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoRightKeyboardInputHandler.kt @@ -2,7 +2,8 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.Mob @@ -11,10 +12,11 @@ import ru.deadsoftware.cavedroid.game.mobs.player.Player import javax.inject.Inject @GameScope +@KeyboardInputHandler class GoRightKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.Right && diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/JumpKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/JumpKeyboardInputHandler.kt index 1e68cea..30f12dd 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/JumpKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/JumpKeyboardInputHandler.kt @@ -2,7 +2,8 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController @@ -10,10 +11,11 @@ import ru.deadsoftware.cavedroid.game.mobs.player.Player import javax.inject.Inject @GameScope +@KeyboardInputHandler class JumpKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.Up && diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/MoveCursorControlsModeKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/MoveCursorControlsModeKeyboardInputHandler.kt index 0cb74d7..98d3e0a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/MoveCursorControlsModeKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/MoveCursorControlsModeKeyboardInputHandler.kt @@ -2,7 +2,8 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController @@ -11,11 +12,12 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@KeyboardInputHandler class MoveCursorControlsModeKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, private val gameWorld: GameWorld, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return mainConfig.isTouch && diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt index ec8190a..a1ca3da 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt @@ -2,16 +2,18 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject @GameScope +@KeyboardInputHandler class OpenInventoryKeyboardInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.OpenInventory && diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt index b39ee74..e4d6707 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt @@ -4,7 +4,8 @@ import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameSaver import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController @@ -15,6 +16,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@KeyboardInputHandler class PauseGameKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val dropController: DropController, @@ -22,7 +24,7 @@ class PauseGameKeyboardInputHandler @Inject constructor( private val gameWorld: GameWorld, private val containerController: ContainerController, private val gameWindowsManager: GameWindowsManager, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.Pause && action.isKeyDown diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SelectHotbarSlotKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SelectHotbarSlotKeyboardInputHandler.kt index 45e04da..0c7ea74 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SelectHotbarSlotKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SelectHotbarSlotKeyboardInputHandler.kt @@ -1,16 +1,18 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController import javax.inject.Inject @GameScope +@KeyboardInputHandler class SelectHotbarSlotKeyboardInputHandler @Inject constructor( private val mobsController: MobsController, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.SelectHotbarSlot && diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/StopSwimKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/StopSwimKeyboardInputHandler.kt index e25a99f..7256c54 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/StopSwimKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/StopSwimKeyboardInputHandler.kt @@ -2,7 +2,8 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController @@ -11,11 +12,12 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@KeyboardInputHandler class StopSwimKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, private val gameWorld: GameWorld, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.Up && !action.isKeyDown && diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SwimUpKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SwimUpKeyboardInputHandler.kt index 3159e7f..9dc4777 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SwimUpKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SwimUpKeyboardInputHandler.kt @@ -2,7 +2,8 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController @@ -11,11 +12,12 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@KeyboardInputHandler class SwimUpKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, private val gameWorld: GameWorld, -) : IGameInputHandler { +) : IKeyboardInputHandler { private fun checkSwim(): Boolean { return gameWorld.getForeMap(mobsController.player.mapX, mobsController.player.lowerMapY).isFluid() diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleControlsModeKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleControlsModeKeyboardInputHandler.kt index fc95e29..a933c80 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleControlsModeKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleControlsModeKeyboardInputHandler.kt @@ -2,7 +2,8 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController @@ -10,10 +11,11 @@ import ru.deadsoftware.cavedroid.game.mobs.player.Player import javax.inject.Inject @GameScope +@KeyboardInputHandler class ToggleControlsModeKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.SwitchControlsMode && !action.isKeyDown diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleDebugInfoKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleDebugInfoKeyboardInputHandler.kt index 96bc21d..065b28c 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleDebugInfoKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleDebugInfoKeyboardInputHandler.kt @@ -2,15 +2,17 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import javax.inject.Inject @GameScope +@KeyboardInputHandler class ToggleDebugInfoKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.ShowDebug && action.isKeyDown diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleGameModeKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleGameModeKeyboardInputHandler.kt index ef4e696..a17e6d2 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleGameModeKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleGameModeKeyboardInputHandler.kt @@ -1,16 +1,18 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController import javax.inject.Inject @GameScope +@KeyboardInputHandler class ToggleGameModeKeyboardInputHandler @Inject constructor( private val mobsController: MobsController -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleMinimapKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleMinimapKeyboardInputHandler.kt index d39dfdb..6f22e4c 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleMinimapKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleMinimapKeyboardInputHandler.kt @@ -2,15 +2,17 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import javax.inject.Inject @GameScope +@KeyboardInputHandler class ToggleMinimapKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return action.actionKey is KeyboardInputActionKey.ShowMap && action.isKeyDown diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/TurnOnFlyModeKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/TurnOnFlyModeKeyboardInputHandler.kt index f3b65eb..3b43d31 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/TurnOnFlyModeKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/TurnOnFlyModeKeyboardInputHandler.kt @@ -2,7 +2,8 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController @@ -10,10 +11,11 @@ import ru.deadsoftware.cavedroid.game.mobs.player.Player import javax.inject.Inject @GameScope +@KeyboardInputHandler class TurnOnFlyModeKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, -) : IGameInputHandler { +) : IKeyboardInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { return mobsController.player.gameMode == 1 && action.actionKey is KeyboardInputActionKey.Up && diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AbstractInventoryItemsMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AbstractInventoryItemsMouseInputHandler.kt index dec8b7d..3b925b0 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AbstractInventoryItemsMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AbstractInventoryItemsMouseInputHandler.kt @@ -3,7 +3,7 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse import com.badlogic.gdx.graphics.g2d.TextureRegion import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameUiWindow -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideWindow @@ -17,7 +17,7 @@ abstract class AbstractInventoryItemsMouseInputHandler( private val gameItemsHolder: GameItemsHolder, private val gameWindowsManager: GameWindowsManager, private val windowType: GameUiWindow, -) : IGameInputHandler { +) : IMouseInputHandler { protected abstract val windowTexture: TextureRegion diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt index 2afc3d5..c2a22ed 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt @@ -2,7 +2,8 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler +import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideHotbar @@ -12,11 +13,12 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@MouseInputHandler class AttackMouseInputHandler @Inject constructor( private val mobsController: MobsController, private val gameWorld: GameWorld, private val gameWindowsManager: GameWindowsManager -) : IGameInputHandler { +) : IMouseInputHandler { override fun checkConditions(action: MouseInputAction): Boolean { return gameWindowsManager.getCurrentWindow() == GameUiWindow.NONE && diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt index f6f6cfc..b5ff2c5 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt @@ -4,7 +4,8 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler +import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideWindow @@ -14,11 +15,12 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope +@MouseInputHandler class CloseGameWindowMouseInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, private val dropController: DropController, -) : IGameInputHandler { +) : IMouseInputHandler { private val creativeInventoryTexture get() = requireNotNull(Assets.textureRegions["creative"]) private val survivalInventoryTexture get() = requireNotNull(Assets.textureRegions["survival"]) diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt index 11f76e9..bf6ba37 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt @@ -6,7 +6,8 @@ import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler +import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideWindow @@ -15,11 +16,12 @@ import javax.inject.Inject import kotlin.math.abs @GameScope +@MouseInputHandler class CreativeInventoryScrollMouseInputHandler @Inject constructor( private val mainConfig: MainConfig, private val gameWindowsManager: GameWindowsManager, private val gameItemsHolder: GameItemsHolder, -) : IGameInputHandler { +) : IMouseInputHandler { private val creativeInventoryTexture get() = requireNotNull(Assets.textureRegions["creative"]) diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt index 454337e..5d5c79f 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt @@ -5,7 +5,8 @@ import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler +import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.mobs.Mob @@ -22,6 +23,7 @@ import ru.deadsoftware.cavedroid.misc.utils.px import javax.inject.Inject @GameScope +@MouseInputHandler class CursorMouseInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, @@ -29,7 +31,7 @@ class CursorMouseInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val gameItemsHolder: GameItemsHolder, private val tooltipManager: TooltipManager, -) : IGameInputHandler { +) : IMouseInputHandler { private val player get() = mobsController.player diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt index 18cd41d..45ae49b 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt @@ -4,7 +4,8 @@ import com.badlogic.gdx.utils.Timer import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler +import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.handler.keyboard.DropItemKeyboardInputHandler.Companion.DROP_DISTANCE @@ -18,11 +19,12 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope +@MouseInputHandler class HotbarMouseInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, private val dropController: DropController, -) : IGameInputHandler { +) : IMouseInputHandler { private val hotbarTexture get() = requireNotNull(Assets.textureRegions["hotbar"]) diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectChestInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectChestInventoryItemMouseInputHandler.kt index d47202e..3118e9f 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectChestInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectChestInventoryItemMouseInputHandler.kt @@ -3,6 +3,7 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs @@ -12,6 +13,7 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope +@MouseInputHandler class SelectChestInventoryItemMouseInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt index 88e3620..cc993c9 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt @@ -3,6 +3,7 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs @@ -12,6 +13,7 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope +@MouseInputHandler class SelectCraftingInventoryItemMouseInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt index 272a178..5c6975f 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt @@ -4,7 +4,8 @@ import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler +import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideWindow @@ -14,11 +15,12 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope +@MouseInputHandler class SelectCreativeInventoryItemMouseInputHandler @Inject constructor( private val gameItemsHolder: GameItemsHolder, private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, -) : IGameInputHandler { +) : IMouseInputHandler { private val creativeInventoryTexture get() = requireNotNull(Assets.textureRegions["creative"]) diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt index f4a00eb..164b0c1 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt @@ -3,6 +3,7 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.InventoryItem.Companion.isNoneOrNull @@ -14,6 +15,7 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope +@MouseInputHandler class SelectFurnaceInventoryItemMouseInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt index 0a455ab..9f25b9a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt @@ -3,6 +3,7 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs @@ -12,6 +13,7 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope +@MouseInputHandler class SelectSurvivalInventoryItemMouseInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt index 04bc619..c0ff332 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt @@ -9,7 +9,8 @@ import ru.deadsoftware.cavedroid.game.actions.placeToForegroundAction import ru.deadsoftware.cavedroid.game.actions.placeblock.IPlaceBlockAction import ru.deadsoftware.cavedroid.game.actions.useblock.IUseBlockAction import ru.deadsoftware.cavedroid.game.actions.useitem.IUseItemAction -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler +import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideHotbar @@ -20,6 +21,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@MouseInputHandler class UseItemMouseInputHandler @Inject constructor( private val mobsController: MobsController, private val useItemActionMap: Map, @@ -27,7 +29,7 @@ class UseItemMouseInputHandler @Inject constructor( private val useBlockActionMap: Map, private val gameWindowsManager: GameWindowsManager, private val gameWorld: GameWorld, -) : IGameInputHandler { +) : IMouseInputHandler { private var buttonHoldTask: Timer.Task? = null diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/touch/JoystickInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/touch/JoystickInputHandler.kt index 1c020a5..b6f31a3 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/touch/JoystickInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/touch/JoystickInputHandler.kt @@ -4,11 +4,9 @@ import com.badlogic.gdx.utils.TimeUtils import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow -import ru.deadsoftware.cavedroid.game.input.IGameInputHandler -import ru.deadsoftware.cavedroid.game.input.Joystick +import ru.deadsoftware.cavedroid.game.input.* import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey -import ru.deadsoftware.cavedroid.game.input.isInsideHotbar import ru.deadsoftware.cavedroid.game.mobs.Mob import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player @@ -17,12 +15,13 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@MouseInputHandler class JoystickInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, private val gameWindowsManager: GameWindowsManager, private val gameWorld: GameWorld, -) : IGameInputHandler { +) : IMouseInputHandler { private var activateTimeMs = 0L private var cursorTimeoutMs = 100L diff --git a/desktop/build.gradle b/desktop/build.gradle index 58553a3..9127345 100644 --- a/desktop/build.gradle +++ b/desktop/build.gradle @@ -13,7 +13,7 @@ sourceSets.main.resources.srcDirs = ["../android/assets"] project.ext.mainClassName = "ru.deadsoftware.cavedroid.desktop.DesktopLauncher" project.ext.assetsDir = new File("../android/assets") -task run(dependsOn: classes, type: JavaExec) { +task run(dependsOn: build, type: JavaExec) { main = project.mainClassName classpath = sourceSets.main.runtimeClasspath standardInput = System.in @@ -22,7 +22,7 @@ task run(dependsOn: classes, type: JavaExec) { args "--debug" } -task runTouch(dependsOn: classes, type: JavaExec) { +task runTouch(dependsOn: build, type: JavaExec) { main = project.mainClassName classpath = sourceSets.main.runtimeClasspath standardInput = System.in @@ -31,16 +31,7 @@ task runTouch(dependsOn: classes, type: JavaExec) { args "--touch", "--debug" } -task debug(dependsOn: classes, type: JavaExec) { - main = project.mainClassName - classpath = sourceSets.main.runtimeClasspath - standardInput = System.in - workingDir = project.assetsDir - ignoreExitValue = true as JavaExecSpec - debug = true -} - -task dist(type: Jar) { +task dist(dependsOn: build, type: Jar) { duplicatesStrategy = DuplicatesStrategy.EXCLUDE manifest { attributes 'Main-Class': project.mainClassName @@ -51,8 +42,6 @@ task dist(type: Jar) { with jar } -dist.dependsOn build - dependencies { implementation project(":core") implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinSerializationVersion" -- 2.29.2 From d9211ab755d82ecf9553527a734ab5db38f8fe74 Mon Sep 17 00:00:00 2001 From: fredboy Date: Wed, 15 May 2024 00:25:11 +0700 Subject: [PATCH 08/16] Game action modules generation --- .../game/actions/PlaceBlockActionsModule.kt | 40 -------- .../game/actions/UpdateBlockActionsModule.kt | 68 ------------- .../game/actions/UseBlockActionsModule.kt | 39 -------- .../game/actions/UseItemActionsModule.kt | 53 ---------- .../actions/placeblock/IPlaceBlockAction.kt | 9 -- .../actions/placeblock/PlaceBlockAction.kt | 17 ++++ .../PlaceBlockItemToBackgroundAction.kt | 1 + .../PlaceBlockItemToForegroundAction.kt | 1 + .../actions/placeblock/PlaceSlabAction.kt | 1 + .../actions/updateblock/IUpdateBlockAction.kt | 9 ++ .../updateblock/UpdateBedLeftAction.kt | 1 + .../updateblock/UpdateBedRightAction.kt | 1 + .../actions/updateblock/UpdateGrassAction.kt | 1 + .../actions/updateblock/UpdateGravelAction.kt | 1 + .../updateblock/UpdateRequiresBlockAction.kt | 1 + .../actions/updateblock/UpdateSandAction.kt | 1 + .../updateblock/UpdateSnowedGrassAction.kt | 1 + .../game/actions/useblock/IUseBlockAction.kt | 9 -- .../game/actions/useblock/UseBlockAction.kt | 17 ++++ .../game/actions/useblock/UseChestAction.kt | 1 + .../useblock/UseCraftingTableAction.kt | 1 + .../game/actions/useblock/UseFurnaceAction.kt | 1 + .../game/actions/useitem/IUseItemAction.kt | 9 -- .../game/actions/useitem/UseBedAction.kt | 1 + .../actions/useitem/UseEmptyBucketAction.kt | 1 + .../game/actions/useitem/UseItemAction.kt | 17 ++++ .../actions/useitem/UseLavaBucketAction.kt | 1 + .../actions/useitem/UsePigSpawnEggAction.kt | 1 + .../actions/useitem/UseWaterBucketAction.kt | 1 + .../GenerateMapMultibindingsModule.kt | 14 +++ ...GenerateMapMultibindingsSymbolProcessor.kt | 98 +++++++++++++++++++ ...MapMultibindingsSymbolProcessorProvider.kt | 17 ++++ ...ols.ksp.processing.SymbolProcessorProvider | 1 + 33 files changed, 208 insertions(+), 227 deletions(-) delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/PlaceBlockActionsModule.kt delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/UpdateBlockActionsModule.kt delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/IPlaceBlockAction.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockAction.kt delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/useblock/IUseBlockAction.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseBlockAction.kt delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/useitem/IUseItemAction.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseItemAction.kt create mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateMapMultibindingsModule.kt create mode 100644 dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateMapMultibindingsSymbolProcessor.kt create mode 100644 dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateMapMultibindingsSymbolProcessorProvider.kt diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/PlaceBlockActionsModule.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/PlaceBlockActionsModule.kt deleted file mode 100644 index f2c5a23..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/PlaceBlockActionsModule.kt +++ /dev/null @@ -1,40 +0,0 @@ -package ru.deadsoftware.cavedroid.game.actions - -import dagger.Binds -import dagger.Module -import dagger.multibindings.IntoMap -import dagger.multibindings.StringKey -import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.actions.placeblock.IPlaceBlockAction -import ru.deadsoftware.cavedroid.game.actions.placeblock.PlaceBlockItemToBackgroundAction -import ru.deadsoftware.cavedroid.game.actions.placeblock.PlaceBlockItemToForegroundAction -import ru.deadsoftware.cavedroid.game.actions.placeblock.PlaceSlabAction - -@Module -class PlaceBlockActionsModule { - - @Binds - @IntoMap - @StringKey(PlaceBlockItemToForegroundAction.ACTION_KEY) - @GameScope - fun bindPlaceBlockItemToForegroundAction(action: PlaceBlockItemToForegroundAction): IPlaceBlockAction { - return action - } - - @Binds - @IntoMap - @StringKey(PlaceBlockItemToBackgroundAction.ACTION_KEY) - @GameScope - fun bindPlaceBlockItemToBackgroundAction(action: PlaceBlockItemToBackgroundAction): IPlaceBlockAction { - return action - } - - @Binds - @IntoMap - @StringKey(PlaceSlabAction.ACTION_KEY) - @GameScope - fun bindPlaceSlabAction(action: PlaceSlabAction): IPlaceBlockAction { - return action - } - -} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/UpdateBlockActionsModule.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/UpdateBlockActionsModule.kt deleted file mode 100644 index 6f0fc0f..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/UpdateBlockActionsModule.kt +++ /dev/null @@ -1,68 +0,0 @@ -package ru.deadsoftware.cavedroid.game.actions - -import dagger.Binds -import dagger.Module -import dagger.multibindings.IntoMap -import dagger.multibindings.StringKey -import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.actions.updateblock.* - -@Module -class UpdateBlockActionsModule { - - @Binds - @IntoMap - @StringKey(UpdateSandAction.BLOCK_KEY) - @GameScope - fun bindUpdateSandAction(action: UpdateSandAction): IUpdateBlockAction { - return action; - } - - @Binds - @IntoMap - @StringKey(UpdateGravelAction.BLOCK_KEY) - @GameScope - fun bindUpdateGravelAction(action: UpdateGravelAction): IUpdateBlockAction { - return action; - } - - @Binds - @IntoMap - @StringKey(UpdateRequiresBlockAction.ACTION_KEY) - @GameScope - fun bindUpdateRequiresBlockAction(action: UpdateRequiresBlockAction): IUpdateBlockAction { - return action; - } - - @Binds - @IntoMap - @StringKey(UpdateGrassAction.BLOCK_KEY) - @GameScope - fun bindUpdateGrassAction(action: UpdateGrassAction): IUpdateBlockAction { - return action; - } - - @Binds - @IntoMap - @StringKey(UpdateSnowedGrassAction.BLOCK_KEY) - @GameScope - fun bindUpdateSnowedGrassAction(action: UpdateSnowedGrassAction): IUpdateBlockAction { - return action; - } - - @Binds - @IntoMap - @StringKey(UpdateBedLeftAction.BLOCK_KEY) - @GameScope - fun bindUpdateBedLeftAction(action: UpdateBedLeftAction): IUpdateBlockAction { - return action; - } - - @Binds - @IntoMap - @StringKey(UpdateBedRightAction.BLOCK_KEY) - @GameScope - fun bindUpdateBedRightAction(action: UpdateBedRightAction): IUpdateBlockAction { - return action; - } -} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt deleted file mode 100644 index 7458dfc..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt +++ /dev/null @@ -1,39 +0,0 @@ -package ru.deadsoftware.cavedroid.game.actions - -import dagger.Binds -import dagger.Module -import dagger.multibindings.IntoMap -import dagger.multibindings.StringKey -import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.actions.useblock.IUseBlockAction -import ru.deadsoftware.cavedroid.game.actions.useblock.UseChestAction -import ru.deadsoftware.cavedroid.game.actions.useblock.UseCraftingTableAction -import ru.deadsoftware.cavedroid.game.actions.useblock.UseFurnaceAction - -@Module -class UseBlockActionsModule { - - @Binds - @IntoMap - @StringKey(UseCraftingTableAction.KEY) - @GameScope - fun bindUseCraftingTableAction(action: UseCraftingTableAction): IUseBlockAction { - return action - } - - @Binds - @IntoMap - @StringKey(UseFurnaceAction.KEY) - @GameScope - fun bindUseFurnaceTableAction(action: UseFurnaceAction): IUseBlockAction { - return action - } - - @Binds - @IntoMap - @StringKey(UseChestAction.KEY) - @GameScope - fun bindUseChestAction(action: UseChestAction): IUseBlockAction { - return action - } -} diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt deleted file mode 100644 index d5e4f4f..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt +++ /dev/null @@ -1,53 +0,0 @@ -package ru.deadsoftware.cavedroid.game.actions - -import dagger.Binds -import dagger.Module -import dagger.multibindings.IntoMap -import dagger.multibindings.StringKey -import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.actions.useitem.* - -@Module -class UseItemActionsModule { - - @Binds - @IntoMap - @StringKey(UseWaterBucketAction.ACTION_KEY) - @GameScope - fun bindUseWaterBucketAction(action: UseWaterBucketAction): IUseItemAction { - return action - } - - @Binds - @IntoMap - @StringKey(UseLavaBucketAction.ACTION_KEY) - @GameScope - fun bindUseLavaBucketAction(action: UseLavaBucketAction): IUseItemAction { - return action - } - - @Binds - @IntoMap - @StringKey(UseEmptyBucketAction.ACTION_KEY) - @GameScope - fun bindUseEmptyBucketAction(action: UseEmptyBucketAction): IUseItemAction { - return action - } - - @Binds - @IntoMap - @StringKey(UsePigSpawnEggAction.ACTION_KEY) - @GameScope - fun bindUsePigSpawnEgg(action: UsePigSpawnEggAction): IUseItemAction { - return action - } - - @Binds - @IntoMap - @StringKey(UseBedAction.ACTION_KEY) - @GameScope - fun bindUseBedAction(action: UseBedAction): IUseItemAction { - return action - } - -} diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/IPlaceBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/IPlaceBlockAction.kt deleted file mode 100644 index 06c70c4..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/IPlaceBlockAction.kt +++ /dev/null @@ -1,9 +0,0 @@ -package ru.deadsoftware.cavedroid.game.actions.placeblock - -import ru.deadsoftware.cavedroid.game.model.item.Item - -interface IPlaceBlockAction { - - fun place(placeable: Item.Placeable, x: Int, y: Int) - -} diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockAction.kt new file mode 100644 index 0000000..e0f6cd8 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockAction.kt @@ -0,0 +1,17 @@ +package ru.deadsoftware.cavedroid.game.actions.placeblock + +import ru.deadsoftware.cavedroid.game.model.item.Item +import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule + +@GenerateMapMultibindingsModule( + interfaceClass = IPlaceBlockAction::class, + modulePackage = "ru.deadsoftware.cavedroid.game.actions", + moduleName = "PlaceBlockActionsModule" +) +annotation class PlaceBlockAction(val stringKey: String) + +interface IPlaceBlockAction { + + fun place(placeable: Item.Placeable, x: Int, y: Int) + +} diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToBackgroundAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToBackgroundAction.kt index fdfb61a..0a5399a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToBackgroundAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToBackgroundAction.kt @@ -8,6 +8,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@PlaceBlockAction(stringKey = PlaceBlockItemToBackgroundAction.ACTION_KEY) class PlaceBlockItemToBackgroundAction @Inject constructor( private val gameWorld: GameWorld, private val gameItemsHolder: GameItemsHolder, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToForegroundAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToForegroundAction.kt index 22aafdd..d3ff979 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToForegroundAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToForegroundAction.kt @@ -8,6 +8,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@PlaceBlockAction(stringKey = PlaceBlockItemToForegroundAction.ACTION_KEY) class PlaceBlockItemToForegroundAction @Inject constructor( private val gameWorld: GameWorld, private val placeSlabAction: PlaceSlabAction, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceSlabAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceSlabAction.kt index 6ac94c9..3e0a185 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceSlabAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceSlabAction.kt @@ -9,6 +9,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@PlaceBlockAction(stringKey = PlaceSlabAction.ACTION_KEY) class PlaceSlabAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/IUpdateBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/IUpdateBlockAction.kt index 9cc4aea..a397f16 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/IUpdateBlockAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/IUpdateBlockAction.kt @@ -1,5 +1,14 @@ package ru.deadsoftware.cavedroid.game.actions.updateblock +import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule + +@GenerateMapMultibindingsModule( + interfaceClass = IUpdateBlockAction::class, + modulePackage = "ru.deadsoftware.cavedroid.game.actions", + moduleName = "UpdateBlockActionsModule" +) +annotation class UpdateBlockAction(val stringKey: String) + interface IUpdateBlockAction { fun update(x: Int, y: Int) diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedLeftAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedLeftAction.kt index 15621a2..4e43f8f 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedLeftAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedLeftAction.kt @@ -8,6 +8,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@UpdateBlockAction(stringKey = UpdateBedLeftAction.BLOCK_KEY) class UpdateBedLeftAction @Inject constructor( private val gameWorld: GameWorld, private val gameItemsHolder: GameItemsHolder, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedRightAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedRightAction.kt index 4d47b35..78e81fa 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedRightAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedRightAction.kt @@ -8,6 +8,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@UpdateBlockAction(stringKey = UpdateBedRightAction.BLOCK_KEY) class UpdateBedRightAction @Inject constructor( private val gameWorld: GameWorld, private val gameItemsHolder: GameItemsHolder, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGrassAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGrassAction.kt index d5ca3b1..56f814f 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGrassAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGrassAction.kt @@ -6,6 +6,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@UpdateBlockAction(stringKey = UpdateGrassAction.BLOCK_KEY) class UpdateGrassAction @Inject constructor( private val gameWorld: GameWorld, private val mGameItemsHolder: GameItemsHolder, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGravelAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGravelAction.kt index 6cc026f..f51bc7f 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGravelAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGravelAction.kt @@ -7,6 +7,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@UpdateBlockAction(stringKey = UpdateGravelAction.BLOCK_KEY) class UpdateGravelAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateRequiresBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateRequiresBlockAction.kt index 57172a5..6b15a7a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateRequiresBlockAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateRequiresBlockAction.kt @@ -5,6 +5,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@UpdateBlockAction(stringKey = UpdateRequiresBlockAction.ACTION_KEY) class UpdateRequiresBlockAction @Inject constructor( private val gameWorld: GameWorld, ) : IUpdateBlockAction { diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSandAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSandAction.kt index 4a2b58e..f2ef25e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSandAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSandAction.kt @@ -7,6 +7,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@UpdateBlockAction(stringKey = UpdateSandAction.BLOCK_KEY) class UpdateSandAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSnowedGrassAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSnowedGrassAction.kt index 0aa5c90..049c90b 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSnowedGrassAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSnowedGrassAction.kt @@ -6,6 +6,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@UpdateBlockAction(stringKey = UpdateSnowedGrassAction.BLOCK_KEY) class UpdateSnowedGrassAction @Inject constructor( private val gameWorld: GameWorld, private val mGameItemsHolder: GameItemsHolder, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/IUseBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/IUseBlockAction.kt deleted file mode 100644 index ddc70c5..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/IUseBlockAction.kt +++ /dev/null @@ -1,9 +0,0 @@ -package ru.deadsoftware.cavedroid.game.actions.useblock - -import ru.deadsoftware.cavedroid.game.model.block.Block - -interface IUseBlockAction { - - fun perform(block: Block, x: Int, y: Int) - -} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseBlockAction.kt new file mode 100644 index 0000000..932bbf6 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseBlockAction.kt @@ -0,0 +1,17 @@ +package ru.deadsoftware.cavedroid.game.actions.useblock + +import ru.deadsoftware.cavedroid.game.model.block.Block +import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule + +@GenerateMapMultibindingsModule( + interfaceClass = IUseBlockAction::class, + modulePackage = "ru.deadsoftware.cavedroid.game.actions", + moduleName = "UseBlockActionsModule" +) +annotation class UseBlockAction(val stringKey: String) + +interface IUseBlockAction { + + fun perform(block: Block, x: Int, y: Int) + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseChestAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseChestAction.kt index fa50c94..fd370db 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseChestAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseChestAction.kt @@ -8,6 +8,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@UseBlockAction(stringKey = UseChestAction.KEY) class UseChestAction @Inject constructor( private val gameWorld: GameWorld, private val gameWindowsManager: GameWindowsManager, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt index 3ce42b9..de1112e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt @@ -6,6 +6,7 @@ import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject @GameScope +@UseBlockAction(stringKey = UseCraftingTableAction.KEY) class UseCraftingTableAction @Inject constructor( private val gameWindowsManager: GameWindowsManager ) : IUseBlockAction { diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt index 7c30402..1426263 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt @@ -7,6 +7,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@UseBlockAction(stringKey = UseFurnaceAction.KEY) class UseFurnaceAction @Inject constructor( private val gameWorld: GameWorld, private val gameWindowsManager: GameWindowsManager, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/IUseItemAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/IUseItemAction.kt deleted file mode 100644 index d963aee..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/IUseItemAction.kt +++ /dev/null @@ -1,9 +0,0 @@ -package ru.deadsoftware.cavedroid.game.actions.useitem - -import ru.deadsoftware.cavedroid.game.model.item.Item - -interface IUseItemAction { - - fun perform(item: Item.Usable, x: Int, y: Int) - -} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseBedAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseBedAction.kt index e0f9964..1aefd67 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseBedAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseBedAction.kt @@ -8,6 +8,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@UseItemAction(UseBedAction.ACTION_KEY) class UseBedAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseEmptyBucketAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseEmptyBucketAction.kt index 57ca3f7..fd64751 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseEmptyBucketAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseEmptyBucketAction.kt @@ -9,6 +9,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@UseItemAction(UseEmptyBucketAction.ACTION_KEY) class UseEmptyBucketAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseItemAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseItemAction.kt new file mode 100644 index 0000000..be4d254 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseItemAction.kt @@ -0,0 +1,17 @@ +package ru.deadsoftware.cavedroid.game.actions.useitem + +import ru.deadsoftware.cavedroid.game.model.item.Item +import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule + +@GenerateMapMultibindingsModule( + interfaceClass = IUseItemAction::class, + modulePackage = "ru.deadsoftware.cavedroid.game.actions", + moduleName = "UseItemActionsModule" +) +annotation class UseItemAction(val stringKey: String) + +interface IUseItemAction { + + fun perform(item: Item.Usable, x: Int, y: Int) + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseLavaBucketAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseLavaBucketAction.kt index 9659617..70438e3 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseLavaBucketAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseLavaBucketAction.kt @@ -8,6 +8,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@UseItemAction(UseLavaBucketAction.ACTION_KEY) class UseLavaBucketAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt index 6c0c3ba..4b2aa00 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt @@ -9,6 +9,7 @@ import ru.deadsoftware.cavedroid.misc.utils.px import javax.inject.Inject @GameScope +@UseItemAction(UsePigSpawnEggAction.ACTION_KEY) class UsePigSpawnEggAction @Inject constructor( private val mobsController: MobsController, private val gameItemsHolder: GameItemsHolder, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseWaterBucketAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseWaterBucketAction.kt index 15e08fc..83b8f24 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseWaterBucketAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseWaterBucketAction.kt @@ -8,6 +8,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope +@UseItemAction(UseWaterBucketAction.ACTION_KEY) class UseWaterBucketAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateMapMultibindingsModule.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateMapMultibindingsModule.kt new file mode 100644 index 0000000..7a5b023 --- /dev/null +++ b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateMapMultibindingsModule.kt @@ -0,0 +1,14 @@ +package ru.fredboy.cavedroid.ksp.annotations + +import kotlin.reflect.KClass + +/** + * Annotation annotated with this must include stringKey parameter for key selection in generated module + */ +@Target(AnnotationTarget.ANNOTATION_CLASS) +@Retention(AnnotationRetention.SOURCE) +annotation class GenerateMapMultibindingsModule( + val interfaceClass: KClass<*>, + val modulePackage: String, + val moduleName: String, +) diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateMapMultibindingsSymbolProcessor.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateMapMultibindingsSymbolProcessor.kt new file mode 100644 index 0000000..cfaa3a5 --- /dev/null +++ b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateMapMultibindingsSymbolProcessor.kt @@ -0,0 +1,98 @@ +package ru.fredboy.cavedroid.ksp.processor + +import com.google.devtools.ksp.processing.* +import com.google.devtools.ksp.symbol.KSAnnotated +import com.google.devtools.ksp.symbol.KSClassDeclaration +import com.google.devtools.ksp.symbol.KSType +import com.squareup.kotlinpoet.* +import com.squareup.kotlinpoet.ksp.toClassName +import com.squareup.kotlinpoet.ksp.writeTo +import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule + +class GenerateMapMultibindingsSymbolProcessor( + private val codeGenerator: CodeGenerator, + private val logger: KSPLogger, +) : SymbolProcessor { + + private fun generateModule( + annotationName: String, + interfaceName: ClassName, + moduleName: ClassName, + classes: List + ): FileSpec? { + if (classes.isEmpty()) { + return null + } + + val bindings = classes.map { decl -> + val stringKey = decl.annotations.first { declAnn -> + declAnn.shortName.getShortName() == annotationName + }.arguments.firstOrNull { arg -> + arg.name!!.getShortName() == "stringKey" + }?.value as? String ?: run { + logger.error("@${annotationName} must include stringKey parameter for key selection in generated module") + throw IllegalArgumentException() + } + + val clazz = decl.toClassName() + + FunSpec.builder("bind${clazz.simpleName}") + .addAnnotation(ClassName("dagger", "Binds")) + .addAnnotation(ClassName("dagger.multibindings", "IntoMap")) + .addAnnotation( + AnnotationSpec.builder(ClassName("dagger.multibindings", "StringKey")) + .addMember("\"$stringKey\"") + .build() + ) + .addParameter(ParameterSpec("impl", clazz)) + .returns(interfaceName) + .addCode("return impl") + .build() + } + + val moduleObject = TypeSpec.objectBuilder(moduleName) + .addAnnotation(ClassName("dagger", "Module")) + .addFunctions(bindings) + .build() + + return FileSpec.builder(moduleName) + .addType(moduleObject) + .build() + + } + + private fun processAnnotation(resolver: Resolver, annotation: KSClassDeclaration) { + val args = annotation.annotations.first { + it.shortName.getShortName() == "GenerateMapMultibindingsModule" + }.arguments.takeIf { it.size == 3 } ?: run { + logger.error("GenerateMapMultibindingsModule should have 3 arguments") + throw IllegalArgumentException() + } + + val interfaceName = args.first { it.name?.getShortName() == "interfaceClass" }.value as KSType + val modulePackage = args.first { it.name?.getShortName() == "modulePackage" }.value as String + val moduleName = args.first { it.name?.getShortName() == "moduleName" }.value as String + + val moduleClassName = ClassName(modulePackage, moduleName) + val elements = resolver.getSymbolsWithAnnotation(annotation.qualifiedName!!.asString()) + .filterIsInstance() + .toList() + + logger.info("Found elements: ${elements.joinToString()}") + + generateModule( + annotationName = annotation.qualifiedName!!.getShortName(), + interfaceName = interfaceName.toClassName(), + moduleName = moduleClassName, + classes = elements + )?.writeTo(codeGenerator, Dependencies(true)) + } + + override fun process(resolver: Resolver): List { + val annotations = resolver.getAnnotatedClasses(GenerateMapMultibindingsModule::class.qualifiedName!!, logger) + logger.info("Found annotations: ${annotations.joinToString { it.qualifiedName!!.asString() }}") + annotations.forEach { processAnnotation(resolver, it) } + return emptyList() + } + +} \ No newline at end of file diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateMapMultibindingsSymbolProcessorProvider.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateMapMultibindingsSymbolProcessorProvider.kt new file mode 100644 index 0000000..49ea948 --- /dev/null +++ b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateMapMultibindingsSymbolProcessorProvider.kt @@ -0,0 +1,17 @@ +package ru.fredboy.cavedroid.ksp.provider + +import com.google.devtools.ksp.processing.SymbolProcessor +import com.google.devtools.ksp.processing.SymbolProcessorEnvironment +import com.google.devtools.ksp.processing.SymbolProcessorProvider +import ru.fredboy.cavedroid.ksp.processor.GenerateMapMultibindingsSymbolProcessor + +internal class GenerateMapMultibindingsSymbolProcessorProvider : SymbolProcessorProvider { + + override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { + return GenerateMapMultibindingsSymbolProcessor( + codeGenerator = environment.codeGenerator, + logger = environment.logger, + ) + } + +} \ No newline at end of file diff --git a/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider index 293ff25..b646e9d 100644 --- a/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +++ b/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider @@ -1 +1,2 @@ ru.fredboy.cavedroid.ksp.provider.GenerateSetMultibindingsSymbolProcessorProvider +ru.fredboy.cavedroid.ksp.provider.GenerateMapMultibindingsSymbolProcessorProvider -- 2.29.2 From 4f3174f9178f0f5c0891bdd9f6ecd8738f0274bf Mon Sep 17 00:00:00 2001 From: fredboy Date: Wed, 15 May 2024 00:34:09 +0700 Subject: [PATCH 09/16] Add Generated annotation to generated code --- .../ksp/processor/GenerateMapMultibindingsSymbolProcessor.kt | 5 +++++ .../ksp/processor/GenerateSetMultibindingsSymbolProcessor.kt | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateMapMultibindingsSymbolProcessor.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateMapMultibindingsSymbolProcessor.kt index cfaa3a5..860653f 100644 --- a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateMapMultibindingsSymbolProcessor.kt +++ b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateMapMultibindingsSymbolProcessor.kt @@ -52,6 +52,11 @@ class GenerateMapMultibindingsSymbolProcessor( val moduleObject = TypeSpec.objectBuilder(moduleName) .addAnnotation(ClassName("dagger", "Module")) + .addAnnotation( + AnnotationSpec.builder(ClassName("javax.annotation.processing", "Generated")) + .addMember("value = [%S]", this::class.qualifiedName!!) + .build() + ) .addFunctions(bindings) .build() diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateSetMultibindingsSymbolProcessor.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateSetMultibindingsSymbolProcessor.kt index 18cd3c9..6bcb60c 100644 --- a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateSetMultibindingsSymbolProcessor.kt +++ b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateSetMultibindingsSymbolProcessor.kt @@ -35,6 +35,11 @@ class GenerateSetMultibindingsSymbolProcessor( val moduleObject = TypeSpec.objectBuilder(moduleName) .addAnnotation(ClassName("dagger", "Module")) + .addAnnotation( + AnnotationSpec.builder(ClassName("javax.annotation.processing", "Generated")) + .addMember("value = [%S]", this::class.qualifiedName!!) + .build() + ) .addFunctions(bindings) .build() -- 2.29.2 From 456e76ce31c05500ab7d9e78e2b02019143929a4 Mon Sep 17 00:00:00 2001 From: fredboy Date: Wed, 15 May 2024 01:06:51 +0700 Subject: [PATCH 10/16] Change generated modules package and move annotations --- .../cavedroid/game/GameComponent.java | 8 +------- .../actions/placeblock/IPlaceBlockAction.kt | 9 +++++++++ .../game/actions/placeblock/PlaceBlockAction.kt | 17 ----------------- .../PlaceBlockItemToBackgroundAction.kt | 3 ++- .../PlaceBlockItemToForegroundAction.kt | 3 ++- .../game/actions/placeblock/PlaceSlabAction.kt | 3 ++- .../actions/updateblock/IUpdateBlockAction.kt | 9 --------- .../actions/updateblock/UpdateBedLeftAction.kt | 3 ++- .../actions/updateblock/UpdateBedRightAction.kt | 3 ++- .../actions/updateblock/UpdateGrassAction.kt | 3 ++- .../actions/updateblock/UpdateGravelAction.kt | 3 ++- .../updateblock/UpdateRequiresBlockAction.kt | 3 ++- .../actions/updateblock/UpdateSandAction.kt | 3 ++- .../updateblock/UpdateSnowedGrassAction.kt | 3 ++- .../game/actions/useblock/IUseBlockAction.kt | 9 +++++++++ .../game/actions/useblock/UseBlockAction.kt | 17 ----------------- .../game/actions/useblock/UseChestAction.kt | 3 ++- .../actions/useblock/UseCraftingTableAction.kt | 3 ++- .../game/actions/useblock/UseFurnaceAction.kt | 3 ++- .../game/actions/useitem/IUseItemAction.kt | 9 +++++++++ .../game/actions/useitem/UseBedAction.kt | 3 ++- .../actions/useitem/UseEmptyBucketAction.kt | 3 ++- .../game/actions/useitem/UseItemAction.kt | 17 ----------------- .../game/actions/useitem/UseLavaBucketAction.kt | 3 ++- .../actions/useitem/UsePigSpawnEggAction.kt | 3 ++- .../actions/useitem/UseWaterBucketAction.kt | 3 ++- ...GameInputHandler.kt => IGameInputHandler.kt} | 15 --------------- .../CloseGameWindowKeyboardInputHandler.kt | 4 ++-- .../keyboard/DropItemKeyboardInputHandler.kt | 4 ++-- .../keyboard/FlyDownKeyboardInputHandler.kt | 4 ++-- .../keyboard/FlyUpKeyboardInputHandler.kt | 4 ++-- .../keyboard/GoLeftKeyboardInputHandler.kt | 4 ++-- .../keyboard/GoRightKeyboardInputHandler.kt | 4 ++-- .../keyboard/JumpKeyboardInputHandler.kt | 4 ++-- ...oveCursorControlsModeKeyboardInputHandler.kt | 4 ++-- .../OpenInventoryKeyboardInputHandler.kt | 4 ++-- .../keyboard/PauseGameKeyboardInputHandler.kt | 4 ++-- .../SelectHotbarSlotKeyboardInputHandler.kt | 4 ++-- .../keyboard/StopSwimKeyboardInputHandler.kt | 4 ++-- .../keyboard/SwimUpKeyboardInputHandler.kt | 4 ++-- .../ToggleControlsModeKeyboardInputHandler.kt | 4 ++-- .../ToggleDebugInfoKeyboardInputHandler.kt | 4 ++-- .../ToggleGameModeKeyboardInputHandler.kt | 4 ++-- .../ToggleMinimapKeyboardInputHandler.kt | 4 ++-- .../TurnOnFlyModeKeyboardInputHandler.kt | 4 ++-- .../handler/mouse/AttackMouseInputHandler.kt | 4 ++-- .../mouse/CloseGameWindowMouseInputHandler.kt | 4 ++-- .../CreativeInventoryScrollMouseInputHandler.kt | 4 ++-- .../handler/mouse/CursorMouseInputHandler.kt | 4 ++-- .../handler/mouse/HotbarMouseInputHandler.kt | 4 ++-- ...SelectChestInventoryItemMouseInputHandler.kt | 4 ++-- ...ectCraftingInventoryItemMouseInputHandler.kt | 4 ++-- ...ectCreativeInventoryItemMouseInputHandler.kt | 4 ++-- ...lectFurnaceInventoryItemMouseInputHandler.kt | 4 ++-- ...ectSurvivalInventoryItemMouseInputHandler.kt | 4 ++-- .../handler/mouse/UseItemMouseInputHandler.kt | 4 ++-- .../input/handler/touch/JoystickInputHandler.kt | 3 ++- .../game/render/BackgroundBlocksRenderer.kt | 3 ++- .../cavedroid/game/render/DebugRenderer.kt | 3 ++- .../cavedroid/game/render/DropsRenderer.kt | 3 ++- .../game/render/ForegroundBlocksRenderer.kt | 3 ++- .../cavedroid/game/render/HudRenderer.kt | 3 ++- .../{GameRenderer.kt => IGameRenderer.kt} | 8 -------- .../cavedroid/game/render/MobsRenderer.kt | 3 ++- .../game/render/TouchControlsRenderer.kt | 3 ++- .../cavedroid/game/render/WindowsRenderer.kt | 3 ++- .../multibinding/BindKeyboardInputHandler.kt | 11 +++++++++++ .../multibinding/BindMouseInputHandler.kt | 11 +++++++++++ .../multibinding/BindPlaceBlockAction.kt | 11 +++++++++++ .../annotations/multibinding/BindRenderer.kt | 11 +++++++++++ .../multibinding/BindUpdateBlockAction.kt | 11 +++++++++++ .../multibinding/BindUseBlockAction.kt | 11 +++++++++++ .../multibinding/BindUseItemAction.kt | 11 +++++++++++ .../multibinding/MultibindingConfig.kt | 5 +++++ 74 files changed, 222 insertions(+), 175 deletions(-) create mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/IPlaceBlockAction.kt delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockAction.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/useblock/IUseBlockAction.kt delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseBlockAction.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/useitem/IUseItemAction.kt delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseItemAction.kt rename core/src/ru/deadsoftware/cavedroid/game/input/{GameInputHandler.kt => IGameInputHandler.kt} (60%) rename core/src/ru/deadsoftware/cavedroid/game/render/{GameRenderer.kt => IGameRenderer.kt} (61%) create mode 100644 core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindKeyboardInputHandler.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindMouseInputHandler.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindPlaceBlockAction.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindRenderer.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUpdateBlockAction.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseBlockAction.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseItemAction.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/MultibindingConfig.kt diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameComponent.java b/core/src/ru/deadsoftware/cavedroid/game/GameComponent.java index 624e544..94d37d4 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameComponent.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameComponent.java @@ -2,13 +2,7 @@ package ru.deadsoftware.cavedroid.game; import dagger.Component; import ru.deadsoftware.cavedroid.MainComponent; -import ru.deadsoftware.cavedroid.game.actions.PlaceBlockActionsModule; -import ru.deadsoftware.cavedroid.game.actions.UpdateBlockActionsModule; -import ru.deadsoftware.cavedroid.game.actions.UseBlockActionsModule; -import ru.deadsoftware.cavedroid.game.actions.UseItemActionsModule; -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandlersModule; -import ru.deadsoftware.cavedroid.game.input.MouseInputHandlersModule; -import ru.deadsoftware.cavedroid.game.render.RenderModule; +import ru.deadsoftware.cavedroid.generated.module.*; @GameScope @Component(dependencies = MainComponent.class, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/IPlaceBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/IPlaceBlockAction.kt new file mode 100644 index 0000000..06c70c4 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/IPlaceBlockAction.kt @@ -0,0 +1,9 @@ +package ru.deadsoftware.cavedroid.game.actions.placeblock + +import ru.deadsoftware.cavedroid.game.model.item.Item + +interface IPlaceBlockAction { + + fun place(placeable: Item.Placeable, x: Int, y: Int) + +} diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockAction.kt deleted file mode 100644 index e0f6cd8..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockAction.kt +++ /dev/null @@ -1,17 +0,0 @@ -package ru.deadsoftware.cavedroid.game.actions.placeblock - -import ru.deadsoftware.cavedroid.game.model.item.Item -import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule - -@GenerateMapMultibindingsModule( - interfaceClass = IPlaceBlockAction::class, - modulePackage = "ru.deadsoftware.cavedroid.game.actions", - moduleName = "PlaceBlockActionsModule" -) -annotation class PlaceBlockAction(val stringKey: String) - -interface IPlaceBlockAction { - - fun place(placeable: Item.Placeable, x: Int, y: Int) - -} diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToBackgroundAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToBackgroundAction.kt index 0a5399a..7258301 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToBackgroundAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToBackgroundAction.kt @@ -5,10 +5,11 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.Item import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindPlaceBlockAction import javax.inject.Inject @GameScope -@PlaceBlockAction(stringKey = PlaceBlockItemToBackgroundAction.ACTION_KEY) +@BindPlaceBlockAction(stringKey = PlaceBlockItemToBackgroundAction.ACTION_KEY) class PlaceBlockItemToBackgroundAction @Inject constructor( private val gameWorld: GameWorld, private val gameItemsHolder: GameItemsHolder, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToForegroundAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToForegroundAction.kt index d3ff979..ec249fb 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToForegroundAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToForegroundAction.kt @@ -5,10 +5,11 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.Item import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindPlaceBlockAction import javax.inject.Inject @GameScope -@PlaceBlockAction(stringKey = PlaceBlockItemToForegroundAction.ACTION_KEY) +@BindPlaceBlockAction(stringKey = PlaceBlockItemToForegroundAction.ACTION_KEY) class PlaceBlockItemToForegroundAction @Inject constructor( private val gameWorld: GameWorld, private val placeSlabAction: PlaceSlabAction, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceSlabAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceSlabAction.kt index 3e0a185..00c62d7 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceSlabAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceSlabAction.kt @@ -6,10 +6,11 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.Item import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindPlaceBlockAction import javax.inject.Inject @GameScope -@PlaceBlockAction(stringKey = PlaceSlabAction.ACTION_KEY) +@BindPlaceBlockAction(stringKey = PlaceSlabAction.ACTION_KEY) class PlaceSlabAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/IUpdateBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/IUpdateBlockAction.kt index a397f16..9cc4aea 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/IUpdateBlockAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/IUpdateBlockAction.kt @@ -1,14 +1,5 @@ package ru.deadsoftware.cavedroid.game.actions.updateblock -import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule - -@GenerateMapMultibindingsModule( - interfaceClass = IUpdateBlockAction::class, - modulePackage = "ru.deadsoftware.cavedroid.game.actions", - moduleName = "UpdateBlockActionsModule" -) -annotation class UpdateBlockAction(val stringKey: String) - interface IUpdateBlockAction { fun update(x: Int, y: Int) diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedLeftAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedLeftAction.kt index 4e43f8f..5507550 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedLeftAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedLeftAction.kt @@ -5,10 +5,11 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.FallingGravel import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUpdateBlockAction import javax.inject.Inject @GameScope -@UpdateBlockAction(stringKey = UpdateBedLeftAction.BLOCK_KEY) +@BindUpdateBlockAction(stringKey = UpdateBedLeftAction.BLOCK_KEY) class UpdateBedLeftAction @Inject constructor( private val gameWorld: GameWorld, private val gameItemsHolder: GameItemsHolder, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedRightAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedRightAction.kt index 78e81fa..42f551e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedRightAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateBedRightAction.kt @@ -5,10 +5,11 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.FallingGravel import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUpdateBlockAction import javax.inject.Inject @GameScope -@UpdateBlockAction(stringKey = UpdateBedRightAction.BLOCK_KEY) +@BindUpdateBlockAction(stringKey = UpdateBedRightAction.BLOCK_KEY) class UpdateBedRightAction @Inject constructor( private val gameWorld: GameWorld, private val gameItemsHolder: GameItemsHolder, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGrassAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGrassAction.kt index 56f814f..476235a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGrassAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGrassAction.kt @@ -3,10 +3,11 @@ package ru.deadsoftware.cavedroid.game.actions.updateblock import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUpdateBlockAction import javax.inject.Inject @GameScope -@UpdateBlockAction(stringKey = UpdateGrassAction.BLOCK_KEY) +@BindUpdateBlockAction(stringKey = UpdateGrassAction.BLOCK_KEY) class UpdateGrassAction @Inject constructor( private val gameWorld: GameWorld, private val mGameItemsHolder: GameItemsHolder, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGravelAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGravelAction.kt index f51bc7f..3c52418 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGravelAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateGravelAction.kt @@ -4,10 +4,11 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.FallingGravel import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUpdateBlockAction import javax.inject.Inject @GameScope -@UpdateBlockAction(stringKey = UpdateGravelAction.BLOCK_KEY) +@BindUpdateBlockAction(stringKey = UpdateGravelAction.BLOCK_KEY) class UpdateGravelAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateRequiresBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateRequiresBlockAction.kt index 6b15a7a..05d9863 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateRequiresBlockAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateRequiresBlockAction.kt @@ -2,10 +2,11 @@ package ru.deadsoftware.cavedroid.game.actions.updateblock import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUpdateBlockAction import javax.inject.Inject @GameScope -@UpdateBlockAction(stringKey = UpdateRequiresBlockAction.ACTION_KEY) +@BindUpdateBlockAction(stringKey = UpdateRequiresBlockAction.ACTION_KEY) class UpdateRequiresBlockAction @Inject constructor( private val gameWorld: GameWorld, ) : IUpdateBlockAction { diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSandAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSandAction.kt index f2ef25e..ac1ff8a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSandAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSandAction.kt @@ -4,10 +4,11 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.FallingSand import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUpdateBlockAction import javax.inject.Inject @GameScope -@UpdateBlockAction(stringKey = UpdateSandAction.BLOCK_KEY) +@BindUpdateBlockAction(stringKey = UpdateSandAction.BLOCK_KEY) class UpdateSandAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSnowedGrassAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSnowedGrassAction.kt index 049c90b..2cf5a57 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSnowedGrassAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/updateblock/UpdateSnowedGrassAction.kt @@ -3,10 +3,11 @@ package ru.deadsoftware.cavedroid.game.actions.updateblock import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUpdateBlockAction import javax.inject.Inject @GameScope -@UpdateBlockAction(stringKey = UpdateSnowedGrassAction.BLOCK_KEY) +@BindUpdateBlockAction(stringKey = UpdateSnowedGrassAction.BLOCK_KEY) class UpdateSnowedGrassAction @Inject constructor( private val gameWorld: GameWorld, private val mGameItemsHolder: GameItemsHolder, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/IUseBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/IUseBlockAction.kt new file mode 100644 index 0000000..ddc70c5 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/IUseBlockAction.kt @@ -0,0 +1,9 @@ +package ru.deadsoftware.cavedroid.game.actions.useblock + +import ru.deadsoftware.cavedroid.game.model.block.Block + +interface IUseBlockAction { + + fun perform(block: Block, x: Int, y: Int) + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseBlockAction.kt deleted file mode 100644 index 932bbf6..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseBlockAction.kt +++ /dev/null @@ -1,17 +0,0 @@ -package ru.deadsoftware.cavedroid.game.actions.useblock - -import ru.deadsoftware.cavedroid.game.model.block.Block -import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule - -@GenerateMapMultibindingsModule( - interfaceClass = IUseBlockAction::class, - modulePackage = "ru.deadsoftware.cavedroid.game.actions", - moduleName = "UseBlockActionsModule" -) -annotation class UseBlockAction(val stringKey: String) - -interface IUseBlockAction { - - fun perform(block: Block, x: Int, y: Int) - -} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseChestAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseChestAction.kt index fd370db..93684e7 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseChestAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseChestAction.kt @@ -5,10 +5,11 @@ import ru.deadsoftware.cavedroid.game.model.block.Block import ru.deadsoftware.cavedroid.game.objects.container.Chest import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUseBlockAction import javax.inject.Inject @GameScope -@UseBlockAction(stringKey = UseChestAction.KEY) +@BindUseBlockAction(stringKey = UseChestAction.KEY) class UseChestAction @Inject constructor( private val gameWorld: GameWorld, private val gameWindowsManager: GameWindowsManager, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt index de1112e..6d6c1e9 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt @@ -3,10 +3,11 @@ package ru.deadsoftware.cavedroid.game.actions.useblock import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.model.block.Block import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUseBlockAction import javax.inject.Inject @GameScope -@UseBlockAction(stringKey = UseCraftingTableAction.KEY) +@BindUseBlockAction(stringKey = UseCraftingTableAction.KEY) class UseCraftingTableAction @Inject constructor( private val gameWindowsManager: GameWindowsManager ) : IUseBlockAction { diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt index 1426263..0b8ba53 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt @@ -4,10 +4,11 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.model.block.Block import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUseBlockAction import javax.inject.Inject @GameScope -@UseBlockAction(stringKey = UseFurnaceAction.KEY) +@BindUseBlockAction(stringKey = UseFurnaceAction.KEY) class UseFurnaceAction @Inject constructor( private val gameWorld: GameWorld, private val gameWindowsManager: GameWindowsManager, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/IUseItemAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/IUseItemAction.kt new file mode 100644 index 0000000..d963aee --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/IUseItemAction.kt @@ -0,0 +1,9 @@ +package ru.deadsoftware.cavedroid.game.actions.useitem + +import ru.deadsoftware.cavedroid.game.model.item.Item + +interface IUseItemAction { + + fun perform(item: Item.Usable, x: Int, y: Int) + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseBedAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseBedAction.kt index 1aefd67..f48115e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseBedAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseBedAction.kt @@ -5,10 +5,11 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.Item import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUseItemAction import javax.inject.Inject @GameScope -@UseItemAction(UseBedAction.ACTION_KEY) +@BindUseItemAction(UseBedAction.ACTION_KEY) class UseBedAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseEmptyBucketAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseEmptyBucketAction.kt index fd64751..6992af7 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseEmptyBucketAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseEmptyBucketAction.kt @@ -6,10 +6,11 @@ import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.block.Block import ru.deadsoftware.cavedroid.game.model.item.Item import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUseItemAction import javax.inject.Inject @GameScope -@UseItemAction(UseEmptyBucketAction.ACTION_KEY) +@BindUseItemAction(UseEmptyBucketAction.ACTION_KEY) class UseEmptyBucketAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseItemAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseItemAction.kt deleted file mode 100644 index be4d254..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseItemAction.kt +++ /dev/null @@ -1,17 +0,0 @@ -package ru.deadsoftware.cavedroid.game.actions.useitem - -import ru.deadsoftware.cavedroid.game.model.item.Item -import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule - -@GenerateMapMultibindingsModule( - interfaceClass = IUseItemAction::class, - modulePackage = "ru.deadsoftware.cavedroid.game.actions", - moduleName = "UseItemActionsModule" -) -annotation class UseItemAction(val stringKey: String) - -interface IUseItemAction { - - fun perform(item: Item.Usable, x: Int, y: Int) - -} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseLavaBucketAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseLavaBucketAction.kt index 70438e3..ec1e585 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseLavaBucketAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseLavaBucketAction.kt @@ -5,10 +5,11 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.Item import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUseItemAction import javax.inject.Inject @GameScope -@UseItemAction(UseLavaBucketAction.ACTION_KEY) +@BindUseItemAction(UseLavaBucketAction.ACTION_KEY) class UseLavaBucketAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt index 4b2aa00..5eddc5e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt @@ -5,11 +5,12 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.Pig import ru.deadsoftware.cavedroid.game.model.item.Item +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUseItemAction import ru.deadsoftware.cavedroid.misc.utils.px import javax.inject.Inject @GameScope -@UseItemAction(UsePigSpawnEggAction.ACTION_KEY) +@BindUseItemAction(UsePigSpawnEggAction.ACTION_KEY) class UsePigSpawnEggAction @Inject constructor( private val mobsController: MobsController, private val gameItemsHolder: GameItemsHolder, diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseWaterBucketAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseWaterBucketAction.kt index 83b8f24..739ec28 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseWaterBucketAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseWaterBucketAction.kt @@ -5,10 +5,11 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.Item import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindUseItemAction import javax.inject.Inject @GameScope -@UseItemAction(UseWaterBucketAction.ACTION_KEY) +@BindUseItemAction(UseWaterBucketAction.ACTION_KEY) class UseWaterBucketAction @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/GameInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/IGameInputHandler.kt similarity index 60% rename from core/src/ru/deadsoftware/cavedroid/game/input/GameInputHandler.kt rename to core/src/ru/deadsoftware/cavedroid/game/input/IGameInputHandler.kt index 55dc618..2c5f118 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/GameInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/IGameInputHandler.kt @@ -3,21 +3,6 @@ package ru.deadsoftware.cavedroid.game.input import ru.deadsoftware.cavedroid.game.input.action.IGameInputAction import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction -import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule - -@GenerateSetMultibindingsModule( - interfaceClass = IKeyboardInputHandler::class, - modulePackage = "ru.deadsoftware.cavedroid.game.input", - moduleName = "KeyboardInputHandlersModule" -) -annotation class KeyboardInputHandler - -@GenerateSetMultibindingsModule( - interfaceClass = IMouseInputHandler::class, - modulePackage = "ru.deadsoftware.cavedroid.game.input", - moduleName = "MouseInputHandlersModule" -) -annotation class MouseInputHandler interface IKeyboardInputHandler : IGameInputHandler diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt index cbc254e..8bf9b1c 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt @@ -3,16 +3,16 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class CloseGameWindowKeyboardInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt index 01a0c1f..e9c8eb0 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt @@ -3,7 +3,6 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController @@ -11,10 +10,11 @@ import ru.deadsoftware.cavedroid.game.model.item.Item import ru.deadsoftware.cavedroid.game.objects.drop.Drop import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class DropItemKeyboardInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyDownKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyDownKeyboardInputHandler.kt index 8e41dfe..ae5f4c3 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyDownKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyDownKeyboardInputHandler.kt @@ -3,15 +3,15 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class FlyDownKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyUpKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyUpKeyboardInputHandler.kt index 976b069..444fe09 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyUpKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/FlyUpKeyboardInputHandler.kt @@ -3,15 +3,15 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class FlyUpKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoLeftKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoLeftKeyboardInputHandler.kt index 8234476..2b40d46 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoLeftKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoLeftKeyboardInputHandler.kt @@ -3,16 +3,16 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.Mob import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class GoLeftKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoRightKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoRightKeyboardInputHandler.kt index 3139a17..ec38218 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoRightKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/GoRightKeyboardInputHandler.kt @@ -3,16 +3,16 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.Mob import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class GoRightKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/JumpKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/JumpKeyboardInputHandler.kt index 30f12dd..bcacbf5 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/JumpKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/JumpKeyboardInputHandler.kt @@ -3,15 +3,15 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class JumpKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/MoveCursorControlsModeKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/MoveCursorControlsModeKeyboardInputHandler.kt index 98d3e0a..84c5b90 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/MoveCursorControlsModeKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/MoveCursorControlsModeKeyboardInputHandler.kt @@ -3,16 +3,16 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class MoveCursorControlsModeKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt index a1ca3da..70ae158 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt @@ -3,14 +3,14 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class OpenInventoryKeyboardInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, ) : IKeyboardInputHandler { diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt index e4d6707..cedc78a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt @@ -5,7 +5,6 @@ import ru.deadsoftware.cavedroid.game.GameSaver import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController @@ -13,10 +12,11 @@ import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.objects.container.ContainerController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class PauseGameKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val dropController: DropController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SelectHotbarSlotKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SelectHotbarSlotKeyboardInputHandler.kt index 0c7ea74..d22cd94 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SelectHotbarSlotKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SelectHotbarSlotKeyboardInputHandler.kt @@ -2,14 +2,14 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class SelectHotbarSlotKeyboardInputHandler @Inject constructor( private val mobsController: MobsController, ) : IKeyboardInputHandler { diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/StopSwimKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/StopSwimKeyboardInputHandler.kt index 7256c54..d8c5acc 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/StopSwimKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/StopSwimKeyboardInputHandler.kt @@ -3,16 +3,16 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class StopSwimKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SwimUpKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SwimUpKeyboardInputHandler.kt index 9dc4777..20cc82e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SwimUpKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SwimUpKeyboardInputHandler.kt @@ -3,16 +3,16 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class SwimUpKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleControlsModeKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleControlsModeKeyboardInputHandler.kt index a933c80..f8e0177 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleControlsModeKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleControlsModeKeyboardInputHandler.kt @@ -3,15 +3,15 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class ToggleControlsModeKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleDebugInfoKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleDebugInfoKeyboardInputHandler.kt index 065b28c..7cf08ed 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleDebugInfoKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleDebugInfoKeyboardInputHandler.kt @@ -3,13 +3,13 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class ToggleDebugInfoKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig ) : IKeyboardInputHandler { diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleGameModeKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleGameModeKeyboardInputHandler.kt index a17e6d2..64a1116 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleGameModeKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleGameModeKeyboardInputHandler.kt @@ -2,14 +2,14 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class ToggleGameModeKeyboardInputHandler @Inject constructor( private val mobsController: MobsController ) : IKeyboardInputHandler { diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleMinimapKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleMinimapKeyboardInputHandler.kt index 6f22e4c..2cd6638 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleMinimapKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/ToggleMinimapKeyboardInputHandler.kt @@ -3,13 +3,13 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class ToggleMinimapKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, ) : IKeyboardInputHandler { diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/TurnOnFlyModeKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/TurnOnFlyModeKeyboardInputHandler.kt index 3b43d31..43a7122 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/TurnOnFlyModeKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/TurnOnFlyModeKeyboardInputHandler.kt @@ -3,15 +3,15 @@ package ru.deadsoftware.cavedroid.game.input.handler.keyboard import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.deadsoftware.cavedroid.game.input.KeyboardInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindKeyboardInputHandler import javax.inject.Inject @GameScope -@KeyboardInputHandler +@BindKeyboardInputHandler class TurnOnFlyModeKeyboardInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt index c2a22ed..52333eb 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt @@ -1,9 +1,9 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindMouseInputHandler import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler -import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideHotbar @@ -13,7 +13,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope -@MouseInputHandler +@BindMouseInputHandler class AttackMouseInputHandler @Inject constructor( private val mobsController: MobsController, private val gameWorld: GameWorld, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt index b5ff2c5..4fb0879 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt @@ -1,11 +1,11 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindMouseInputHandler import com.badlogic.gdx.graphics.g2d.TextureRegion import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler -import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideWindow @@ -15,7 +15,7 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope -@MouseInputHandler +@BindMouseInputHandler class CloseGameWindowMouseInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt index bf6ba37..8acdb7e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt @@ -1,5 +1,6 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindMouseInputHandler import com.badlogic.gdx.math.MathUtils import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameItemsHolder @@ -7,7 +8,6 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler -import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideWindow @@ -16,7 +16,7 @@ import javax.inject.Inject import kotlin.math.abs @GameScope -@MouseInputHandler +@BindMouseInputHandler class CreativeInventoryScrollMouseInputHandler @Inject constructor( private val mainConfig: MainConfig, private val gameWindowsManager: GameWindowsManager, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt index 5d5c79f..c1f2af5 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt @@ -1,12 +1,12 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindMouseInputHandler import com.badlogic.gdx.math.MathUtils import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler -import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.mobs.Mob @@ -23,7 +23,7 @@ import ru.deadsoftware.cavedroid.misc.utils.px import javax.inject.Inject @GameScope -@MouseInputHandler +@BindMouseInputHandler class CursorMouseInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt index 45ae49b..6a66338 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt @@ -1,11 +1,11 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindMouseInputHandler import com.badlogic.gdx.utils.Timer import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler -import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.handler.keyboard.DropItemKeyboardInputHandler.Companion.DROP_DISTANCE @@ -19,7 +19,7 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope -@MouseInputHandler +@BindMouseInputHandler class HotbarMouseInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectChestInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectChestInventoryItemMouseInputHandler.kt index 3118e9f..62a4836 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectChestInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectChestInventoryItemMouseInputHandler.kt @@ -1,9 +1,9 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindMouseInputHandler import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow -import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs @@ -13,7 +13,7 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope -@MouseInputHandler +@BindMouseInputHandler class SelectChestInventoryItemMouseInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt index cc993c9..aefea54 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt @@ -1,9 +1,9 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindMouseInputHandler import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow -import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs @@ -13,7 +13,7 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope -@MouseInputHandler +@BindMouseInputHandler class SelectCraftingInventoryItemMouseInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt index 5c6975f..976f443 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt @@ -1,11 +1,11 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindMouseInputHandler import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler -import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideWindow @@ -15,7 +15,7 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope -@MouseInputHandler +@BindMouseInputHandler class SelectCreativeInventoryItemMouseInputHandler @Inject constructor( private val gameItemsHolder: GameItemsHolder, private val gameWindowsManager: GameWindowsManager, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt index 164b0c1..eac8cfa 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt @@ -1,9 +1,9 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindMouseInputHandler import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow -import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.InventoryItem.Companion.isNoneOrNull @@ -15,7 +15,7 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope -@MouseInputHandler +@BindMouseInputHandler class SelectFurnaceInventoryItemMouseInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt index 9f25b9a..58687fc 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt @@ -1,9 +1,9 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindMouseInputHandler import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow -import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs @@ -13,7 +13,7 @@ import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @GameScope -@MouseInputHandler +@BindMouseInputHandler class SelectSurvivalInventoryItemMouseInputHandler @Inject constructor( private val gameWindowsManager: GameWindowsManager, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt index c0ff332..541bba7 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt @@ -1,5 +1,6 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindMouseInputHandler import com.badlogic.gdx.Gdx import com.badlogic.gdx.utils.Timer import ru.deadsoftware.cavedroid.game.GameScope @@ -10,7 +11,6 @@ import ru.deadsoftware.cavedroid.game.actions.placeblock.IPlaceBlockAction import ru.deadsoftware.cavedroid.game.actions.useblock.IUseBlockAction import ru.deadsoftware.cavedroid.game.actions.useitem.IUseItemAction import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler -import ru.deadsoftware.cavedroid.game.input.MouseInputHandler import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideHotbar @@ -21,7 +21,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope -@MouseInputHandler +@BindMouseInputHandler class UseItemMouseInputHandler @Inject constructor( private val mobsController: MobsController, private val useItemActionMap: Map, diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/touch/JoystickInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/touch/JoystickInputHandler.kt index b6f31a3..d717c18 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/touch/JoystickInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/touch/JoystickInputHandler.kt @@ -1,5 +1,6 @@ package ru.deadsoftware.cavedroid.game.input.handler.touch +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindMouseInputHandler import com.badlogic.gdx.utils.TimeUtils import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameScope @@ -15,7 +16,7 @@ import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope -@MouseInputHandler +@BindMouseInputHandler class JoystickInputHandler @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/BackgroundBlocksRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/BackgroundBlocksRenderer.kt index e86450c..0d34540 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/BackgroundBlocksRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/BackgroundBlocksRenderer.kt @@ -8,11 +8,12 @@ import com.badlogic.gdx.math.Rectangle import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindRenderer import ru.deadsoftware.cavedroid.misc.utils.forEachBlockInArea import javax.inject.Inject @GameScope -@GameRenderer +@BindRenderer class BackgroundBlocksRenderer @Inject constructor( gameWorld: GameWorld, mobsController: MobsController diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/DebugRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/DebugRenderer.kt index d1a1d16..0fa2756 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/DebugRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/DebugRenderer.kt @@ -10,14 +10,15 @@ import ru.deadsoftware.cavedroid.game.debug.DebugInfoStringsProvider import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.block.Block import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindRenderer import ru.deadsoftware.cavedroid.misc.utils.bl import ru.deadsoftware.cavedroid.misc.utils.drawString import ru.deadsoftware.cavedroid.misc.utils.forEachBlockInArea import ru.deadsoftware.cavedroid.misc.utils.px import javax.inject.Inject -@GameRenderer @GameScope +@BindRenderer class DebugRenderer @Inject constructor( private val mainConfig: MainConfig, private val gameWorld: GameWorld, diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt index 5e1da4a..d1fc65a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt @@ -6,13 +6,14 @@ import com.badlogic.gdx.math.Rectangle import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindRenderer import ru.deadsoftware.cavedroid.misc.utils.cycledInsideWorld import ru.deadsoftware.cavedroid.misc.utils.drawSprite import ru.deadsoftware.cavedroid.misc.utils.px import javax.inject.Inject @GameScope -@GameRenderer +@BindRenderer class DropsRenderer @Inject constructor( private val dropController: DropController, private val gameWorld: GameWorld, diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/ForegroundBlocksRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/ForegroundBlocksRenderer.kt index 0bb4001..8353b0b 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/ForegroundBlocksRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/ForegroundBlocksRenderer.kt @@ -6,11 +6,12 @@ import com.badlogic.gdx.math.Rectangle import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindRenderer import ru.deadsoftware.cavedroid.misc.utils.forEachBlockInArea import javax.inject.Inject @GameScope -@GameRenderer +@BindRenderer class ForegroundBlocksRenderer @Inject constructor( gameWorld: GameWorld, mobsController: MobsController diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt index cb70e16..b6b22ae 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt @@ -10,12 +10,13 @@ import ru.deadsoftware.cavedroid.game.mobs.player.Player.ControlMode import ru.deadsoftware.cavedroid.game.ui.TooltipManager import ru.deadsoftware.cavedroid.game.world.GameWorld import ru.deadsoftware.cavedroid.misc.Assets +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindRenderer import ru.deadsoftware.cavedroid.misc.utils.drawString import ru.deadsoftware.cavedroid.misc.utils.px import javax.inject.Inject @GameScope -@GameRenderer +@BindRenderer class HudRenderer @Inject constructor( private val gameWorld: GameWorld, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/GameRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/IGameRenderer.kt similarity index 61% rename from core/src/ru/deadsoftware/cavedroid/game/render/GameRenderer.kt rename to core/src/ru/deadsoftware/cavedroid/game/render/IGameRenderer.kt index c0ded1e..88b5744 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/GameRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/IGameRenderer.kt @@ -3,14 +3,6 @@ package ru.deadsoftware.cavedroid.game.render import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShapeRenderer import com.badlogic.gdx.math.Rectangle -import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule - -@GenerateSetMultibindingsModule( - interfaceClass = IGameRenderer::class, - modulePackage = "ru.deadsoftware.cavedroid.game.render", - moduleName = "RenderModule" -) -annotation class GameRenderer interface IGameRenderer { diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/MobsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/MobsRenderer.kt index ab1dd01..52ac971 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/MobsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/MobsRenderer.kt @@ -7,12 +7,13 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.Mob import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.world.GameWorld +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindRenderer import ru.deadsoftware.cavedroid.misc.utils.cycledInsideWorld import ru.deadsoftware.cavedroid.misc.utils.px import javax.inject.Inject @GameScope -@GameRenderer +@BindRenderer class MobsRenderer @Inject constructor( private val mobsController: MobsController, private val gameWorld: GameWorld, diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt index 29702ae..f2198aa 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt @@ -11,13 +11,14 @@ import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player.ControlMode import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import ru.deadsoftware.cavedroid.misc.Assets +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindRenderer import ru.deadsoftware.cavedroid.misc.utils.ArrayMapExtensions.component1 import ru.deadsoftware.cavedroid.misc.utils.ArrayMapExtensions.component2 import ru.deadsoftware.cavedroid.misc.utils.drawSprite import javax.inject.Inject @GameScope -@GameRenderer +@BindRenderer class TouchControlsRenderer @Inject constructor( private val mainConfig: MainConfig, private val mobsController: MobsController, diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt index 4e65b41..945bb1e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt @@ -8,10 +8,11 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.render.windows.* import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.misc.annotations.multibinding.BindRenderer import javax.inject.Inject @GameScope -@GameRenderer +@BindRenderer class WindowsRenderer @Inject constructor( private val creativeWindowRenderer: CreativeWindowRenderer, private val survivalWindowRenderer: SurvivalWindowRenderer, diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindKeyboardInputHandler.kt new file mode 100644 index 0000000..004012d --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindKeyboardInputHandler.kt @@ -0,0 +1,11 @@ +package ru.deadsoftware.cavedroid.misc.annotations.multibinding + +import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler +import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule + +@GenerateSetMultibindingsModule( + interfaceClass = IKeyboardInputHandler::class, + modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, + moduleName = "KeyboardInputHandlersModule" +) +annotation class BindKeyboardInputHandler \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindMouseInputHandler.kt new file mode 100644 index 0000000..02b934c --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindMouseInputHandler.kt @@ -0,0 +1,11 @@ +package ru.deadsoftware.cavedroid.misc.annotations.multibinding + +import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler +import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule + +@GenerateSetMultibindingsModule( + interfaceClass = IMouseInputHandler::class, + modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, + moduleName = "MouseInputHandlersModule" +) +annotation class BindMouseInputHandler \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindPlaceBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindPlaceBlockAction.kt new file mode 100644 index 0000000..779835f --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindPlaceBlockAction.kt @@ -0,0 +1,11 @@ +package ru.deadsoftware.cavedroid.misc.annotations.multibinding + +import ru.deadsoftware.cavedroid.game.actions.placeblock.IPlaceBlockAction +import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule + +@GenerateMapMultibindingsModule( + interfaceClass = IPlaceBlockAction::class, + modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, + moduleName = "PlaceBlockActionsModule" +) +annotation class BindPlaceBlockAction(val stringKey: String) diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindRenderer.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindRenderer.kt new file mode 100644 index 0000000..ae994ea --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindRenderer.kt @@ -0,0 +1,11 @@ +package ru.deadsoftware.cavedroid.misc.annotations.multibinding + +import ru.deadsoftware.cavedroid.game.render.IGameRenderer +import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule + +@GenerateSetMultibindingsModule( + interfaceClass = IGameRenderer::class, + modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, + moduleName = "RenderModule" +) +annotation class BindRenderer diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUpdateBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUpdateBlockAction.kt new file mode 100644 index 0000000..8665ec1 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUpdateBlockAction.kt @@ -0,0 +1,11 @@ +package ru.deadsoftware.cavedroid.misc.annotations.multibinding + +import ru.deadsoftware.cavedroid.game.actions.updateblock.IUpdateBlockAction +import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule + +@GenerateMapMultibindingsModule( + interfaceClass = IUpdateBlockAction::class, + modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, + moduleName = "UpdateBlockActionsModule" +) +annotation class BindUpdateBlockAction(val stringKey: String) \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseBlockAction.kt new file mode 100644 index 0000000..b34214d --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseBlockAction.kt @@ -0,0 +1,11 @@ +package ru.deadsoftware.cavedroid.misc.annotations.multibinding + +import ru.deadsoftware.cavedroid.game.actions.useblock.IUseBlockAction +import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule + +@GenerateMapMultibindingsModule( + interfaceClass = IUseBlockAction::class, + modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, + moduleName = "UseBlockActionsModule" +) +annotation class BindUseBlockAction(val stringKey: String) diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseItemAction.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseItemAction.kt new file mode 100644 index 0000000..de2c74f --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseItemAction.kt @@ -0,0 +1,11 @@ +package ru.deadsoftware.cavedroid.misc.annotations.multibinding + +import ru.deadsoftware.cavedroid.game.actions.useitem.IUseItemAction +import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule + +@GenerateMapMultibindingsModule( + interfaceClass = IUseItemAction::class, + modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, + moduleName = "UseItemActionsModule" +) +annotation class BindUseItemAction(val stringKey: String) diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/MultibindingConfig.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/MultibindingConfig.kt new file mode 100644 index 0000000..12427bd --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/MultibindingConfig.kt @@ -0,0 +1,5 @@ +package ru.deadsoftware.cavedroid.misc.annotations.multibinding + +data object MultibindingConfig { + const val GENERATED_MODULES_PACKAGE = "ru.deadsoftware.cavedroid.generated.module" +} \ No newline at end of file -- 2.29.2 From d01792885c45d3c027e96bf5bf51f00492f600de Mon Sep 17 00:00:00 2001 From: fredboy Date: Wed, 15 May 2024 04:44:26 +0700 Subject: [PATCH 11/16] Use my automultibind lib --- core/build.gradle | 4 +- .../multibinding/BindKeyboardInputHandler.kt | 4 +- .../multibinding/BindMouseInputHandler.kt | 4 +- .../multibinding/BindPlaceBlockAction.kt | 4 +- .../annotations/multibinding/BindRenderer.kt | 4 +- .../multibinding/BindUpdateBlockAction.kt | 4 +- .../multibinding/BindUseBlockAction.kt | 4 +- .../multibinding/BindUseItemAction.kt | 4 +- dagger-multibind-annotations/build.gradle | 7 -- .../GenerateMapMultibindingsModule.kt | 14 --- .../GenerateSetMultibindingsModule.kt | 11 -- dagger-multibind-ksp/build.gradle | 14 --- ...GenerateMapMultibindingsSymbolProcessor.kt | 103 ------------------ ...GenerateSetMultibindingsSymbolProcessor.kt | 86 --------------- .../ksp/processor/SymbolProcessorUtils.kt | 18 --- ...MapMultibindingsSymbolProcessorProvider.kt | 17 --- ...SetMultibindingsSymbolProcessorProvider.kt | 17 --- ...ols.ksp.processing.SymbolProcessorProvider | 2 - settings.gradle | 6 - 19 files changed, 16 insertions(+), 311 deletions(-) delete mode 100644 dagger-multibind-annotations/build.gradle delete mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateMapMultibindingsModule.kt delete mode 100644 dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateSetMultibindingsModule.kt delete mode 100644 dagger-multibind-ksp/build.gradle delete mode 100644 dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateMapMultibindingsSymbolProcessor.kt delete mode 100644 dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateSetMultibindingsSymbolProcessor.kt delete mode 100644 dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/SymbolProcessorUtils.kt delete mode 100644 dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateMapMultibindingsSymbolProcessorProvider.kt delete mode 100644 dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateSetMultibindingsSymbolProcessorProvider.kt delete mode 100644 dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider diff --git a/core/build.gradle b/core/build.gradle index 0cff94f..7aff468 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -13,8 +13,8 @@ java.sourceCompatibility = JavaVersion.VERSION_17 sourceSets.main.java.srcDirs = ["src/"] dependencies { - implementation project(':dagger-multibind-annotations') - ksp project(':dagger-multibind-ksp') + implementation "ru.fredboy:automultibind-annotations:1.0.0" + ksp "ru.fredboy:automultibind-ksp:1.0.0" api "com.badlogicgames.gdx:gdx:$gdxVersion" api "com.google.guava:guava:$guavaVersion-android" diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindKeyboardInputHandler.kt index 004012d..558dc96 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindKeyboardInputHandler.kt @@ -1,9 +1,9 @@ package ru.deadsoftware.cavedroid.misc.annotations.multibinding import ru.deadsoftware.cavedroid.game.input.IKeyboardInputHandler -import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule +import ru.fredboy.automultibind.annotations.BindsIntoSet -@GenerateSetMultibindingsModule( +@BindsIntoSet( interfaceClass = IKeyboardInputHandler::class, modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, moduleName = "KeyboardInputHandlersModule" diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindMouseInputHandler.kt index 02b934c..af9b608 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindMouseInputHandler.kt @@ -1,9 +1,9 @@ package ru.deadsoftware.cavedroid.misc.annotations.multibinding import ru.deadsoftware.cavedroid.game.input.IMouseInputHandler -import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule +import ru.fredboy.automultibind.annotations.BindsIntoSet -@GenerateSetMultibindingsModule( +@BindsIntoSet( interfaceClass = IMouseInputHandler::class, modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, moduleName = "MouseInputHandlersModule" diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindPlaceBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindPlaceBlockAction.kt index 779835f..89f2dd0 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindPlaceBlockAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindPlaceBlockAction.kt @@ -1,9 +1,9 @@ package ru.deadsoftware.cavedroid.misc.annotations.multibinding import ru.deadsoftware.cavedroid.game.actions.placeblock.IPlaceBlockAction -import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule +import ru.fredboy.automultibind.annotations.BindsIntoMapStringKey -@GenerateMapMultibindingsModule( +@BindsIntoMapStringKey( interfaceClass = IPlaceBlockAction::class, modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, moduleName = "PlaceBlockActionsModule" diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindRenderer.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindRenderer.kt index ae994ea..c1d96a9 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindRenderer.kt @@ -1,9 +1,9 @@ package ru.deadsoftware.cavedroid.misc.annotations.multibinding import ru.deadsoftware.cavedroid.game.render.IGameRenderer -import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule +import ru.fredboy.automultibind.annotations.BindsIntoSet -@GenerateSetMultibindingsModule( +@BindsIntoSet( interfaceClass = IGameRenderer::class, modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, moduleName = "RenderModule" diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUpdateBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUpdateBlockAction.kt index 8665ec1..310d69e 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUpdateBlockAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUpdateBlockAction.kt @@ -1,9 +1,9 @@ package ru.deadsoftware.cavedroid.misc.annotations.multibinding import ru.deadsoftware.cavedroid.game.actions.updateblock.IUpdateBlockAction -import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule +import ru.fredboy.automultibind.annotations.BindsIntoMapStringKey -@GenerateMapMultibindingsModule( +@BindsIntoMapStringKey( interfaceClass = IUpdateBlockAction::class, modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, moduleName = "UpdateBlockActionsModule" diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseBlockAction.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseBlockAction.kt index b34214d..46353ca 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseBlockAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseBlockAction.kt @@ -1,9 +1,9 @@ package ru.deadsoftware.cavedroid.misc.annotations.multibinding import ru.deadsoftware.cavedroid.game.actions.useblock.IUseBlockAction -import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule +import ru.fredboy.automultibind.annotations.BindsIntoMapStringKey -@GenerateMapMultibindingsModule( +@BindsIntoMapStringKey( interfaceClass = IUseBlockAction::class, modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, moduleName = "UseBlockActionsModule" diff --git a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseItemAction.kt b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseItemAction.kt index de2c74f..7f17bfc 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseItemAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/annotations/multibinding/BindUseItemAction.kt @@ -1,9 +1,9 @@ package ru.deadsoftware.cavedroid.misc.annotations.multibinding import ru.deadsoftware.cavedroid.game.actions.useitem.IUseItemAction -import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule +import ru.fredboy.automultibind.annotations.BindsIntoMapStringKey -@GenerateMapMultibindingsModule( +@BindsIntoMapStringKey( interfaceClass = IUseItemAction::class, modulePackage = MultibindingConfig.GENERATED_MODULES_PACKAGE, moduleName = "UseItemActionsModule" diff --git a/dagger-multibind-annotations/build.gradle b/dagger-multibind-annotations/build.gradle deleted file mode 100644 index 27133f0..0000000 --- a/dagger-multibind-annotations/build.gradle +++ /dev/null @@ -1,7 +0,0 @@ -plugins { - id 'kotlin' -} - -kotlin { - jvmToolchain(17) -} diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateMapMultibindingsModule.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateMapMultibindingsModule.kt deleted file mode 100644 index 7a5b023..0000000 --- a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateMapMultibindingsModule.kt +++ /dev/null @@ -1,14 +0,0 @@ -package ru.fredboy.cavedroid.ksp.annotations - -import kotlin.reflect.KClass - -/** - * Annotation annotated with this must include stringKey parameter for key selection in generated module - */ -@Target(AnnotationTarget.ANNOTATION_CLASS) -@Retention(AnnotationRetention.SOURCE) -annotation class GenerateMapMultibindingsModule( - val interfaceClass: KClass<*>, - val modulePackage: String, - val moduleName: String, -) diff --git a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateSetMultibindingsModule.kt b/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateSetMultibindingsModule.kt deleted file mode 100644 index 2fb4915..0000000 --- a/dagger-multibind-annotations/src/main/kotlin/ru.fredboy.cavedroid.ksp.annotations/GenerateSetMultibindingsModule.kt +++ /dev/null @@ -1,11 +0,0 @@ -package ru.fredboy.cavedroid.ksp.annotations - -import kotlin.reflect.KClass - -@Target(AnnotationTarget.ANNOTATION_CLASS) -@Retention(AnnotationRetention.SOURCE) -annotation class GenerateSetMultibindingsModule( - val interfaceClass: KClass<*>, - val modulePackage: String, - val moduleName: String, -) diff --git a/dagger-multibind-ksp/build.gradle b/dagger-multibind-ksp/build.gradle deleted file mode 100644 index e73405d..0000000 --- a/dagger-multibind-ksp/build.gradle +++ /dev/null @@ -1,14 +0,0 @@ -plugins { - id 'kotlin' - id 'com.google.devtools.ksp' version "$kspVersion" -} - -kotlin { - jvmToolchain(17) -} - -dependencies { - implementation project(':dagger-multibind-annotations') - implementation "com.squareup:kotlinpoet-ksp:$kotlinpoetKspVersion" - implementation "com.google.devtools.ksp:symbol-processing-api:$kspVersion" -} diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateMapMultibindingsSymbolProcessor.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateMapMultibindingsSymbolProcessor.kt deleted file mode 100644 index 860653f..0000000 --- a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateMapMultibindingsSymbolProcessor.kt +++ /dev/null @@ -1,103 +0,0 @@ -package ru.fredboy.cavedroid.ksp.processor - -import com.google.devtools.ksp.processing.* -import com.google.devtools.ksp.symbol.KSAnnotated -import com.google.devtools.ksp.symbol.KSClassDeclaration -import com.google.devtools.ksp.symbol.KSType -import com.squareup.kotlinpoet.* -import com.squareup.kotlinpoet.ksp.toClassName -import com.squareup.kotlinpoet.ksp.writeTo -import ru.fredboy.cavedroid.ksp.annotations.GenerateMapMultibindingsModule - -class GenerateMapMultibindingsSymbolProcessor( - private val codeGenerator: CodeGenerator, - private val logger: KSPLogger, -) : SymbolProcessor { - - private fun generateModule( - annotationName: String, - interfaceName: ClassName, - moduleName: ClassName, - classes: List - ): FileSpec? { - if (classes.isEmpty()) { - return null - } - - val bindings = classes.map { decl -> - val stringKey = decl.annotations.first { declAnn -> - declAnn.shortName.getShortName() == annotationName - }.arguments.firstOrNull { arg -> - arg.name!!.getShortName() == "stringKey" - }?.value as? String ?: run { - logger.error("@${annotationName} must include stringKey parameter for key selection in generated module") - throw IllegalArgumentException() - } - - val clazz = decl.toClassName() - - FunSpec.builder("bind${clazz.simpleName}") - .addAnnotation(ClassName("dagger", "Binds")) - .addAnnotation(ClassName("dagger.multibindings", "IntoMap")) - .addAnnotation( - AnnotationSpec.builder(ClassName("dagger.multibindings", "StringKey")) - .addMember("\"$stringKey\"") - .build() - ) - .addParameter(ParameterSpec("impl", clazz)) - .returns(interfaceName) - .addCode("return impl") - .build() - } - - val moduleObject = TypeSpec.objectBuilder(moduleName) - .addAnnotation(ClassName("dagger", "Module")) - .addAnnotation( - AnnotationSpec.builder(ClassName("javax.annotation.processing", "Generated")) - .addMember("value = [%S]", this::class.qualifiedName!!) - .build() - ) - .addFunctions(bindings) - .build() - - return FileSpec.builder(moduleName) - .addType(moduleObject) - .build() - - } - - private fun processAnnotation(resolver: Resolver, annotation: KSClassDeclaration) { - val args = annotation.annotations.first { - it.shortName.getShortName() == "GenerateMapMultibindingsModule" - }.arguments.takeIf { it.size == 3 } ?: run { - logger.error("GenerateMapMultibindingsModule should have 3 arguments") - throw IllegalArgumentException() - } - - val interfaceName = args.first { it.name?.getShortName() == "interfaceClass" }.value as KSType - val modulePackage = args.first { it.name?.getShortName() == "modulePackage" }.value as String - val moduleName = args.first { it.name?.getShortName() == "moduleName" }.value as String - - val moduleClassName = ClassName(modulePackage, moduleName) - val elements = resolver.getSymbolsWithAnnotation(annotation.qualifiedName!!.asString()) - .filterIsInstance() - .toList() - - logger.info("Found elements: ${elements.joinToString()}") - - generateModule( - annotationName = annotation.qualifiedName!!.getShortName(), - interfaceName = interfaceName.toClassName(), - moduleName = moduleClassName, - classes = elements - )?.writeTo(codeGenerator, Dependencies(true)) - } - - override fun process(resolver: Resolver): List { - val annotations = resolver.getAnnotatedClasses(GenerateMapMultibindingsModule::class.qualifiedName!!, logger) - logger.info("Found annotations: ${annotations.joinToString { it.qualifiedName!!.asString() }}") - annotations.forEach { processAnnotation(resolver, it) } - return emptyList() - } - -} \ No newline at end of file diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateSetMultibindingsSymbolProcessor.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateSetMultibindingsSymbolProcessor.kt deleted file mode 100644 index 6bcb60c..0000000 --- a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/GenerateSetMultibindingsSymbolProcessor.kt +++ /dev/null @@ -1,86 +0,0 @@ -package ru.fredboy.cavedroid.ksp.processor - -import com.google.devtools.ksp.processing.* -import com.google.devtools.ksp.symbol.KSAnnotated -import com.google.devtools.ksp.symbol.KSClassDeclaration -import com.google.devtools.ksp.symbol.KSType -import com.squareup.kotlinpoet.* -import com.squareup.kotlinpoet.ksp.toClassName -import com.squareup.kotlinpoet.ksp.writeTo -import ru.fredboy.cavedroid.ksp.annotations.GenerateSetMultibindingsModule - -class GenerateSetMultibindingsSymbolProcessor( - private val codeGenerator: CodeGenerator, - private val logger: KSPLogger, -) : SymbolProcessor { - - private fun generateModule( - interfaceName: ClassName, - moduleName: ClassName, - classes: List - ): FileSpec? { - if (classes.isEmpty()) { - return null - } - - val bindings = classes.map { clazz -> - FunSpec.builder("bind${clazz.simpleName}") - .addAnnotation(ClassName("dagger", "Binds")) - .addAnnotation(ClassName("dagger.multibindings", "IntoSet")) - .addParameter(ParameterSpec("impl", clazz)) - .returns(interfaceName) - .addCode("return impl") - .build() - } - - val moduleObject = TypeSpec.objectBuilder(moduleName) - .addAnnotation(ClassName("dagger", "Module")) - .addAnnotation( - AnnotationSpec.builder(ClassName("javax.annotation.processing", "Generated")) - .addMember("value = [%S]", this::class.qualifiedName!!) - .build() - ) - .addFunctions(bindings) - .build() - - return FileSpec.builder(moduleName) - .addType(moduleObject) - .build() - - } - - private fun processAnnotation(resolver: Resolver, annotation: KSClassDeclaration) { - val args = annotation.annotations.first { - it.shortName.getShortName() == "GenerateSetMultibindingsModule" - }.arguments.takeIf { it.size == 3 } ?: run { - logger.error("GenerateSetMultibindingsModule should have 3 arguments") - throw IllegalArgumentException() - } - - val interfaceName = args.first { it.name?.getShortName() == "interfaceClass" }.value as KSType - val modulePackage = args.first { it.name?.getShortName() == "modulePackage" }.value as String - val moduleName = args.first { it.name?.getShortName() == "moduleName" }.value as String - - val moduleClassName = ClassName(modulePackage, moduleName) - val elements = resolver.getSymbolsWithAnnotation(annotation.qualifiedName!!.asString()) - .filterIsInstance() - .map(KSClassDeclaration::toClassName) - .toList() - - logger.info("Found elements: ${elements.joinToString()}") - - generateModule( - interfaceName = interfaceName.toClassName(), - moduleName = moduleClassName, - classes = elements - )?.writeTo(codeGenerator, Dependencies(true)) - } - - override fun process(resolver: Resolver): List { - val annotations = resolver.getAnnotatedClasses(GenerateSetMultibindingsModule::class.qualifiedName!!, logger) - logger.info("Found annotations: ${annotations.joinToString { it.qualifiedName!!.asString() }}") - annotations.forEach { processAnnotation(resolver, it) } - return emptyList() - } - -} \ No newline at end of file diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/SymbolProcessorUtils.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/SymbolProcessorUtils.kt deleted file mode 100644 index 1ac8a6a..0000000 --- a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/processor/SymbolProcessorUtils.kt +++ /dev/null @@ -1,18 +0,0 @@ -package ru.fredboy.cavedroid.ksp.processor - -import com.google.devtools.ksp.processing.KSPLogger -import com.google.devtools.ksp.processing.Resolver -import com.google.devtools.ksp.symbol.KSClassDeclaration -import com.google.devtools.ksp.symbol.KSNode -import com.google.devtools.ksp.validate -import kotlin.reflect.KClass - -internal fun Resolver.getAnnotatedClasses( - annotation: String, - logger: KSPLogger, -): Sequence { - logger.info("Resolving annotation $annotation") - return getSymbolsWithAnnotation(annotation) - .filterIsInstance() - .filter(KSNode::validate) -} \ No newline at end of file diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateMapMultibindingsSymbolProcessorProvider.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateMapMultibindingsSymbolProcessorProvider.kt deleted file mode 100644 index 49ea948..0000000 --- a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateMapMultibindingsSymbolProcessorProvider.kt +++ /dev/null @@ -1,17 +0,0 @@ -package ru.fredboy.cavedroid.ksp.provider - -import com.google.devtools.ksp.processing.SymbolProcessor -import com.google.devtools.ksp.processing.SymbolProcessorEnvironment -import com.google.devtools.ksp.processing.SymbolProcessorProvider -import ru.fredboy.cavedroid.ksp.processor.GenerateMapMultibindingsSymbolProcessor - -internal class GenerateMapMultibindingsSymbolProcessorProvider : SymbolProcessorProvider { - - override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { - return GenerateMapMultibindingsSymbolProcessor( - codeGenerator = environment.codeGenerator, - logger = environment.logger, - ) - } - -} \ No newline at end of file diff --git a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateSetMultibindingsSymbolProcessorProvider.kt b/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateSetMultibindingsSymbolProcessorProvider.kt deleted file mode 100644 index c8f4e15..0000000 --- a/dagger-multibind-ksp/src/main/kotlin/ru/fredboy/cavedroid/ksp/provider/GenerateSetMultibindingsSymbolProcessorProvider.kt +++ /dev/null @@ -1,17 +0,0 @@ -package ru.fredboy.cavedroid.ksp.provider - -import com.google.devtools.ksp.processing.SymbolProcessor -import com.google.devtools.ksp.processing.SymbolProcessorEnvironment -import com.google.devtools.ksp.processing.SymbolProcessorProvider -import ru.fredboy.cavedroid.ksp.processor.GenerateSetMultibindingsSymbolProcessor - -internal class GenerateSetMultibindingsSymbolProcessorProvider : SymbolProcessorProvider { - - override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor { - return GenerateSetMultibindingsSymbolProcessor( - codeGenerator = environment.codeGenerator, - logger = environment.logger, - ) - } - -} \ No newline at end of file diff --git a/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider b/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider deleted file mode 100644 index b646e9d..0000000 --- a/dagger-multibind-ksp/src/main/resources/META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider +++ /dev/null @@ -1,2 +0,0 @@ -ru.fredboy.cavedroid.ksp.provider.GenerateSetMultibindingsSymbolProcessorProvider -ru.fredboy.cavedroid.ksp.provider.GenerateMapMultibindingsSymbolProcessorProvider diff --git a/settings.gradle b/settings.gradle index c441146..99367df 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,8 +1,2 @@ -plugins { - id 'org.gradle.toolchains.foojay-resolver-convention' version '0.5.0' -} - include 'desktop', 'android', 'core' -include 'dagger-multibind-annotations' -include 'dagger-multibind-ksp' -- 2.29.2 From 03d8db289aabe9b91e04505ccebcde96ada79be4 Mon Sep 17 00:00:00 2001 From: fredboy Date: Wed, 15 May 2024 04:46:01 +0700 Subject: [PATCH 12/16] Update README --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index d7246af..bf5e371 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Written in Java using libGDX framework.
You can download apk and jar from here:
## Build instructions +You need to publish [my ksp processor](https://github.com/fredboy/automultibind) to mavenLocal repository first. ### Android To build for Android use
`./gradlew android:assemble`
-- 2.29.2 From e98430fb12bef3d624efb08cfccee4166b18b2e2 Mon Sep 17 00:00:00 2001 From: fredboy Date: Wed, 15 May 2024 22:21:15 +0700 Subject: [PATCH 13/16] Update app icons --- android/assets/icons/icon128.png | Bin 6535 -> 6469 bytes android/assets/icons/icon256.png | Bin 9301 -> 10883 bytes android/assets/icons/icon512.png | Bin 0 -> 21978 bytes .../ic_launcher_foreground.xml | 106 ------------ .../debug/res/drawable-hdpi/ic_launcher.png | Bin 5200 -> 6607 bytes .../debug/res/drawable-mdpi/ic_launcher.png | Bin 3239 -> 3900 bytes .../debug/res/drawable-xhdpi/ic_launcher.png | Bin 4862 -> 7739 bytes .../debug/res/drawable-xxhdpi/ic_launcher.png | Bin 7367 -> 11176 bytes .../res/drawable-xxxhdpi/ic_launcher.png | Bin 7873 -> 12739 bytes .../res/drawable/ic_launcher_foreground.xml | 162 ++++++++++++++++++ android/ic_launcher-web.png | Bin 53480 -> 5498 bytes .../ic_launcher_background.xml | 127 -------------- .../ic_launcher_foreground.xml | 106 ------------ android/res/drawable-hdpi/ic_launcher.png | Bin 5392 -> 6519 bytes android/res/drawable-mdpi/ic_launcher.png | Bin 3384 -> 4026 bytes android/res/drawable-xhdpi/ic_launcher.png | Bin 4892 -> 7397 bytes android/res/drawable-xxhdpi/ic_launcher.png | Bin 7432 -> 11243 bytes android/res/drawable-xxxhdpi/ic_launcher.png | Bin 7871 -> 12261 bytes .../res/drawable/ic_launcher_background.xml | 54 ++++++ .../res/drawable/ic_launcher_foreground.xml | 126 ++++++++++++++ .../cavedroid/desktop/DesktopLauncher.java | 3 +- 21 files changed, 344 insertions(+), 340 deletions(-) create mode 100644 android/assets/icons/icon512.png delete mode 100644 android/debug/res/drawable-anydpi-v26/ic_launcher_foreground.xml create mode 100644 android/debug/res/drawable/ic_launcher_foreground.xml delete mode 100644 android/res/drawable-anydpi-v26/ic_launcher_background.xml delete mode 100644 android/res/drawable-anydpi-v26/ic_launcher_foreground.xml create mode 100644 android/res/drawable/ic_launcher_background.xml create mode 100644 android/res/drawable/ic_launcher_foreground.xml diff --git a/android/assets/icons/icon128.png b/android/assets/icons/icon128.png index 19e45326fa08578225d7d92a3ba04a13b4aec611..08d0b7401fa8cfbcb93b395b99127fd8353c2951 100644 GIT binary patch literal 6469 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 literal 6535 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 Pl>*B0Z{;dwOauQ99V|4= literal 9301 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 K;=_d-5C09x@Q?NY literal 0 HcmV?d00001 diff --git a/android/debug/res/drawable-anydpi-v26/ic_launcher_foreground.xml b/android/debug/res/drawable-anydpi-v26/ic_launcher_foreground.xml deleted file mode 100644 index 4535da3..0000000 --- a/android/debug/res/drawable-anydpi-v26/ic_launcher_foreground.xml +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/debug/res/drawable-hdpi/ic_launcher.png b/android/debug/res/drawable-hdpi/ic_launcher.png index 9c5bde7a6ec143bdd8458d732e362630fa2eaa18..595b5c6516bba7f95193cccf8ca615756058bf2a 100644 GIT binary patch literal 6607 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 Yj`0x;{ZYUObP7pyH1yP~)NIiI1K5`7(f|Me diff --git a/android/debug/res/drawable-mdpi/ic_launcher.png b/android/debug/res/drawable-mdpi/ic_launcher.png index 7e8a490da5483a2c6b5b6b8a2f4d9b17110b5043..76e15c3bd61b854e4f0827ef368fe47739a3b9f7 100644 GIT binary patch literal 3900 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 KMNUMnLSTZ-dm{A! delta 3236 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 WM{%1ZM!*mN00007>q%;x&f^Lm=o1B@54(%Rl{ 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 literal 4862 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 VW3^sl%zG`6nTfS=y%8b)e*hLL_Vxe( diff --git a/android/debug/res/drawable-xxhdpi/ic_launcher.png b/android/debug/res/drawable-xxhdpi/ic_launcher.png index ca5ae82ab948b9b8ae0bf88f74cdc04ceefac486..94f1374abf9f9b3010977924b693b18e295f5ebf 100644 GIT binary patch literal 11176 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 NEUzI~C1dgF{{X6z=NbS2 literal 7367 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 diff --git a/android/debug/res/drawable/ic_launcher_foreground.xml b/android/debug/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..c963cce --- /dev/null +++ b/android/debug/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/ic_launcher-web.png b/android/ic_launcher-web.png index f6a837e7495b0b09b20084b62ccce3af13546625..9d5fc15cdfa1fbbd7b48aff3c039d25ddb73bfa2 100644 GIT binary patch literal 5498 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 T0Tt3W1-5+=vxT$iz_)(|{sz#1 literal 53480 zcmX_ocR1DW|Ns4RILNV593xI7Dzastqm)WT+n&kZQZmjIT;xl z$&6#iu{nq1{9fGUVPPvIhXbeeSHm6#!U}Z&?5b8u_wz zuZIo*4xBU4zjn|1U!BE2qSdv^r?s#77&S%Tx!>_dO zrj$$*H<_oI8Nn;($_qY=$z*;`dLq%&dGoZ-Cn>Vu=I~voyGNYr9Z#Tx@3Drs+WW4A z(0^rK>Z9)9b>^`qycU$2j*!LTg&>M&S*Ff%qkuU7yA<6y`hfk&!6!o}@tZ?_@v`Tm zX=g+~=Rm;Y)I9I5iT>K?;|JTy(g0_ucda?}p*1T33sb$1wPL7J$L$*A zV=diSfE$mP2P1vO|G-yJZpq6JWcA%^&NiWdE7?gtDQUC3wSgUqzu+Af#&?}Xj-b2(5ExHljr-Q^AD8&i?st&Jkz-SynwLZ zXp)n;P?U3y^)r*RN1 z{wZ*vI#+hy{RH>ei&+5$r&SW1v7))+9!9D`xfq|3OrDN`mf95S+~e{p*in3O%pah~ z3B=Wo6opJzE=1nkkAlU#M-~cMfvJa&=j2!+H|O|uEc3>$^NRDn%)IAASe|&jn!teX;GQb> zd65!x!xqE|qD($8C*w!994~@WC%lHP*!2u4r9(HH08TLeuKqm$S1k(aX_sK^Xl@Dl z(rnGMKfeKIkble4H6%zi8f{kMgaLYV`980U0N%VMR}&sTDD}%Dc{%~vGRdmFAVDhM z>E!*^Dbrgc>N=Ap`WY%{lFIA*1L^Cf$i&TUoiHR}ROvG=WhcD53*Y*RSQ?bD@B3xh znn6=eQ2J-c)!xk4Iaz@25$$W(86OE%3vz99+&_I}Km|>(HY0~!{&c+R7Kp11y%ac( zh2^J2UzL25hs9d6Q#yX503VxK{bDzp+hzKV?TWQG9!nx)rIhz?C88eiOb-g95=xdu z=IwaVV=<6vbM0XuJJ7u9l+B&xOL0A7{B!sB`HWL4pc@_Pfg#9xMTZ&8yZ=39Fn9(! zbuL76^gb4Fn^4NFwqNF$sgmi>u<)NxiF4YcECtgnOK}4pYc)as<>8?`{HTP7ovySq zIv8MoS-kzL?gJh1#(6W`$cG^)5ZR0h)Bf=!EPVe;k($p0@jK{20qK~|8xtN2krhAp z_lyl#WSmk0;+e#vu%i%o9R4fGck_5!4lN=c_y5;pVfwHyPAn1n{dMJJ-|^S@T=Aj{ z7lmNy)~>#eBOUvjf$39j#xM#bu$djhLz2WOoeFSGc3Q2)?>oS$#422MsNJ*$Ke6x~ z9XA$OH`TIz{Ac1Z;`JU!viZMX2c?24FoYs#1pu#?hGmCj*(7!c2lLY=_jsoNZW5WMZR%oS@6Ze-fSipR$3N!0lBm;(v;}-m-t_iO zLLddxPr2%PPTuVPxLi*i<%b=p{G({1>q;LoDyh3bj<{=pw&iN&61FfPp4Bx^l^2HH z{zw?Dr>!!?>C0&S={2M6?`CtDa6M3H&}p9+INqd8{9P8h6mjC8NH*nvOHg#~%SF>iEF%+I z_B`Vr*)kXL)_dHIxX_TdAgcFDrW$4NA;dBLtpYg{BK>J#Y)E4LvgYg1fOx3-FtC;X z z7(Ra6Nx%0UB)7wY^Hs=5?pH;IyZvZ{7Oj6u?NngB{*)kh7&*~wc4qeSGFPI4;%(2n3?*{^)OK=BF{EfafLpO%W!A1pw^(#eu3h(t96qpwJg zsh~l>ma@cV3^X%24*_<*W$VggHR0jr0>Ct_6T>n;DA*uzJwtwaq9_iUks%4yFR=xn zmgq6&^thQv@z{$4*U0b+I_jkceT)-D}=b{m-)UgTr5zx z%GP(Tq)+qBYmt?qyQ3ikl6}tj&&x5q@zvt^tuMT3^9ni|DxZo%SB9qbssf&QhZw%V zi+~~f`hOxQ6V#U!^HN=)A)=godx?LIt>pL;i6CFx?UO?30|f363;G^plXS}G6lft_ zfhR#}c)ih@enZhgulIqmYagF8Pf5`E%9#h(16$V?B9G&!n>T3kQzg=;wzN;!`1UvC zTNV8)Mz-vcQ<&MEa}917k|2lNO;3up2ZS5-vO)_}|0q9G1ZtFCEG)9#-*b~IPzOVZ z-f)}CXT_B#pL(x-3vB$RRw7+VgXpP>!W{|DNYLacsw`1^4*hocBCc+V7DuB6ZoZ9!+IR(Zm2Vg!oi1h4wgP*z&%xaeF&S6O6tNkjO)wJ#sW_lpSWz$s{ zuwH(CbX;8#h>acX9TXh(&WE%@FX$*lo`uGW? z3W+Ds6KLT*0x8RiK>p8W%lwge^5EBJ6N$?)5ElAvJpm)5=i7`ayHP32!KYj5W?EPw z&on!%fHE;!KC7F--FUJx=)#g)0-hD9O`iT{#$7JylbXG*D`GUja z5o7ci7DKp~MXlS720(fCd`nMhY2gMx8po=5BgBwi7ZD%Ov0H9X@7EC5226&jE^ob8 zvm$iFk;2kkQP?3>+^m8g`>9-1>D%;Z6>A5~e^TE8;K=G599<;$TS^6xBO=Xri`J$g z4nvWZX02UM9N$2HZHFD5*V0jZm zSO^q>z#8EVdrZLCJ^7wLn>+I1*%bD#%>xG z{K+qJ0DOd~xsZ5Yq?5f{m!d!gO7VWvzq0K?92roK3NjWe6+wZXYsx8g_v9}HM{b%5 zC9&h0KM*F@>A=GLsPshm#`Bc-`%wvlp+D|Q(_J;=#Lsvdp1(Hz&h)m*Ecv;`s1LbIUYN3-X2rC;yh`g zs9IqUTsJ=6up;ji_ulZ-MP?ij^`ctoBo6XzImQj9ZbKC|^JN>r z&Hu__3OaV^fMzFPUQFB&Bt%IkxMf$CyO)PcDFJ!GmsOWo^|P&M zG|qCY?_On(;g5ThEq5+rfNz$?MAdYKrDre#Xf+rIq|vy$yZ7s#+5?^GqI}(4cYYLX zy2f~9sIFn~ThI~d--Wx9qLtU1Ga4lHLwQl1C#@er&a5`^0H`P}xIGsRHJTrq&_9R;u*SS=Yj(M>hq=Q#*nWZ;Sh#tE(B66#ZUdhP4i? zs!Y&8lOB?dCWn8qoBGvH{-n7f`!MIm^<5yb-yZljKie)2z<_SNKlAN?vFnm6dMRVR z;kg@f{lmZd&E+Zq%{yX~qMrIkkJP#Q(Q~Un9xVEPv&Oba^oC_V1+Q5pcYklOjeA zUQcmRvZ+-zoh-tF`R(q}|0susxE%&4j~cCCZ1DOCdIYO;^)7w!LypFOtB6{xklh&K zbK8))nV&(uAIPMaFz?e?p$`>_vGfuZ+(Afe-}m90sOH-8BDbz zt7sE{9SeTi9~s70(s$q2&%Lj7eRp5m(4aiy(*FjUW!9Jx8tIsbg_qzqkNod<4P&5! zu96#f#Oy*XLOx$q0)}F|6hXqhdh>}{Mx7RFY`<;C3gZ#SL$H~g=OwBiBP&&EXj6Q7 z_rLoW$k5`dd5GX(==I*={^BPcMuVcOvMu>V(T zNfboj`JMLZt(A}@vv0NK8z?Wubt3rDA*?4dM(9fXjW??3ta3)mXw?gaipjcIB`_3t z)1t&VQgX z0Tj~Rb`f#FqWG%82!g~G$K>rm!fy7qQ+wb^VaZsflftAMt5ZL}@#1w3J@M)#a5eQ6 zt|F%(?qp7?pxfM=J649J32}|!?8M;wECcGMQ`f$qP_9(KFDf2`G zi31I^>Nix&HE0NL zIvHL42FS5Lg`O35O8vqS;!!pXG%9ntt`~+@_qrq zhzfMP%V)WYxWrE7o-3GlTd=D7;_%pNuBFc3IArza(U6%*PV1}xj(=+qJTj5_P-3OW zSJ>5hP~}*9^g~ypXsb^*cV0ETlyMI)iQC6LbT>ade)!6-;k%P8_v7VxAM|>2 zhYb65=o+a6ZT%z8z9P!r{bgz619=O7T`1bt_h~=%ay1mYXk$amthfC~d{W(Hk9=wa zeY?=5a)7Ef_3`HKVPQB80Da4S{PhzDs4wGsW}L&<$Oo1fVGS47TBSLP)92%vqAYOe zm*Lq(|5oBOb^0ORk{W#H-H;n&LMgMn3czo(v!x7l&wqY<&yU!*;T--SWZ#l#mmEyu zpIzTC4tM7ESI*nkTcq^wd_KXSbiJgCH-xDcJz|kr70e2f*i_B*DMX-J#5!Y^&e4Y3=ZlI>Yt!+$E-F*c48Z8Oby?^N88bZ%5}n=WzRSsNsL z6EoA5V=&G@phTGtnL+U8e0eRJ<9qkp@B=C!y$O$ExgF-WI@ra%NV*|Z`%(87JX`4q zHcFSozLm9p>wM@`~FGhVFG;Ig=1|9b;n=Gvo#J!byw*e`^Q2CP5rd(}y`;pMMDERe)PL z-buOn#VanB7%P?wJ;dzE2JzoRP|<}0PM=+t_xu#_KWWPGtscPFFm*59seBDJ?0 z&x`V&Z~$!!lGgYp3}JllS*v@e0X%Z#ygI8q8ux0z4nr8Jm7%*~fShpRx?S&O`gXQ3 zIH#{E_~6z#gpa!<;}=)+x!$pZb3OR+RrYH9p*j4MjbYqeX2ikgjR40*{(v(QO4taA zYZ~24^P?ZFVKeE*FA5UQh15(`BU9Ev6HxmO9VME{uwe)yxhI;jh1*g;0mXnhe;{tU z-;^n+1cKV!{B^}dK-Q~-mV@9c3djXsdE~0y?uaHt(RnrR8p-x%RZT|gb=ZROsb3ra zRVrYXRga88^z?d5_#O*oz#;XYcGF7x8x1|~H&#R2&MgU60cXjlU2J@w&L14F#zQlM zq9}1hr|;PGz#`ZP3ivJ()vGVu#Ubris0zXF38*1c|7)_Y5-j9(k) zv0xTn#(5HA2Tq^IKKXa%fCQp14JWYMDfII-0@g41U`)IeN2d=L;d7jfsHMxeN}5of zJSyQI$K|DKi0pg-#m91<8aQeC)9kd@KGfKNH$Sj->8XF-@~Xh6$b~N}ah5l0w~6i3 zA(8RDtBN)Q7! z<&74d(1I&y9Da^i$tT!&PK682jC;MSKT3=ZVmf$ITpVirPX_{>l=>#tXUB8xKBpJw zJ;UuvHG}dQ8y9i7+vh13?!KQ$y^6+>cTQ~2)a>B8KB0>_OGH^Xza*{#3M=!663{=> zle*W|6H%o;C37b9mt3;5zKS3pqHFTNez10+Adm|TWEFIuw+HT-$qTAB!eC0U-i3eb z4J`hw1Sw_c*Qzd?0TyWZ$*0J8E75EzQ_xQak3ee`OLzBPl!>_ly-pa#cfI@~hUB{W zTnWt5xv;dq&AMJtO!omLbk?X)C4F!|a7SR_9(hM_USXyLL#UrLhIZ*x)sI4=>k6hE zstO7G*Tfu^lh^mg7$DGDhtDL!Ihrj3T#3$pcSJ_UIMxD4)A7PUN+1i1O3?3gQvz&V z%=sE<$ZH@y}#f0OzgS zdx6=3CmlCeDl>hkHrjtv0~W>uu92*j0FRpbG4o%~Umc?)BESaKzOcD7oQ(wzHHF9P zyH3hg3UD42LJLn-gQSIH8_tcK?Qg{Y`El8H+f2B@eM34dDAWBQi{0N@X-x^J1=rN* zS;s*IfgLt4SwpmKb}a6CB+Yu2?);i=aA(Oe?_s99DE?HOsbPb~I1n#Gjq*`FHfglx z&XgT+U5hu@sEUHd)`S|^_$a$VzN=NCj1tOz0#Y#o`;4O?4*4~=Cy;ZQ-uXW56_4ux zRz2HVZVyb%e1$=M=pa{yGPwKW?1+ukwGh{A?PG1S;+q{j_8P*lxLqvKg1$SY9^VFX z1t+l=Zd|pAyaiHt4vRcapIN|y%fR2l3i~9m9Bn2LwiydKzv3WY>H7gLQ~_6IkkUO% zwMLWFQ++tqoxq{|dO;mge;N6yhE3z(y)Q>uNQTWeA0pVsy!JC+U&j!B(qHA(BjkwP z`5xLFn_r~tVKH(4kst%FsDOQgSl)gcW%N}dfT5Z#ZB@*kNmxtfn4yq zqr6QZ>-eLz`l~j4SrO#b<1@s+FRA9oDy*iqJn_JD(Yi!3|6|BYoZ|U?Xh>3UJVigC zZwv>%{HLd?3B&2TE`h*zZgtM7!ws%0q&pCNyv7X(0F)+|*=pS)6a+H4e??D3|R=3?Rv5x!N${tyqVMx;d zXrbYE73@Isek)ddLtqbZ?QQLycmm1RFcsu}U+$?9!a0hdCu>AmP?iN$U_tSzy(>Q)fvY@895`bL9+~(y01g;n0i7-mjm_N& z`4;}-4i)c?Tt8sq?dJNThEW(Jb@JQQS!sgv09NvY^dMtGd;ge=U1pRO^oQY6*pKc$^ zIbByDB_dzgv`AK-$O5RWA0FS#`O)7xf!GUie1L*@3Z4BKAge$8Curna6R}}Nt1#be zpPFIGy38FgvfuB_yQph%i1BD!Dc9cCzzcBf*;)0N_hKy|>%dBis4%Q56Tsa%8fpPY zK_*(T>CW2@n>uod9$ngyAzIHA))4l>nEuE4O;_JnHepfKE7%uxlfMArBEyKG;{d*1 zfc3@Uq#0)Tm8cGUK&HauT^k-}>D5u?MG7}q5F`{KUd?Wt_JCR=xYtqAy%LGkMeT@C zV_`7zdh*7;KMyQD?ZDSLu6Gx87X$X`)urUCb?~Dr>#rGH_2*9Ls|{~5Rn+t zMV7JjSXfe=eGdxOHnYJ!)9vKcm+V>hO5g0M^oP9ZtIdci13X5?WH*- zf_G$gb$ZDU^DuqCa+49lvQS4(74_=XplLdQbmamM>LDUchU8kXfJ;PE49UQbH&9m$ z5G+WSUuV-ajyr&)$ye9zVuMUo{x1vg*#X2=OZ-Dj-7AoVsL4<2e_X2K;`OBg?#A(W zKMR{r%bK>kUUeHP-vs1Uu#D8WG@h~b1qpsUlRtWnG8;54=m z*D-MJRWC$DRClfs23eCvEj|-`%HSJye4cpsjm3#QK+!(sWfM4*%DfQ~R=;a#g>mB> zn>k2sWps$T@6^T*YMLX*g!XK;C>lzTjXTY_s`zSpv>5<@mT>0J%kRCjR8osF_NYKw zFT0UHpe!?HT)cevB3Ak+qHG4UmY16G^C-IaRd<>o)$|5}b2EGT`cnY>RM!r?J~=qd zg1uSncS;fM;6qawJZVnk0Nv}gEDvgZ`g2kc7IoUVtSdz8IY4bE?Hz7?uUggBs! z2om@T4#~)da^YmQ6zbRr@>^RsQ0$5=SWx$ESsrBAA>AiZ!g|>(f{m)XnT3lYG$BXb&7ES3W1*SGtj2@1Z^k{n3E>Xs4UCGi%^9TE zrA}ettu6`DX2*cS+LfPTYcl0m8-Zd8(`=LJl-P;|x-$oF7gi#UfududRtux<+)>+0 zP!jAFGA}`C$p~(~ymWu^`Qiw1v9z94l(?nA>-q)8YxjccMcw5LyiI>* zT3|(?hf93mPH%&yiISc3$#{0tc{l4-#$`#ZrH`&nX-c5r(Lq37&W=B;5;DA}u3rKL z-+R)sx!CWflIZx;obu(oqwK?=dRajBO-%5nBM@8!*{Q{sTHDoY8|XP!#Tgn)T{Kn((>jwVDx1aML=UKi2$;Twa$kGozj z5qNtTm2ezf6Q__WF2;#*Nuoi9d}~JF<+gC|FhrKzDBW?IMJxgP<*Ezv?rxR}Uw+sK zfI}Y*AG_>1u?PX@U-);)+V)!=2d%6=dD;S28!>ig-S|K=<=@+>*B?^vdJ<=Z;dQ2) zVRcE7_ldrZJfscpj`Y$_vVuGBs@!HF*uAD*&u@w`H}G7IAyj6o8G}eFjpLc}r3azr zbR(_O>W8B_vcZPlpaaBQRc{{8FJlR<)WgKizzJvFFhEh1~LRG4$9sgrcbXwL$Uk&QTBM z7g-9R2zhwAJj(4tJRgdr4F3AZJN5V{FR=}+5^n=%zJ+VLqQ4ID`_V{`_(^ec4lG(E-FD#D@m76c3&7YiI;<3Zrp#ca2s4@}HH>t?sr5L#Y52 zxVkPyRrK-qO`XKYpTq#gRy-?wWvaB%sbx{@`C_C^H5$6F{yhDIEUI)vAtY}Fk#f{* zGNCN5zcZB|T+Y4Rl5hg9Cd~TY$;`jE?>^0s=);1bh7XfJgn4727odCmN*eZ$>=~!~ z^JGDlqh&#en+L#fX9c%jUkS0LYq<*x{7yPKQE4kV6Tnbm2-3sc|le3&*{|; zHG)4H7KO|VE$#Oj<=}U|Qp=vGG8i$C^Ia|gaoA&EfUTJKeZ$r+*TEh-&97u07i;&H z47P6Eq$!VKlQhw`TJ|pcZgmtJZ0ks%b^ z^nopS7tu`aQ^h~7-ITe!LsN;c00OVm{fFa4Y&L}@VGK1?y7wW zBD(iAzrhfcVTL?x*v+QKkONuFce$2i< zQ{>R9JP2eaS*$6Fb$O$=UZ+Fks9hVj>h&rRy3mhc%Yvqsixss4qU=z&%i|US$s3O0 z%DsX1K;ub~^|b~MbMHUoUv&C@30Cr~ipP<}=2uZ}gE+#an-vb=d~?p^reO<8ar3GZ z@Q>)K<5KDkR{~eW%WepR;T3He_766{mB7z4569Pq;cCN);NuXms+zQ5O+S3M0j05D8^r@as^l!kf*B-FCzzuuBAP;pz$(SPdlI1w}?ta(uyZiS$?llaRB!0>}%LQSh8w}l#?6D{9w{= zgk?!8;F@*p7gMzdxck(C-xy#mU00Y zM!+$6;1*5DfO=5y!_8^)K+l^y!ApW5lO1Qna!crV6!bzEcHBxppSybr4Q_)KnUfj> z{denMrq2ii^_GU$9hugWWJgfkJ8f*(6$fzuj<4W_=)JZ_VquW!^mIEyksVmh0|KX? z^1Kd0E50tcQFd*PuBeO#ruAREBex|Okc^an0_Nj=`>xkk@YxkLnPf|f5D&Cx= z3kvLhq{Omr+_}Vb9bqZxs^lH2j{e zgaVY^e0mJha46ZEyZyC?H2axo)I5@x`J~37=qD%`x^bOZ$PV@i1Tneooo|O`V?f`< zo*F?=sH5L7RN5~T3j&_0+Q!vWa@-M*N$<=s5|wQzHfhztxgci#u?$CG83X_O(pkLT z=9`Tn7-bUMKzY^9H-@?+V9|)!+Ue!)B&u8m-)LJ-rIri@>b_g zb5Xu@=8M)SsP|Q!#t;yykxIQSX~T=MH9q^%2G&iMK$!$EywH5p^6(QtN>dj5Dh`2) z$4Xqn%gemUzt)vQ6fx?siq7CT~_A2DIfe=Q5R@S%S>`5KMnu;>0-G0}NxEAaUE(a%0 zd40_pX!e@i%?|_=3*ho}YOYuirC6EUJVgO;H9Hb@=x+u+evs*E4G$`-+}`Ap<@R2b z?YiU6fwAh7drsyd0vbJ^VJ-|lH)rpnF^g{wd-9-c-Q1XayPA5eFvS z^|?`4&?vL`1I(;8my@6O3-mK8A3;le#|uJ|i3r7p9tU|V1LTOX;yTamV}s1=W%Iwp zQZ~dPIQ^)KLOOfTdRJE2qb}$pBMhi~Gow$D3v*EE`f&;i91m|I(OGXMi3XW? zZrvS(gt(hYk~M<-7?Jb~a-WR)8RY0)>kX0PWoM@!>Ym^wRCdPkx~+AvD2jlBfqD)w zLNk=C$ama*X+{4ODc{b(H~dv%-u%RtfCBE(I>T0CzYZQr6Cd;yhnFYTqE*p^6tb!t zJj65=2Rdj{KK`rXt3WXK9h7c5$MTPRL9jLdLw*zL`X%3X3{ZIU)YrssbKnQwkFVSd z%FV-z0r0*!-ID3^%7r(+5p?eQv1jGwNHOY#P^BV#e^n-GZ;v4I#jL^z`-O*k!i2-m zZeP1?58g1Rk!4Zp)YMyvxt(I1V5J%hk-e0hm|DVcgc4$UAl2cqG+70O09$uX&Zy_g zz;Tl<{asRj?de$uNu0poyUnM0R6i`dGx$iy>V%AMce5aV8N##2S`hCl-n!34GKG(Sopb^ajN1ZzMO(_{t$LXO7NG}g& zmJyH($&bR()^0w^{KT;q_44Oq2(bv^J&M=Daw&s7T%Z6M?BL=RQ91?s} zMyfU-s6nv7SzJm@-igJ{bjG1}6kJvKis~${g-Q_r-9tJxm>57hrHg)K`mZN4e#heD z&EiM96Z;a zKue}Od0x;pamflT3cNnDozEQsY@;`vw-2I7C7GXUn23J17r=!l*u!we)4eR4)4TcG zK0K(>HI<1GA`&}5C>>L0#;H(0)M{D<%L*~g(?Lq0)j6>r@Mi|5hy>6%qU>Z52b1gW9y<5B z+nrZV;OqLn4xxU?^>`_gl|Z8YA!-6hRx*I!96-}9$6@Xlu5jC&IXc)+T5vOOFb+WH(7=Sa&wvNgtF7kGueAleBv6` z(OBfX{T_URANVSX_r!ow&kGWMX|$3Tkja_eeKL;^9nBCkp(J_e?^gn<$}OJ9%i=ep zAVh0%+zpR{uSsaBIxtjlpV(}J<8&4uiti{P76sP6%ffJ8X^|HB?fd0qcfPUO(&59= zi~A{|9!P~2%bIZ@bgqro@O9f9wdX{cJXA__09#n)>rHR2rfnssHp3UtB&F|fG~zxb zyk4CAb7!~(;N%+}s~L^gTl403;-QPFIab`~!WD)OA`)-#3+w2}lz0d5FK9c(Sb`ZM zwl5AM1b3fPd>k!mDPw@FmB3`?k;AIPx_V?Yo~O`b^Nrscer>1twn??eXMX(eF~z#A z5=a<7w%@g@!Av6QaS=k#pLr_*@3jWazdmS^&Q@5s+mnY!Ps={&IX2Mwq?10bRmNgwpUl_# zKLE${PICFK;VAvp!0>xJ$mvAJvR$=TTV?|dUvKgD$BCTw?h9e;q1%ahAwi+WGC!3^ z^N7aW-22hP4t>9b@GGWbk1jlMDiGey6`F3%q`kjWoZ{vD&(*XlvOLUbr=Qp??NxZ` zob9KBKB7HaOugNmn=GqdmhEcR%xF<*klLc(G_hQIjHEWG>z@t=Z%yLS8bLMOjcM!{ zV9UB=IC>Zb?~N9_M!Z}mveE3J<{?2-BR z>_Fwx*nJyig49cQ;6 zos*FSe69SM(X=k+F>5j5MQPqfer2eB_M+EG%(JAxf>2QuFyD9j9?huv8^S6-oVZKm zM2%7J{CW5ovX$E>vYuw?mF$hxa6ppcE*s7%2U`K@*vUZvp~t%KATz#J0NtG*ln*te zOd#q>S-7v?e4?6u6Q}p=eLy%dlUM!X@uT#aqYtb*P8^SLwgY6P-}b@PjMq*eWwv-i zq3Y~GAdJ5x+9?cNLd?AK#}0hK!k14~2*aTv{}x#^&|vAeXUb%J$FEQVmAEMyNhA zB!vjb&HH%kQ*ko1RFNjWjCed3;(XBr;tuOmNx6#sDBQUlh!`fvB$0}c2UmiHMAknc zVHBv;0eI8)j-#_U?9sMOT!}xbj^2~A-3>}Ic#X-Y2HF1iGU!6XK{O75*euobr%6Ya zla3yeLE9d1I`yS*zStW>5JgV`pxLicz z)H2=CWoT4ZNu-ismO3io^XM{$ppzMR28XBPS!eu1(lM|$M<;Q~&8ATwzLA!FNB`p0 zh`>c7&TU8Qd|57*a(_E1iXxiOTKk&?tabO_0=XlHQ;@e5VbIx&`;E$S!Zd2)Zojl~ zi!ACyilxa?!dUE{NwO0=)biE0c~A6cV;E8`ze8tU@8lJj(KMGkrI(s`@s*F$HM#$G zQRbLeh+KqK5~;#ZKdn2oM*W2-DvR21FLE3UGCtV!RRx93w;&H6J{5~T1k2E`Yfo}{ z-fV8xVF-FF6bGUEpmf7JZcbr+-N@GhLuh}PDeB0J$~v%=6X22AAdbqa%4&XcL69Yq znLOLx1Smr-KL36Voc5!<7DVFYFQ^j=g2|2GF}=5h4HLi2Q3ZVM5yGPyzAja!rVA9q zFdFv0J;b@3%*}@iAyXe)HY`4fBS9@sd@b8pR8z}9WDV_BGoWnk(u9M^NMiO51b?hA z#kK(3_TPdhbYWj%*nGwGf9~M3&uS>!Sr>b8QZw0s|2Hw({`rpb z7hx=_Xj}$Wb948hTk|dLG0eUeq>Ub@S=|EFtM78NX9u6rr@!A7bFje>j-!qlvu+EL z-aWogb3ME}Udx6!Et4w6Y{>g8)v|&qpBxev++R5DaG}s*?=lsk0_MAf+saz67m&8UsJFk(6e|nPcaTMyj`XmJya(JEZm#Q^A_qxJpHW`}W`# zzA(^l36mS#JmR>2GQhHoo|!5eo& zevR(yPiE-$Mr2CvEIq`3m+N#vh(-F@103Fa-WZlJi8~$&s*4iyn@?NS4>8;h6?8nI zSFH#*V_@fHAp=IFN<=h-K&ONtrfMQ0GU3?w2%sFAcxDk?$-fVW`0v5nQ{U-pMppe^3v z`qOyZ>D08P_!VW(&Zg>$|?K3z8I53YyB~s#29+pasbcW8J+L&A=oa zg8{>OLjpmCu%A9zaC!G>yi8^0vX9fkIECT8t)owA#)v)|BbBtBY2Jyz8+Rkb zC()R=-G6NQ@brd2GDH^6+|L(zJp4r$@?L=jjbm5r3=@OkJGTOf&BhNjI7;g}GB=1k zEUHLgau06Qo2&E;hT#5uo3&RMMA^>&hds)f|N>Y5?~|)2Ft^ zQRr0Kp=w9ubUso0v?-ytpU^+>kEL`idG+(#xW#U1fXmOG6+N_xAO35PCIz_kAX1CP zQwh}3n%(AOi6~YXaBuB|Rn3fit2I4DEXm)no;utx6ax`_E#j5H`wqOsUvmuPrLVi7 zIqwGN&0^i7bz{%-AdryS8nRm+kpL0CN3YYa20tEafDvpM-WNiD5Mr^TYIwXP-3$X4 z*ldsB*P}X+dWFQ8gP2Gt^wJ{nDP#-%stx+1$y~lk|E?7;ibAL(2Ml@sNC#OEYAmqg zEjP+m2|drFt^xu@tNm~J%IqEeO6~=kSm25?Dc}Th2O{S$`r64z0gamavzHqdy=*7yZt;K<7pmxCMpU;O~4ep*|)%?}h1hgypK zDlO0tjq85S6oef#oI>FTVe01hOc$Zb+zVY4dJ~|FUQd&WtOMR(Y?Sq z7348a--VWvgU>AzwOV9R2@UwUjaV_12@goAqt3+U-?nd=(GCn<|O2N@OB$;7R~s!BE*05-5IJM$qdyslY=bu zwSC;+?2>2M?RL&LLZ*PEY^_4L_9F z{;=e1XV-s5=y6$m{mydct=%)n!^(CAz%6Bv#|Op!D4XE}f?cv3U+ zj6VMQ&Fs7jg6w{W`^xQh8CD;+je`;@{&uW;#WKktM!u4~E^&s-cRgqoXhbwyl{b!W z(s!Nyo&-4ao&8isi4vmA5PsGXTR<{^(}$Rd8}cbravp`)?GXIp(sTL$%L04|X88c! zs+U$`gH{OY?4VI)>lX5mUG@U&qudp?cmDfo{1K4KFUzCIXOQ-!*Z8>>hVWZ&BqRkQ z;ZGR(g0N6Z4V$fn>YKCYAbE7wnPTGnC$JaQ>2=6(rxo!Ww*NYU*VIJLlwdxirP>j; zQn}3Z3-HPYKg-fgF!y0!j!J3A-z`~yQ{g`Ajg@+si=xA)d6Qanum4k*!Yau zvj)8r6YO3*U;6=&M^c5uzR{VIV@N`41TC%o(E^HpNzd z7UW+p)QUc~9zkPtP_~PzeK+>+6id8NLfN*u<@NQfeOY&nf(o+kwM*l!#~)((x)f~9 zzJ-MoR{XbiHQA2YuZv2gambe3z0+_KJg92o1D#$M?+6Oc;CXFOmaE{x{!?GVW+(7s zxP%q=WB|_D{0(ywHqip50XKh0JMpw#@gW2E#BKb)t`=}%K18F`2*7%h2Rk(&Qo`Md zZe4@~v6=sh<2&|So_d!Tl`t_;m5YE$L9Scfxbf9|0i6qM?j9q%U1ff&n;7^zwoM6@ zBYqjqwcEX8K&R`ijKy;bo^AV$QPcAItEi{%If*>ZbGvXp)R1Sb+me|Qd=v$cPz35* zN&h{pny;)i7?jRZm1thS8k|*-WdrjGW7k4ag1F;l*lj#4W z>CEGy{N6Wy9>Y+^Qe;a^rKs#XF-8-GCTGS8fIo^xOKb-nNRyZF9#&CZIFe?5?96owgBJx|5%WM*O8-S{0q z&n|wWDc!m|$EQkT+5oq1Rn(2d?cpcdXRLk<#v|$1aq@^Gj`VRzZ=U)9oWO$Bt?w)n zMiKV+v&uo^A*nC7zNB}V#qa=KKykN=$JYmN&&UA+#xoUc;XuitfT-4EYHsw?Qb(9x zc&7l?{pq8A+5+I8hPGkk!(tfvjS*&LsbDCyM~}v;+e85>5rT%bt0 z?eJ2lkz^`D5eVb$_?7g2S_P&hMHh2hk4GWRv-gHBrqsX)suM`RE$9!3bZM0%;ws z;vY&&A=u&6L6(h-BkWo}n&&SR!dqG9Gc3~OOXm}ND2NXF(uEqM{pme=FB$=JPfb3` z<}SVJYKwn5<#>z>bwAO5!tyXQ#ZRoi6#+|4(~4(v=d(P|WLA^q5tp4OSqQ7fN#spjvK)IL9kG~Hn7eJ?c zbF1?uo>Z%+B8k@@bN?0=5z*Hj*IuCY88YkMJ7G@mmawRVs&nPkAVyIWtJspzA|nTc zM#>!rslL|R$~a0-O(q7Nbp&&P@MSk+x^wy5V?h?qZl zz5P0ll8QrzSD>n-U24(@>Rp%Zf&9OmO+NHS(>JH6t@xUa34%4Jzh15H_Rj}BhC$f`!!NqZX`xHya{+T@h&3?;wfl+$?#2%B&slU1o zu&AQpoB#)?P5JRQuk-uU8o6fsVfX`P98(D6nE$ zM-UiTbu8+8jJ~n}5*QSJV2xg+1#8!s+P0K|$^|>%mG!IfPakv&i8znMzL{Fh-G8YW z^hZ<-P8vVee2f&`;^^ORG_%@wn-&d7R2}Z;dtIK{$-#hKPtoS&z4@PPAKu@@p{je< z>*3XxF_rl7?r%&@a5XmKG|eEIE{2jWK7xL%)EIpn+IRb}AX;o`Pxv+eHFLQ9Py^^+ z&tdPfHxyLW76ikepNPK+kY2gQ{(u!|ttx1h%#o|x6A~8o{VOY{ZKogN`IDe>&P87k z{QASy5qUANdb5jhuEhxr?qLk!n{~>=&00<(G}WP^Obke=Ff-Xr@U*{^#d5w3HBc^dS8kh zeI30vYYf$i&57%WUxyp|)vlTzY2mix{y42htI5@zd>cwrd0sDazGm%#=HhH0&HZC2 zj}~8;AakPqphv);EiK;p8oEfcwFmZq6m29}CjV#Fr-GBP-RRtv8PBk|#SHqv(b=lq zn5D*dC)sYDXBS-qL^}zS<8s$h5zwE*DB^Sr<9+4#P(^9RPf~+njy_1jgFhnKq4{KD6KixH)Uw`48eaVzwDEfMmJkFFk&bm1xOyWVmMDjnSTaN6-0d z2B*r$ZARVxuJvoXa+?l}2mrC*MBQWRJqo;!1;7}{AResx=Xhk{EZ#ze3EX5ImpJQA zcHa8QB1b3R)x+%JNs_aem&T%sC#TY!WEMmlb@kN^$0r0fr|jIAmiMm#@NSfqYz=Dv z$d^ckJVzu%18!+ZcHCtKpJRX8YY4QzER}<;L*(!N^My-xTd9bt`GZ?Tqq?WF4uU{` zqr~HM7`W2i{uRbNp*13VyR3py!wQ=3r>a!V7s5A$?ox027sYQJE|z>~(9 zxX>(&fxF~jtEg(nqR&t>+yFZ~qHD>UIuA!Tmx2S?(UT)d=_QvL5fkpl0wJSmr+Jn2nMn@x|zHHV8NVbwsU@6@`MmXYyHtxVIX)K-}e}33gjt90y zkH<9y%9527K(DH2&9DHL#06we^wfd4k8D{;4#3|y6z8{knG8cGdhDD5=LzwMEN6NW z)4yK{(|aeNaCZB1M@_*YsIWt6R%&YekiwPB)HMVjeT>1gPE|Kd3Yt9TI2|?N-w=~KJ*%4lB;AZRLB8^v0YZU&R-M6P3 zHNf`H`aCBLgMnu5J=*m!wDqK;rsu&B26Z7Y>`xn=%q*%|qs`laA|z(v0IN4ENYlFa ziVOAz8?@SdA9{MuZ5|x-lyyC<6KdGA?^xohyA6=l*4XB4hs{hbtsAw{xUBCRT3o?= znDjF7x!^;ws)sV{wcp`DCU)8_tZnr=ltzd3F7Es_;~-%1y`u7>`EJ`T2>L^A?E&l% z6>oOkpS-=nQVu>3_ey9%K7($kWWnuS=>q5vl6*#c)rv)rIoMg(aNqCa4e3>LUblUd zk4!kisF#NGqm#E+*Y{mdY~6y{lMc-o*pPno#)W))0H<3Nx8 z?Jos9Gu5L?6o2|4omO7ly;~&k^O7`#2;z_mreBE*Tl(#H7akn>j0M&7Im=C z(LHtt7v`q+^@UFFZ`%uJ_AB;Yx*_@`OKZ5((%bn_9f85y1)W{Z39BbON6 z?naPw0d{syA3KaZyPxnMXCYSkAwt=3eJWd*(2>2pVoeYko>f`c`o$+MBH4Fo$5_P{ z2+zn0>Mo!s9wCYRJ0AO)d_M(VEVY5|tKbU@G`h3O9O`)dMMFF(FJtuthlIgdQF z`8XR$*e9zB#FnGK%Kr3@Q5OXf6K!8pI@>&?B_mf0asY(eT`p#en?8hB5ZHU=Y2ng9a?kHa4-AFU?aI(19nW z;Yjm$w%-Ts+AGvCvgUN6i1uqO3@{a(?g>5LSm#KJ!jsAoheA9^+%}bK}bn66`D8vt+(!TV@43uY- z8Jq^7XXT<~O05)v9diLXek!s`vz)0VpsW(EfBJq;?4b&S#<-qF-souBr%;8SJn|xb2zd zbB5@jgZZprQ!3!tHAdwKlp&N#MBg7Ch}YV%Itj0x2}&i_Y^-eMHW&GeVc&*By>(-& zP7c&hrd6In4_K=c>s>e0lIY#OjMke^MK;)TE(u^piZ`8eF1W90-DW4Q+wfEAxra0N zr(%w7>N9VG%twFpMU}9h73|IxkN)8s0xCkoYW>mfxUUz_5)Dr#i-aY=`3r}N#tu6O{*1q16^1Go{l4UAA zY}W?%VJP5*fQg#`20V_==QD=EXDDGEf@ZuMHNS&*_SR8-MVf%qELU23^WA^Y50b0D zz=%cgLJ?4j#ANpT$sHcPiADb@|5!}WTJ_4FRE0);S5NI4Ox$$xL-!{G59Gi;Kl%kN zX-jcvR^whbzUQbHJ1GlXPvjhFah>Vpj23_+4&BMRDDVUb&;9f+gjhe_1wi@u@AKbXYd@<1NbB ziMQm#16KjcYZATcDH0)q_hJ|USpYh)H_cy+qMe9Pqbqf`X_l__Tmgv}cF&7D2s+Ci zyd$jLtG?HCKoC7cO|xRRXteXz^jLZ2i=cA&h>l?%Oy`%$jt1~^aGQK$9UTOPGv zH+APk_-LXs0?Jsu2qXevS)8zTqtnrod=!ZqPT8tgLFxccy`;c+yxP6}fC)fag~->@ zs2}0uP}>#yH^LnfM+<+#+94+lt^M~uUOubF$C~e8140a^Jhz0T8bKn#D9e~d^qPHq zPC3}iV^H0wCSoFi;l|Uu4bgGXVx|5)Tn#!yBJZ$8{NoqW!;SY=&=ZoUZmO*O*D@eu zIhEi-8_ZswE*!W@Hz#xoa!k?g^D-^ zSYqClvFMdF-$qO$Kef>hxWXlimu50>q<)G^cdA~AzqLcR}n?E41ORhXs_}yg-deh$)f0Nx{tZAL$r^vr@JVSC}QwdK<`OhO6d$GdnotGK9bJpoMm z!hZNyHt=YO!~3jw4P6}UYZ!^b9ry;1v!&^>(Vq_{4Pzf@E^&;|$9`p-kTMV;HbeFf zW^#*(I|+SOz~04l>)k%gh;~Lcj`;fOfC8vwsZzoa*N-TG*N!JXTEw2y+R@sH{ehkj z$p3ZdM&R^nQ(v{&fGvoS6;3}^wNX=zRZTtF34QfP#?1PrDtm0f9Nm25-_2vn4j^$d zbjuLsl`Bk6?9EJGRue?i=+1_p{#mpfKM2k6as-j_vr_d}A@K_*iXpC+s-Aaj>~?Pg zq=?@vK>xuVKl*Wu$;lQ00g)Ey`lMQy86VNFzE{9d>j-iv_HjqzWPx^3L%QQbgp}F; zRu(K5jM#vpJn}cM5alQ1?phZq(JW1@Y8+mM7ag&WsNNsG6!mhe(4X5W>jztIvh<*}Ffc2)2qEP^JtkxNxz)J|XfWGj=c$ZC2AVon$wsM!GNVXT7| z9H#;kkr@A-!`=Cw#HPfbb--gI;+i!>cs<&TUZSoc2QnJmuUD?z@rM%HlB8yp5@qM) zK+NF+ACE!1-z^R-u4cK=xTA7mwtMLT_6I!}``1tK5NFKRG*a z{5pM>D!8r%kueidqYH|S>DFm}B2Qq@QYkHTdSm!S$REV%Kz)8yTO}&?C_gmDorLx z0GI`7$XLqze7r^@L~8E!$%0)uF#LF1-K%yy_h0- zJSB+f*8xPoPm`wBv0Ff*sfl>uj4vwibw?)#8XrFI_OhkN_zVK=!8Tjr8}wtr67qlp9u5Pd3W!U*g5#F?ELpuM&K!(A zJbF{~>N+Qv;d{C~bPQZ$|HO5;9Q2e+?B)vD&jGl9hv2|Wo%P>Ln52IE!1MUX3m*2H z0nHf7hsc1%6A1+#ggxAr%ZZMqW2c{$z_Z0!=2>PrF*Sh+6l@SQ$Fl9P=?jKzTzqrS zwXC-tozr1YU6mHPvD1VQak2pJNdLBct%K(pb314S2lKAO_)zc7 zJ+N@g=che^MazblocXVniAF*#T?)Lm`aKza)^1uG@<>Kk;qmHl*x92)>vLIS$_<#j zb!xX+j*eeg^D^q!Ue)d5Q8``0-n_1Led)F>8V}X=#WXu$%KrJ$qLxUJl5wM7UuGQA zdHy~@rs>5i1q2ucu`O>kCE>rb9EIn>cBIONmgN;c93_uUQ+Xl`pw^qA)>FQ|u8g6b zzr%(75A0bQzWv_FWqh{X_Pmm;SX!*gg;c*%6@79|GW}UO+ua`r`36-8J0(c^`OyS- zj~#>QPmJ2=y7Li9%R!_gAKwS_?v%UxdOgq5y1@H}DXF7B%2YCOAyaGl`b6v+kV!dM zTAb_u%_VUAMznj)=(*wb&xM7`Jl)iFT9(!yE$C(AD>ZJsVajT+F8CpwPqn;ycStaS zwlk^4_1yK!RJ$7!7z8yFQVjJ@srTu^eE+`0L>au)Y1^pL!vdx3QE?N7&_GkT)41Xb ztuo%J#Scfb#P>WESZ^Pv=Ee`*UQ98~8r}@+YaH8a7NB+*HO{Tp8eYX{ah|U25Nyg~ z^a@2k^D)87mA<2Il6`e{gh&8}Y5E+NUmu-O?K}(;B?+Vhy52%rzCk5>&$7mEouo17 z!=BOsSxr;)V6#p+&^dYXKD)$_%Dc~e1i(F;+gP+3Iap z$TTh9G`RGXDdpzXti@qA@P+5nt#)B+gKjqN5P+ukkJYHP5HvgAoq0Yi^Lr#X!JF$> zP&`+EsbxWmJQnYue?}*;Pn`9vA3*;-#4rK5`0y|v%G&Y`V&u}v! zHJi6^R0$_`Rb3eRV=TW1ivvebOSpLt0cb$T*m+EQI~-lJlK}O$xQ>cRf=I-w!g9;$ zb!R*u7G2-+Iive9gHw{QBIG8AL2oHawRnR^^%jyiiibzkV%5nH)%U-R#ia_(2!asA z{32^NGJeaS?Z8O=enHT&pZk5-pMWXv{YOK-|9t3mH<)P4DFwAUOIE0%bWA=VPJXHf z>B9-}ClTUnEPG916X*|uRbPL1)DbT%dYyP8M{o9YD@+fi|C6!ghh|05&`|qd9B+=p z5)_f?Y1d|lXe~2KTM1uC(Xa=9_dR6^*=MsY0Q~NG3j~&SQE|kTni+s$$6MLGR3H{M;PKk$#-mS<7Sj;Q9d7*a!H$5q1%tu9(gVkiS@{Y6e1uSO&=BN?iJnBGcOQF$N&jtt$&-DrOt2(RT|8%>@FAEj&5{fTa< zxC^%><4&&>SUl60@tL&p^>QXU4hVc_=)eY<>@RsM z
1R*oGnM>PebbmD_(7c+&)Hzu|4JiTMq7>!Sn?&zu*;wMm$mQtqav@M%BS0B;R- zgmz7eK1MtOtSojq!AM>dMHxp-au@YK($WM>SHIPO8(7L4wb=(@D_IZK@mONTWJiti z4b92&oTBZp@H$;tHvUYfAm|W{DUtE2bo}c8-Z#GL(z_>sh9AHQ%ty%9LOWgF7kiLr zzYi)Gr(Bpp^XHNUJ<&&h%yWVIjLI4P@QfeH;|6n1t{&|%*KhU_>i5q`C zt$gs30S?`0Ri99TOAGDhkh-fD5&cqfdp;W`QSVahuhYY7dl`eQNITj0sMu?T7oJkh zJ~((2@NYf)4hcHaD@%pplFiAaR;BuRQFsP0d2z~StsE@rZ36WxqZb(Rl&_J9!0i6X zgvBAPAA29e?tz0fM>rE`4*DSf%<|WwyLap2+d|J*)d9mrh5x;;tD}b>NyC`aX83~f zrF)SFb4-^sG2F>bjbrYHw|sLu(v<&8o-(z5f+#Zj+K^%kKo9qnnsP*@EpTZ9@S!8w zqs5gJ`KK>9?Pc{v*hE|$79q#Wa%V7ZET8+InTQt;DW4vx%uZrh1kK#P1j|ZTx=oT4cV(?T3g&q2OECs?rGCchlsJ^?ll% zybSvDrpE_80VSge;FaSJ?dl6Kv4BO=mJ%kFrYxb~K{`n1qfq&v1r{yex$)E+OAVpCQx}?ZMW6I?UE}o>gr5DMpAC5Ly*8&G#1xfGTB-AW3W`imgH5rGTm^8blf?CZ` zyFY1DYNQ*hN0O+HqEi$Qf%WxIBMV?UJGKd2z+LAj!CI+>Ok&O|7lIC%h0m>TIn*cy zeQ)bQ(cZ&sDa$n1w})-P@!#8e^~vsqUJwtxL5HV_R0h3H<1p?1>O=V3VeY22?$67g z%$*j}!R(}t8l4L8@3OApmP!4!f9{+kZT`;%(EPieX)D4@eDcC6h{rUAS$2AiD32L& z@qUqR*cr5Y5%M9_(u10^!5M{C*C zY#dhWLDqWa%5CnOJ7l^5`eDD4?MA>7tMxObA1?lP*?`A>0pLt=#HRP6GwWIGIUE=w zzi>Ga#8NH>5uFQI``31--Q&>Ow5(ylSN+Xp-bLwCZlvep&8Bu?qJ}I`tg@RI|?fxW0(du&4@R^MUCQ3K)roXwl?}iPEkFPYJV+( z(tl0}GvY+^IK3y5d|yx>P<|Z4_tjjr)*>8-C4OvWlq$cV|Dq~vmhY1eFK>Q~Bu*B> zE9`S2czXEq4Q3q66x#9qT=BrJ7YQU*s#to>?TsJYH`tWb`cle3^ z=E0cMO&Y6EU@uO+XgM!H>M3O=)>>-$Inv(EC;SF3B>%Z>quf7RdE36rRxQs+;HHBfCISvIK#^|yXayX^TVK(Di&gv zLUKVw$C^G!zpH#$8Z&@}Xwk34n?s@MUtFdm!@WUc=7*uQW+1s53$uiV9%j|T)BbYc zSa7K3nWJ}jR52#vGiff1_MjjH$t#x}d(i^Gd(wpP5Ii`Ff{QBL#dS5el5Mc)@rw8k zYdH@`EU7eVhPso0agN}7ly)*zFov!+GGUy#X1TF*U2ojhcU39`rGn zWfBJ5T+%QY1<_VvcT^W3Z!U)WHQsb6b&9bg09S-)f9hu(`rNFCu4#2^RO&z7Jlgx_ z)kfIOE3ZFGp*(jwjmQhprV&b;EV#s`XQj(O=J+(GP)Y)m+S z9(mVmGn&c}W>&qLa{Uy%-sh;tZ}jI5osM(cnJc^8C(P{hVc)F#aZRoE!}}9mKJ0>R zNx)3`41^tpR-gmg@BF8r=iN&C6@Vw}%+U5^roz@`%Cg^!q$F;V&FX2HADAaRV2&BM z;7E_v=O)pLHlHtn?{7w&_>vV7OEuaO01ft>$q{N7J}L713&6G0l(sn&rPo%ymXPKk zBHOXLrN_renFf0$$YZv8e7`m|xp<+Q_xLJX3_%T`Fy>-Rfz zF<@8^_fXt|o&B{T@87dl4}6Uo1+$PGL<$X!qpbz3 zzfThb=?fMk+#2T%c`PxCFJ#I#lXgRW{rZ|>i3qn?-rUE-q(_>|$1&;Nw(|aTxN3Um zT0I3#?^Qx4Q`WjU9hySc#D(SXr3%lQ4p9n^KmzAE2`h3NDFjjrO`=$q`{+@j8HP;T zY9q>B3>^lfBP}ok_k}bJ)_)-=TGZe&ukrX#6;*j~$`IjhF!rZT)!fj9qPCac%lPQ; z0{~vUPo`Sv)m2G98SYqy=360<*KwU+eFECbIjO>&%T+v45k-hGfN*Nst z7%iLB@LdlqnN8XC^cARM>O56L{h#SW)FChKU$h?<->~rtdh1LAmS)R$HwwHm7sbGU zuqJ4x>F76+5W~sA037k0zAto)N0(VgJCuVRScOEww%RCm|J^;SPiNHCp0QI-`lu1e z17T?h9y7xI;$_Wg9B|&hyd{H@sJ+!JF(T<-?%s8>m3jj+)euw=8YhU}hBoGLW&km+ zQPQB6sUu=W?^0J24umdcYAE^b@OE7i8&&`Yi%3`%Y@G02P{I+fo77DpZ=^yEG{RcG#`dmY0!w-!^W{e`$bqKuoaOx)fbIhFI|Q%&KXh=SQWFb`2(+R)6ufY7njnc%&b2p zv*kfdtxinre*sH~r+feLx$e>TGCh-Da#{~XLA$$0CV^g&96G{^rHlrts3~*@6|AIx>oF4g9_5s!uzqP@PkYC2`yRHLEsBnxk5hwx=}ot)Lvo;(evt7*PCyg% zuM9DgSn*cm2LUs=0dLaIl>b{?__R3mVX=n#)_u5`X7FG*t?FU1=e00O+N`;E^z*gS zG%w@oDc?SZxhl`RKxk=wuuO$@F59Cs;sGT8g z&8|Pa=u=y=GGS0%dIQkL^BI46fbE!g&d(RGQG*8^X|&@0>Md`UZ~i+h{)a@SWfoMn z%d}tNxHQ-Ne=7AvXn(!66Xw^?3(_w%wT4M#@vYMrik%iJCQ}`C9stw>Xdi; z%@`5^9z$xgR_@f34=83IaDb?~Nn^GbnmAx45#_KoVjvDcThQgyV$J#d&^Wb-%*x?) za##|#-4p&+*YqaUyx)H~y^cgU#E3`OuC@t@)L2w5QsWD;itflo?PqFNWN8|B;Q$(! z4j@YWkvN{#rBIjLz*nvr>Mf{bOcfHm;V1Ly$t{ zx^H(!GmK{$o2wLXd3#Kf{(R4ouBfTA~Rfcb5~ z>c$1k9zc}rl`E%}Rt52WYC5F1$14A}5NQ4po?8Q7Q3ptu8O05Y&ck&;tbFg^#D{9N zoIa8Gk4?gr;HK}{m1!f!@I>hc1hrqDY;aj}-xms<;kS~?_xE!cX^d>OMQUJ1$084@ z32>@KBb}0T;PI{R7A7*Sk@pD>SX=*zO!!;w^yQcESr~c8#os5k3h%!iDPa#b{WC)l zeW`#-_d7WB1|wrVh4qs$24Y=0Sx{U zmo7Y5{D;C*ZjW%NPf#>pfs@lAp6C;GNQeWo+go+LR4NY5T!poWev~RUT@w>i@WfbG z4p7;810Hv@0IRe~ztn7{!tj2-JXXqD>`H@|!||u1N(z zFfe)4!i5kCnDj)iNaL3(Yl{46Js=Ut4L5`Z28A)Q76y=b5$R(B#z(`X#zUWe0I1`&Jno!WfnoS^ptXix4V z?ALF%xo{}SYnit|Y4^X+=I8LzNW%uy^9>&vY*@-HF(XHn(-$2z6tv;RCUst)`u4mR zT00#H>oDcMAZHb+=k3?ju<2M3)94zcBF5G^vkyk+et6PFT%iW4_rBTHeDkXRK|n(nQ-_hA$I#nXF|Xk z7=n3BZ5q)2>(&CMoYmGamsOCD{v}u8lPa2Yh6Uk$I56QG@E`>Eyp1&Cf!7($+K&_N z{@HQ>F2BcAE-{kiJQYV75Xp!Rg$dR(ff7ZRqZsW+OA@s7s5cG>tP6njm)scA#)IO{ z-@EnoJj}891#>QLnEOkt;eZ9-=R>rBeQ@j)vl5m<{kN0SN6B{pj`s#3ctY=YC=S(C zW5s?txhMU@k`KWDQW&WUP>xL|ZSe%cHmf&bOb$!3^~>>{{5%n_O@sabrNymF#Kv(O zRYeT(0B$s}xpHk!s|GeA4x#LIw>k0tD29}8N8d0N701NnHpE-c?`8gIILuMF=iIq> zFl1WE{e|Ag&a`%5rv!H&hu-S?dxJ@Ib{&gc+<)}^8c*EFKRXuC&n~t8%EzC6VShpa zJA|xmY<=ep<6|Vd@-1!MX^PJORL!g{mN2MG#Peq;bYm8-TLNb;Lu?CgT`H=`#{K>9 z^>Z%@$2Lx2WRXrAEzVwF1uSXY#D@mKe=ov?i40}T7=CYo<5HXsM6wmMzuF}wF4ly;n>ZqlRJtc>O z(xB;%NzjCFq?U(cq}o)H$w~TEJs--Y|01j;)6RF7wEWKjpX(&H(;x5F(8C#vE6v1i zb%;+ES(?`WaeMMklDr%i*zm1bam`zTu}Ya=dXD;g{#g%qTm>=Zi;s(qCasgO1#qC% zY(SqS&;OzyYbEmF>RE-tR7>R27hAA)?%}S#|GxStAh-FhkmTeN$}Vs1!Vu2}e5bT^ zdo6Ww5*QJGq-_D({_^Nf@~#*y{kCa)&KNV&N0y==a`FFQ^~X)Mwk$Fg<--v56785# zGY`HCiXQji^q;QJa5xM0qV)#>CeYU2ymXph7F?AkD@bT3$@-I51yKzMqlRVS_3?j` z3bb#CagX=k&rV zXSGtD3DPc<$CP>pCTrc^E_wjcETVexIEg-B`C_2-=;}R&FC#SXw!QC(12V_hOoq9| zzm_&x5o_1X!Sd4)@3{!K)C*Gr7+E^y!V*cP$oA#-&O_6-51Nu}F(MH`&NInH{>#>k zx@ehGFG7&;m`v#xN@8O@&k$3)bANxtSt;P)gA-A{X?r%inQCLf0k@vRN{aO&7CgzI zLY~RMA^}Qi&!q|mS{}_Jl=p@QDt1`qvS{r#lqfmyy)ndMP+5N4d1h3iGofaDmRWSi zd2;u*CW;U_~iLiA9*hpquup~jgr4udn%OD(D4m!wc z#!}zas8u%r6|$1%RI?U!YkY1ontR?lZ^=yV`T``iH|nmbVo0ACZk`vtKhTeZ!Vtql z*b__AOyBwpG%lfowyzYRCv2;yX5mhkB%>l68b$Kg97Bx&w>{I^;K}C&+unLJ-`oRy zYnj%{;^QYF`mytv`~BCW5BUS!O4d zs>I@7MAPnu9K)DM2Qzzn)irJlm{@ML4;TTHV_d|A%NYP)o|?SqLs`AI=*zPoS_N25 zmxg>9Hd}PRDM7%8m{kW*&ZefaI;SE@NQB_3nlWe9q_8Q&Vt2p&&C3j;Ww_ZgtI+z!eu19m#Kg>4pTz(hU>z&wt-8g5m z6qZsRUGLNU&|yU$5VqR8uDWZD|XmYQUEQnN^`~SjsEGTh+{IceJ1!&xU?O znkMo)KweLVy`L(9`mV3_HZNv3Uof6TaWw6143}9-rww-2X)dFK!A14 zw~vQm20MC1?ygZ9;|nkpZ#x<8ijE8`ZSM$*bvpbx|8q_LckVdi z^n0V44mrRN?t0hBoKK2p3Xx;;Fi6w-&}9KALNSjvc1k44lu6@Hcvj?kic%2Md}8gW zy6`E#a98mw$LLD7tzz3FsK zM_kRlGvRM1m;o~=y`*G)2ZsKbm4+DAD)~YCuCHBfqueI6@m=J_;6DXr2aA?(UTSq; zdJM~`R%`W1#Ke#O_k>6H`mSxAeQ+4u4r|4vXth-R<7@T6LmKlpRV!}RdTFaf4*Ze* zIaYqX$FLdaam^vS)q(E=#yybwKH~86>!Ja4&MZ<|t$noOcFC#ZWrN-1{nzk;j&KZ@Fa6^#k#7=^ zW=1&ZQ!u)k0D;jJ^q&TJq_fqu4-mkNNVnq)@>bdExARyow>J(3-6 zbm8Dq8^L0LD`AaY8Cu6g6*p-Q`Tt^oLGoI%QFJ=g*!j8}N*xb#uUw#N@4kl6RK2<8MN_8Heli?_aHr*@Ar$Tkn3JuHA!(d zBw^5Dv-`CB=O8v9{9}^KY-hD$Tj_h6|4v9bxOh#~ep&BZPPstl602XF$|*ndk?!BCLuBzrFmAe&w@6;7;RI`Y#usUJJ&boB;L=wsoAtlLgu>_~ z-8tr>SGWz>Ns+73pKn=X)F*+u80iw9-xMaPW)~dAcKPdV*I#O#ze*$cN?EU}4l$X! zU0qkW!P@=D`SK0`d9{*{F0}()+6h?IxOrC4rP3_@v3L`4*>`Zi8Ksq&zJjNT#}zIBVwqW@a3Gv`@h|dqM|_LA3g@2M0gBY9LgvN5uF6m1b68 zi22X7#X9uDiY#~*P5$Aocj@;kgVQg=7>h&w zNrHSsZDd;VlGUI;bjFWWdWXkNyD*};?ogBN3XFxXdZWror|75TXE*A zZ?}xyQOdLqdG%vM8nv;>(-aVUFm9*bjWr!u>b`^E({X0%A zzhBD(Ood#ww^RD67Vag;e!n!5|XvUTkuKe^@qEvU6YtwHQHv-0WY16mx=mYyLjBLp!o(t=2QO*gy2V>8#_babQlrLjUtfm16V~ zl0X;VcHcHSLJJUGV5r?o9*%P!Y42d{bX)cgBl7v`cg`V-b$8!tb&Um2X8w5GM{vDEB`mmkM-@%3LE6FOosssMjy#?FU0CCA3&aDLdOlf%9Eq%cuH z0DL4I&Iv9}zTE0Jv=^9;4TvTZ0MWH)J#cdzj+oD?i7VDb(CiOoHKI&#*aH}NlW#Q- z4diIg&3eC`t()3IlXlr^C|%bLz@0*38Hh;z2kK{0JK0vHPiXh z676ge(0M937ICVBxx^29FtXdKs*xtq2wqw7=Ihm}Yl7giO-nxOH^P&phA5>Fh_;U)N&HLm3lR1^=@Rawy^oubfTtIREP(Z@dPx0bR?_a-`vI8I2CnFIU z8RA>la;=2FZ*?ESCXOLF7tb$#!k}Z&y@61|2#l#}>O?mO^mL2v#ZYn= z_zQlgw8J*L?d^q&)YLg)92SG}~vjKyIdkAdUYYy1< zkR`ZZI~ri|(<$40Xu$=snY5Npcmh*>hnR{cm*bBZfuiiPq_SI3t9x0WDeuCB3bW_O zAw?NGvBO`5JKd3SUE21=_nguo9?6?sO-mcjc2|gk3c=P30%PK8$lg)1%XDdu!8cSDd*?)e~IYB3auPxzlamvnq|l zt2AQD1m10hy)&K@!n3kn1w{q!1{wd&Lqqun{h0v6^uy*KW*}8MlUD+%Xy)8j>~+UQ znb0dwlrE*MSMBtoG@lm<2vPZR;b%>N-hp+=o1T@lCrb+xGPKGOHLBvJLqnoz5TDo; z2Z8kewVs^csKX|)0!@mwihh}CHAm-#ZyM7@F5onZ>4O^nKMyRWcpZnyhl59`20ZUm z;1tPvmjnVrbbG8md%^}dT}s8=rk6otShZHciSYr*g;pv1esb$G7Q;>5xd0=B0K@#X zeCM_Qqo0d*!8=OCcVWV5|4r9?PoUu_*H1i~9Ugd6Mgs9&_Ir8YrCjJ$Sxp+$W&^$r zK(YZ}6e^|d~t-u z)!e=Cr>`}!g+74>VDPK_=I6clEg`RBTIM+6hct*D6*qDyUMJzhB zYAl);9n5hJB5^y&3(u52?2?4Bq}Q5}6@p30Tkdz^mM1>mrhg_tdbmZI%E$g);J%23 z*dFfNY0BmMp?B|XFgd;)&X&+I>&6qWL=O^D-fr%)S?dGSfnP*r?{U#99&-az%dfCv znIJeGXG4J7@MRUrav>jxLFTqb-@|OOieADOT2M8#zJ5KobT0B^T?GpVVzGOHV&W`pJ{XeGOJRZs~ zZXZAQ3?ms!5+g)~l6{G+GukMHsH{aKl`N6$W}<~u6xqUP5h_b%-)3ZAvZctrui1BF zX1>Sgd7j_v_g7x8=6>JjKKFgjc`w)dx-RT0&jsEf7@a#^WX7Cu@`@wE{=V6bj=B~3 z;(yhfu&t7tq-!twg+8?ni~Vn0d7DR_Abb1wca12xnrDXdE4zZA4$RaBliug5bs%g) z%_n2_Rey~W>0;S>|H80Z6Q*$}1xxB9>|HUk8J|W-%Z}B!>o8(+f?Ohl-fd;|p(K+G z;pa#)uRHh=PdWspU)opKc7vSXt`{})2{M@ETyJG`_M5T3Z9?N7s8vgN?U*CW7%P5Y(78ZN(|?Dc+p&Oz3>S_us$+Ttr;c&8{d3Tt6}oh zY{+B&p(C&rI^rx$p9P{Gilvud=j^&Jvl@XYbO#5c3ee%AFL^Q46LAK=Bso#m2JWsZ zd(Klvw)ya&{_-xE2=O{unhX12dTl2kUs{}ViU+yNyAROgka;faj72GscIkUk!S&_I zt3_s|QxwlC!ic4B4@lEOf!;&gN~eD**`4)c9L(MNX(OI^Ad zFdr=1b17&K_;>K}6Zi%W@Q41EjzqGLxY75$q0%XvVpJRfYPRILUBwWxT30uI&Bs+*Glo6BLNca;wPN zz(u^5HfY`Uxjl4(%UVrh@@@bzq&QPq5ahlS#)xrESqYN(g#rUG$?fBi18US-O?2)% z?Y(w&gn~#+<}i+gi+J6u`gQEu94dCV*4-$kJFWav2tBbNA-04y*A?-uf_F8u_iWg9 znF5NOy2;2*HX!4W+yS(OzWtV@Uts}#Ph%HL48&fj`&Svv^;6p-H9RH@#HgqGb!%}p zXxjy$@<^x}*IE9t8J~OeeF?f6xBB}@2gum3$4QDfo2 zyQMsnAiw*5XQC*8!i7eeu6d&@1OXXs+Y+W+Yd>tR4|#-d3Y!dEvwQG`nJI!ExFW|6 zYO~iX{OB*kiG^zYw6@Skc#&sW-WKPWx&=ZUgg6*?#$-bld1t;N0pJtrX&{y{Dn|B)m}I`Xqv`YV)TsPA-4TvA0jKw$f;8z#@?lz*fk z@@P_1bDtQ230W+g#&_Yk_0+GjcJU!Q?1j4Q3GiIre#Q3dd-+ORp{CY@$poQ+SM@a8&?Ef$b}2u#ps{J6YVdkvV0vVK!bHnI#0ZV!c5kR7~KUj;;XKw_NO4dK;kT{8^W z;%C+>8bwv47{E5M!_55;g6TI<%EswAF;Kf~VPHIPpkLzp!ifk~QnhX4a2o`3STp-J z&cIY-{}Mm*i*cFFU753UsKb*KqrRMFc5wEn`D%bEhRT}(K>#{Z9H<1UDfc$oP)l zWglj_8HjXV9w+sS(nbU-O{9TP*fR4nQwcNBZL_+UP+xK&o>jX8H%m05@_rNkP> zhx<}0nNaTdE7SEG=`Z&^4l*TxN3YQIbkJs(%~p^jTh`Y3{5_3k$lJdC>0-q-IxBp) z$l)pG^RXuZ0Ua^51jmD~2PX?w^MKgc)zYKPoAz{u84OGGg2-2>xjL@Ivm<|pyLZD* z{bu=WU+$d@7T|Y|mirS1mRHa3CtX9p89vLd_$O|94)o4L+Spi^UvK#Frpau8!$FJX zXeMzlI8IBo`WFKWkZhkedlXC~|6a4IkKb0E7YDWmMFF7+j63oU7GW@kQ0FGVJSK?m zV|BA)91F;4r^uC4KaXZ*QycL}}o;)nQlpTe(GgAW>eWKM5jQ2j1$&Am@` z%>}`i{yz`OdhDk;Zl}*kmS4nx(4!<7<{rC~p>9P6Ya$5b(Dv@zIMp!64lI|Oi>t#g z!^b&&-CY(`9{0>y9UbxG$$UZB-iv}Hm>sH-_#{!Y zTsprk&^$r1Kdxc-#MvSbBJt0>C}Frj^^+GB?7&3=T1TpLm#bv6>H!OL{Ra%&A)SnU>ePqy?F z4u$$W->(km`ra4WcG`JCt%!>+=f`cuHL){u@B3lOUz_Jdz#Vp~@y6L%2`m1+Fd`9* zzd!cA^1wcXdi!N&K2LUIkcwBy=n}V_I(7zn(e5J;T#SvPf-8nZ?O0I#fqbwExn#C$ zXW^md>nfpG@qGXnHEpT0i8l*hjJ*7)A2EKkf8wm!kr9r2{&LvC?y(z*Sbe) zkdQWw@KriH;DR&B@zQd+kN9K<6Z(rCE%njz8f8|Nw%TAGwsOeYC2VKM|B6Hif}0u)&V8lZ~iiGp;PsKKF*RsG??g^x+ZYo4dsAPD;lc?ZlQSgkjA$?gz) zTz<&wlWwytfGP%c-!nL=Ng;MLxjy zJ9S@#_}8E9JZ#`N`sz>3hybFi^I-Age4xbS0P|vP)&|TS+ZlvMplYYak>5|)K=PuiVp6VZtRTo?_u;B7@^L`CjFM4_2uC8uM!d8nif^1PR5|(1 zY}XioU7_t$9l7nWtbhh!n)*Gk*@D{P#@SLF(t_4#PlajtSE(uC{jdJQb`o9EYPl=y zSML3k%AQ?RUzRxx6*_Qigs0g%8o)BWar1isgO6uK5>?L|zL5q6FRvfBX1Oe)HUmQ+ zVF03p2MYPewO$%n19dhRCvusYsJg4-9mT6w&MLcrE$@o=+{zPv^`V!Jf?z!m-}b|I zr0T+gJ@&XTq%-FEn1yee5q%+aAh8x??}imnPpH=ZLJgC=S|Wph+6S|}+_%@}CRP%+ z=ZpGnKBM12rj{4D<k$@{8Q{1jN=%l;(ZSUNnP}!=uKD(0dP&eYfN;LfJpzAv*4LPxnBe9rm7XG zf#7mMpj}TsU23}1*A_fgrpYRwJHuaMS$z!_eh)Xy>!q}Quz~VUs97};=_JI1ZQUh@|lN*SmlsW+VuHZ4g-vj!rJ-4q$7eM(P9)Sm! zYR)t1aHoXTDWd`&D8FIZ^k6!-(du>T<_rSd39b^&e}?e@91a#;@Khc@GPLv&OC3PD z(Y9W4-w4CchyFq@w0X)iq8&A9He*ZSG~(nw+K6d=#1cPo>vB-@xY5#K*e?FrXY#-I za3wWk(^GaO3D`P<0Sh22`P&(ip7p|Pcj2?DmxuMB3L)1!s-j(PeOPXF#;M0l^viSM-pcvw?**Q za?(oI#$bLcdQsF_9#T!bSj*-wASFkhO05LN-St>_km0Tr`6nxnB#O-9f>R@Y$S zVf^#<`q8KdIkWKNC!$EZ!5vkzd^bgJ&G#_9RIS-)UWh<@b&24ZDw zT7X$R41;&Mc#?^)c6L^Qb%?79Big#5cAiFoiP-4qB}nQb%T36hDw5q!=bQl4^DXgw z_nJOHm{2Y9_`q~&{pfNj^CLv*WLjJKcZAcnz1kpdE$wwW|Lhcm(6Yt2_=g8Fm@zKi z*qa-oW&9BxvtROA|3UhT#h4EqO{Vm8)JG-+IQfx@G6N~J7jyJ$P?SrNxv8oG2GmGE|ba6`^ZrcqPc1|K*p1JxDRl{ct|^ZjKw5>A#Mk}k1!K7AZ| zaG>A_T!BA6SAq6ur_Y;hIMO#i`t4a*WW{M%{{RX)M6s{rM$pMdF|tfTbaAA39pdJF z7?$P5dwFQWfIYW*conWL6!6CU$r%Vg{&#;U>8z6MkNV#9ft{c}fS!cDJ3CvWBiMsd z@T9UL^`ddRP#!!3SgpN1?k&6bkFp?{^rN}gjwDZy;ehGN^PP}XVxNHS!G)}{uHCRk zpZo_AFu83#OPgPVfU?HQQ%Lz`Y3UfG^K4oCjN1|oJvX}qSgwue1}C8t^S4aNM7}+4 zagYr{b>%QoE{51HXS-l}D4-s6>Ocvq<6TTejNPX}cen&DlG$vx)QA+yzoh?~R(Ktu zY`fNp>8WvhDS&^v|H10U%~6;^hnb$WhXqgyca48AduAN?LzvNif$Eo@mDQm-eaeQ;{bz(PLIS-|)9pbNK;`_h_vv-+B~+z(kUW6=nq^klSbRIT1l zmJjxUKd*rgp23Uhv?;xiU0D`%I&)r}Qw07G4lM^LR!7#B>$FmDf zayrH)-^eU{OIN-;U<>?~$4q~boq9EIUcsN_(Z~$6)Gv9B8 zN(GfPo6X9GcU!~!H?g)O&GL;pzK>5Ol$=xez>-8;*DGiXk9u#9ZR1b~(f$dd>iljE z=&=m$&$h%QFPC(!3P?Df_yZGN22yj02g$Kvr+=YtRe(l5d548)W#H~p zbIc45{3p1@kfHX@q#jcY%pl zxslP#&N~Un;o*bz{tO*4*rti87&JQMGY$d-b*0eBD-4T#G_Wm374JZOIP5;<WtS4VQv98VrhcJZ5yYC$fUDyH16ShfXFw|=xN3~tse7+|( z^v{$!05RV>Ru;y0w|Zj<^)9JcXjcO5>ck^VNOm_hYDC)_U*K{dQvyzu7^f9BkRAPDm=3`rwt|(XL%kqQ zjDO(pOErnq%gv*@q~+>n5htx35ms-8qii(NYcA4e?{D?8QFyGVyIaeNO~tBEo&Q)l)yD?L|%J*j<#hFy@JkMxPRob!H@9( zq$K*qw&6bcoT*l0=PdD2RuM3SVLxKVhpqM&dkSFJeR~pAu8I=FI=bES)YxH+k0A!0aCi7Tjt)nH2BDe( zAznW%f88EXMX&IdWeak3EsD~hv+Ybu=~sU48(y+L6qcB`Z#5MSgauf0fdDLZ)bD3qk6xmm=xnj*4D~Bz8Nzf)iLK3d>%(LjZo~3l*K-2~3^3Hl zUsVpBRffyFKdYZc?Gj7m5DO{S&t&s^YaVmV6Xwb0RH>z>a%KD zh!3;1Zd}RVTFtfb8*LufReAjGydWv$uoI3{#Yj?34rLv&diV9Q-LOs6!8eDjLX^Pl zy_n&5-C-}}4^lc6sn_qW`foh_rwmqIM~V&tU~bkI=n8E+fIGiWXRYl6;$<<*nE2I# zYVBqREa4AWXsNuK7T$4_&A1IVVTOGaCL33IY!6bhZat{vU`Q9o0KJhH>>@W;8OwG>?mRDHkX84PR04^ctzZQwOOfajh$ zAU#(Gc~h-rUIM@^@4NpwpUoa`*El_yTFrbs)!>9eQL?lwj-0p}@9$x>U=dD=XJv}y|``>BHHF%|QJ@fK$O8dl8dNKB}NbuXaC7Y3qV_tE9`GIbbH@FXg zI|9&;-i=P)Q#Gdy)K60{i~N}jfaMgO?@OZ^0}ZB4fzv9LuyNt|{x6C>tPzv=V)5hT zV_!=YF@*cYVw2+Brw5b)1EYP+#~N{v+%JwTiiQ*k{T%8d-@wLkdJGc-2s_zXk0(~Fyy4Q~w&N)3W7AOr6`c>!JpAFIf4EV1 zW|r1!00#H~8A>$(&jmq4Rj+TqNW^Bh8ADCl+plwMhbUh9w!cr3mLQt?uQ`AI7eCSe zeG(vWgpqgsrZhT5q#N6AM3QFwHMH06d5O%YTwhM0v&Zz5Up@7tF)QuQ#|bR za;Nw7oKx7s1E`yFDew&dtXS&FYgY#g{mZ5%qT20%_xm#nK<-fDt&r7?X5etE_5RUe zya6EmeD}PWxHqw2!&h`YRi_UDUdWLEM%0ed@q=idfvlUFD@&~CY^ZcWGQRdY3=MJQ zpnm#p!I%b!zy^g|GpESkQ~kG6n?{~m##RuGut3?1m{Bz+KVNE=C`Nc7ZugY;{c;Td zc)Gw7r-|x-KE~q&tG7Aze-uG{G;yzO31gV(8AKOP6`n9V%72j^18?*vVdX3UI}oa` zfyc9?v%z4vZGT=u;JDS^gbGh;1-J7cE%eCZJ}Ax z)t@{Gs9SL{dMl~#XoX>#kgS;Nq+2GjN1*O7Go+b9?I5!lU&sE~Snl~nnce7%8wwG> zvC|<*kLSv{Gq4T)?a2didsv_8DKM9A>2DoXQVc;z93)!GO;auitpLuI&n}zt4k!UF zc3#7Owf2H&9#mA^?t$kJ0dx3at~~pTEh*o&2mv#bw_I7_?&d@ zG=8&VhhtmyVt59(2@;G%P$qqkLVglE{)y+0JCJGFU#eC^>+70fj^Any)JU>nY*$Oa z%LG1O8j8{7#DW=`+28epwCRYQ$I1pH)+L6AMc>mKl)GEmAKwh?z~u(NyuconJ27%i1b-H#C-MTcu_(fs{LkD zs!`xnc-ryvTaa@TGfLZZ;b+kyP{VN_uM4z}4^Mqmi5ZA8ZlAxMWMblJ*|H@}X|5jH!e3B>M}j|qYyVdg}!m(r5< z!rbYrNQzQ7w_iG2~BBQESS7i%fCd2v>xuIJI?-z(*2l2>A1Ax>XR^G+B~Tol=(_x6h!mr2`n! z7KkxaGHrGQ{HHw7cF!NJ-g143geaoEO!D*X6eIs2#u9Ne zzsOM9DHuuPvvpWG4?rlZSnkR6MO#qRX#0LtjCm!Un5qF;%@&NTYTL%Ilmot>rc@A7 zL#^o^3ToGAOAGOl^n-c85xF!KNVR`9=A8sYdxd)7NP;|9{I}}Ph3!X2eA{w_`yZif zvBT7UH=ycmWiaonm1tLin->2RIl@q9cYCIPp>^q!8U|Z0pn9c92^`0LipuBvyc^V6 zlW#24+~6bE@#9EG0~lp|w*jf2|M}W+QGZS-K_=EP{m7o=y$(s(-4GRe^{(fxLwtni ztc|_L)+{q~-A4pTIgjw2rF|RpkVm4{`0*=xF;5ZOpPDPIT<7wZA8e@gEy@L3;FkBc z?lK7LcV+w??-D_uLoTlc7*v7mku2khQCEgw@oV#lF_XkLtR+nMDgsmd9Wt>~-eDs= z5B=Y#KM^25p$ViV3&t zZFlg82nl__I|wdxhh;;!){+kXCBn zow~<@&5=t&qW6^%)i+};^DM@4^k-PYO`Igg#C3rNIkfFbU(a~Pb>237*`6880y~Yr z`p@g$8~^rN7)`jHKWs6yxrKmeUVuM{`Jdc|2p8U zzF^8<>hXfSxM144VgZtE2Th0H*a6H#oS<@e`aQDT8|p4iS|=+#Wl|UCT-^ zWa=Ja+n%p@7`jtJ) zu}-ZIrJPe2A~bDlv&|I2DY+nrsTBz{H4fNpUUwS*l@2v<_1qtL#XK~frG0Y{AmQ=H)m=P3>K9|pZ11bjU)~-tDOJk(EM#-c=}a~VUfS|?t}IK0|KYZgV`ykreQL?N z!~0XuDHaYufH1)6KP<#2UYYm42S&m~%f@_qnozhYjSs z^^`J3RD>UfFtEgJcQ!=q#BGR7fhl#7TO0nn0qNU7E_v>+V^#)M3qul=l*h79jG5E` z>$0BjL9lxoxw#mV(TXJ$R-U>0r4g|3uWa~t@xp9N;&QpswZ?PWo*KM~s2%ZH;q2R1 zlb6dzm*B?4fk{p=UTatV3HXX?YXV|H;(YQ}G%YByN{ zPTV$w=!d1~XE`;(OPVxyyXOGwie?SSUfsefTmhx;@c`!Be;2ph-2N#1a=w z+7*ch`@n>7@S&Qw6~G&N>Z2J~pwBM^2=9ao^$=&3;s(VGU;(5eSloa#x|el`HdnT% zxR%?o0tG?wkBXms6xePyIBaxeFAGjPy0(8^;snfB3zG=d`ZAb9u*G^jWl$;m9&&H# zt};>`1fD$a%q{RtTl-pd@yI}(gQ-trcpHSv%zJ5)hA4I%GpfkpVu*)qsN|87Li@=Qn8fdj&~v@%YmxlFUfTj`>(< zigeLYr2!3Yp7n5a_7pk+i6|QP=hU)=5x3OI$6(<#t@#xa((fK?z$s)DTELHvu>5lr zAw1hP55aV0j5Ew2(-dViLGkFGtW$YMpgn?g?@$i(T3)v8iP;$Z9A^rikM|-$e_5&h z>jqEups^{sqz6?v&-0NN&_~iq~!BSVriiG6~*K0Ph8%R%)r-4EA6Q?J`_A~xv49p;7<|^Aij)=VM6JcfF z*ByuM`6n^7N01PCkzV}FuuWI*pm(trC~ORXeTZ>VlDp6CqMS^(2bP;#=`qKb(2c+K zyvhzjYWl_SjV(GZG}VPzd-rH%(6z(tf3(@)#{J*d2i=g!{#mCt${@clKOPG+8IP*) z`w!oqST6K@-axX$f}`IS3MIk7>SQ!+RgL-ORus|Y90$hsE0z7ErIPMD2w;GKqg*?+ zLO4@s>eZNcLDn2!w9y1B2HMn3NBboLKEqF^fjj0|c2A9{J6}V}?;GI5Q`m~)<|6OE zVI?mv<2HHj$Kqr$>kYFyQ=`C}i8p^$-h*br)X~zCN0$)7omhRAi)G$>k3v<=Kvr>^s$h;mzGlDhRHW$&&%i&_z{vim zHEqp4tV6>qWE)Vs;qSYYkuOj7YhGGH#->~i@ivSx zj@zwd*!v%X#NtRM?0Uk1|Ra@AEmFuIlA7m*0?;5<^yKY>?lY)bK~) z?!&(RRwu_|zLdZoR%5NzRjMLRxpmbS1{nIt1E0{q3C5i(nqP_%OIQN~}iAodGF< zfciF32L8hiorSt)sq=w1$-8%(?*6W8QQKB`6Ge*VFUuRn*Rum42PQS&TU=eDOA88E zL+NGGew|qiBty}9{6-Pb53FLTSa91h2F>%nYOeoJz5|9D!{!+Ly1r!-4Qa?-%G!KB z)^B?gHz!TbX#SZK1ypW^22tp0`YBPPt;_EY)@i8hL(magHN>|(DuSd}oNvBO6gC^| zF<3(9NTN+NY$!0V1xV3yuXEmSFkUZngBAqz+l`ygOW7KK+bR7!H1U_2C&Je_-1pfZ zLl`<>ZoVamxdAmxYksUDx({jvF3I2t{7bCB{47WXZaWEwP@m@wt`o7@P)jqx%j|jH z0KMDcR+x?-7qRHMt6^m%D_BH)br=`T8QzwQJ!Dku>Uhv$#^{3oX>^~1JTJ!fJV(s8 zE$Q}5958RPaVmr31DPy5EZ*y41W9zu6i1F-v7bFSwr;;)M`?$c*rX9JXz@)yCiG<$ zmsbnUvGl|q`$Un;{>g0(BZ8b(nX8|p=WNuD7XTAQP_pv*$SGGhSf2{uImDs!@~@oT zpy@LbCt6|L2ol=`Sy>6xpl*a-SY!PIK-1&%7K=UOm!3waTQ4C;-p&^;i8SQKuXW17 zArYM5-!@B(ThD~Rz??9KaN?bG-mdQxFssbMb54LTW3B&Cxd3dVkGs1?DzX zFtnnoT@>COwOS=h8DrB&;R=ScWVbyv6lu`A-88Q46Yh3_IW>ojN)ikXB{Lef8E(MI09&~Ap>5?F`q^8--rZvX4 zY~;{#imEm%;lRgZ=m8At=J;wb<@@oJU{qc`lyf=zsq`qGAdIoi@Cm0wL*Pq>hYQiE zjA#oE@InSXw}5qD9Xjj57G)K~cfGZNhwZ^c8sqJW$7hIAF?Jxwf9o2SYQpXgs6S9w zY4$mLFt#&3Xn^IVDiVazcLeMjyg!FG0yo+9zbO&!`x|xWyMV&Uet}((5Bby_jc`+- z9LLhh{dhRY{M<9sYs(gu67QfyBf!l1-irB^Ls&gVQ~laA`BStuU;%#x06d22(zUXSz2|TNpfdjX#owPf)z!^v~I;OX> zy^0Bw`VHgpb2fFy-Y9^jHGH6Ed;`xNsHwX8*HM;Ho@~4hCF>U;bS|{hE#< zt!=CS-&bGk2*h>#>QkixW?{{gTc%1uKZ#kv&A6c>U=wjBYgM?6C`ai6kke)T0?j3g z*qDkJKd|@yJq+VmuV1bKi}()9T7{hq4&5J5mL``QzmqjH-ZJ;ff4(o&Thh;DtQq~x ziwa)t%d9`|8c8{E6O`iseKm;epbFYs}hg}O8}j`5%{;+ zM0MLXh^wB6?t>Wxw1U2vCl@}(z{X6ZcD`O=4^gpzC-3=P2)uPad-C?1K^c9iPHIYgy7_EELqJvB%)HDS_o8OjrY6(wUXQ{PEmSC>mu$ zEZH7ev<4PH7Lrr^vF&X}ujdeIwEt>ZihP@)+z_tbGxK?>FHqQu(DB6RysQC@SfK9v z^$~GV?vSvOY15N^>yWWS@Yzlekj2~=RSj_GFO*tsTlGxgRq-|l3iWBDQlN?L!fQm# zEBoXT8zBL23X4}#iIlNf@4Mcd3@C-TV2mZrKFjae`vh?ld^Phk+2!Pa7WQ5=^MeI> zm%XF8n!r{t*tQ8og}sP#l6Q{ufE3>QTg1;u_7Gjm5lBABK?k%ZEGDwsLzGeWJZab40={GyTRz8Z zv`>iX2*6WTD|Zq3svYaiVQl%4Pq$x-=7ryq6)a!^M-m1%53ClpZU_fP(vZ4VNb8me zs6b1+L;o{@-L_@Q@AJ&|1$Qo~b>KSQ0>VG^dKVp^72%P7UQY9gk;O7Es$#A631r?A z9{DFYzKUO}8ZH7F0gWQTvVXHv_ya#_*>J30;e|GA`}bO_ZJt0#v1w&Y?L#osi9VGp z+dSxnhAlkr2F=VMxs)s>*;m&KIvud~*L3l+XTcK;NPHw=5A@%d-80Ny7A|Yv(XI%d z7OvCJJ$RNDr~u|9Y;K;3xSBDVwR!391^ewQHBHP`-tOBA?zLIRAUFNE`a8I|tY0Qn z#M~DB%iOr9p#&yI(tUO&vnc3yEO-6qI9k6kG#GDo_HL&yJLBpOa@%ZLl@OVmvjIrutO4;7|t1XA11?s-#oZmP#Rv5c#m|kc@qa&JAM3;KQ zb^IA~`bCNGv}$+$X}xtVlYY(LV>W;}r&_pf6w^+-ZcLIww@h|t1+IJ^^7?$^#J-iU zE6%Z1k(&D3NeohOn(w{%Hz>f*0Z#*cAv4>BU*F%toHhtPK*+Bcwma&!?isge#@j3TZk%`B0aRl#@+A zsksNrNgN0Q9R8cXbjTk-bi~bOkbK#Oev!JD^zQySz0cgxiknKJ*LX2IupOj%36fI6 z@%F9Cs+DrGy0$!y*bxUTspkp#xo*M8nTfFuJ>=d;U$WXY2CXmHrm2-~zY&V;Xr8e- z$84<=Wf+=o+Vcf5i(%^IPFf)j7}6~z&xRq#7WKZ|n1y$OosQqvis1T=KEB0RV+a)c zWj>m<+UkNhQtiKqLH~5y-fa@W?rCN63^-Fp|7UT`JlB^5CPtfQi~p zC17J@^SGNjw8lB21dDTn;aEcZj~C`!(9hLMCFiU^ie_k)jZWuDf)I;kKL>bSYg@wh zl#xE_%w%Mo2c)`pm-J_(&vR~d(Kl2HO1oZA$D59Z7=$BSGcoSG9(+F_GWn()Kkxpj zW@j_Q( zkmS}oZHfkP4W~sOx$PmbeJ%C(YbTj}4w#k=8=!Had1MqisQaY(S$6dl(vegvmnVfK ztb#|Mt59sg#5AeB|G{36tQZ@QgF$cIWY!$2C3bh$fWfvUQkHCo**7*It7blxkOR@e z+~AlG>0xw0PcoOsXkQ_{ysFSYotx6>Mrnlmx-il%O~m&3!>(RKP7k$qcGvSh9M%4; zi~aEUdc+9#z(M@uz1HKQ|9uH(m&Yup{skfP_;m>(!tHW+dUgN^z1fW(fP8;xn_uj{ z2?8Y?;XE_E8mtHTtw#`rlH*%iTg11ceYo_v&cnVd{@46ySM(6MZ+pl&4?r8YAL8==T&M){5}Rp7%17Fbp!^Gj^ou$=gPwX25(O+~O7ES6Xh zg;7xe=QzmKyHCixCA}@6P02^yF!|F6J1$;B%Hx6L4=6x5lQ!eAegC|@c{6{0+5?xK zf@??KN`TrAjA=a!o>9GHlYW4Dw_Lz-{o*qMClFiM5qD<6fAgOxqggOZoLBcQIIzd* zm2cluWZ=kA0L)CB>$eA!)A}VK=Qh+qUhTC1_$nUi4j!KEDXW`{>$xkRzOx+m37m!9 z(Gqe82T*(rJ1+PDA9#PsZZCi6IMZ%(VySCma92q8G|lfzVGuo`Sg6r%47JdC-V#S@ z>(~d9FS={2z@LMAD!0fPD(t8Ptnq0VqK5z#1={7_^_;XxKn+}uDZqwE{e~5loDaIB zi!^JF-VVK=7pd*I^l{ib@vsY~dtp}N^R;dlk?qexT=P?=@>S@!OugX%`dhl2%XCfN zYLAU!=9BSdP523hlb>=Peva@wRksiZ1cO%&|DE1Zx0*cLl^j7@L(thI57np)nSN<6 z${u%CuNbx_zRjvvqFJZ7T#U|HY~6wc zv&eu;?b7;4957hPss|~&D>B)4HSee!FOQ=%B+Cx=RDt1iu;;GY4v57GhDbE zBn4q3EwW`GummBmPxX|*&8XYH))qP^D#SWvkvkY*zO($B>v=$Z+hb+5EET3vFg)-o znaT>I+c(2)Qn@3AD>9xR9QwE4f$U1y?cx-Kuu}SH{LdU&1By5quc=_p!;DFvHAzuj zB`D%?_M@YCV10TZ-hV5~(40t0TgVOM5+FFSk9XTF(eo2;m3U3B&ArU>AC;c&-TGFw zM`2&2BslyxS@SftH=9OD^wI#);-?$_VkEXoS3>Usf<BTeJdM8ary}n_n;qzSvFK~Hy_T}u zUH&_;Suq_gV6ZDLCh3` zAdmHbJ)7PA^Y%YhgTYUM5!-Fw5oBNV+5X3X{&}icWzWpXT5@x$*=#^XX`pLU{yp^8UH(7w4Ui!Jf9JRi=BsOGd@`H+nkyZ3uKz~-ha$w*4-Um?q^?zb`(AZ`zcvi+y1v$6Jt_(4#Ehx5L&*Uzv>Q6YS zYH!GhzeueLGPw9bc60y9@)(=*`-0ySK~9Hp*MGU%?P`)Jot_`abQ8(`s49@-$grOMDI7)KUhm~Km^{ABJm)t@`VnmnOs=)a1uIN6v!V2uK;I$r3S7+}v_)^hC1Vmg z8I9khxzZW3P<_X|rAx;*^psq#ty4oj3)nxJG(RY9xg4eSvGH+?78|^JBG7O&!-7Z} zIrt|70m;%vx19cWQ0|ESYgdlZHDNT*(qv80kz)6X=H>7+%kU!e>14Q|eHn0U(r%C| zV3V%Nf*w%bX=TTvA_(LpMC&{O!2iy{yOSg}^)z06IRiU0ivuIJw`D0z^@EQ4iw>VGEH7h`L{uQ+<5 zEN?t)nj~Mg{`dG=!0M`wzYQaGpb7PtZE!*q#N{j-SP>x;in!A*K#-K5Y5Sii(n}&T zHd+)vm)75OohR93(pRL`yC_${p*<_bb7j&Q?<^VbMd@j`p%mo5M6bTT-4TjcPqAzH zuN!|osv_~4w1SZl$-2M63U21={&sP@NI$5I%iW2<@&5<=^<3=sbB4#k9u{y+0d33b zeH(;((>Vw8NYSl!zGZ&u*V@TmmWX&dp+Ei_fHWpto`t?Zc^8UnIkQ#|Lk zClyW<##}Ngh6SltHn9L}-DyQP;zP3%|>J z8G#iaaCKjFY0Um|hK8@H@4j&$JHtT{So!nUu0Q@d=jyEc)(i~sVY*(x1rHNm)!kwN zRLBIB;_YU3*VeGy@!wf|2jTmor-QQCV^fkC`46Yl1!6*)@ ziVzk8>wI35cd|f#0gIlTr}=lS8NihZ(1NT5g`hwNb`+2T8CX1pG53O<3yhEGpV8m> zK-)%uY+#nnxC7D+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/res/drawable-anydpi-v26/ic_launcher_foreground.xml b/android/res/drawable-anydpi-v26/ic_launcher_foreground.xml deleted file mode 100644 index ce92ea1..0000000 --- a/android/res/drawable-anydpi-v26/ic_launcher_foreground.xml +++ /dev/null @@ -1,106 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/android/res/drawable-hdpi/ic_launcher.png b/android/res/drawable-hdpi/ic_launcher.png index ace457e0a422932704581b8a71906576aede191f..2b9989e2f36065b18a963cddb7949f925f0eef97 100644 GIT binary patch literal 6519 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 delta 3382 zcmV-64axGlAGjKjBYzD4NklmdGkw zvABXPvJ^|PQ~|XBwNM*N6^lSDW9xX*CTTlK=d`We#3f1F_Q}{Wj+)MNI-TkMHkmp3 zAk*jg7yRY}+&e59C6k%Vhum|1-=OOGz4v{d_j#WZgzum4pMUS4r#%}4LHK(?5MB@j z;RoLlFD%8dVO^0QJ$iK0%*>3}=S|uzN3wFExZ*I5y<-)?kjn5nZ z3lkF)=O!j5aDTa6*le~nU$Xj(#>dAQA0OxCmtW@0nKLWUYPD#!T1H1lIeq#xGcz;N z0+>uD1_uWv1_lOJU^E&T8XCgkaNuw_yi0H7na`%l$;rnakB70bF-Av686O{)R#{|f zYD!{uc9z-MS-f8Fir~Fouk;4oZa1e-pJr}uPWlXw$A5#{?Z#rU(A(QfUtiyvH()lK zF_}!5Os4-71Yy&&g5Mwr!Zwe`!*ZskrZ{`{ti&s?yz)d=ufEsol>+d1Je)p#`ia~{P51l(>nZnvBA zwkGyf6%*ZFN8;OONPPPYichbR@x=#ZeDMK_KYxJy?k|a~EF!Y9h@JrhBO@cY-EJwd z$A8Ag7#kbI<#OS4I_Wg%*rO~Uyeyx@58o#F&o@c>e367d%oBNOhR91Zgf<=}q&SD1 z`s3eR;9yGw!DV@bx1Av6`bAQ%UnKkAKjNi@hZ2gv+#;|fhk)V(bQ$%Gj*c=hF(Iw| z>hq&R-_Op1Om-GzlKk0q(iiR{f3!%-e}DX*==lrm|MdlSHB{k~BPYH3(EnUuPfsI? zPp_l+^g8KFC_aB5#b1Am{Es)0{o^>%=f^43cT>^UOiRC3Ivd1uq*2q2vbB-CJ~fd) z9wG9_BP9M|p5(v$hNRDKknqVo@t^#f_)q4E|70G2)p2}s-FmwD1U5j zAgDBt2wf`&mR3CF*3U@3evy>hZ;^KIDrpbq$y#_w*1|)=`kL`CdWnphBVz4lXlRI` zp&_zrj^J0AMX;uk^o0kcFWe{b!LNwFdzsiZAJvbk*aNBPYJ1 z7`0lBTCIM50r3DUXsVM0#4VF@`+rT6ZoE#)?YBt%=rXDIu8{fFJu<)gm_0TPL3Nd+ zx75+2>!(N8Pj`PG-Ti$iT51V6QBJ6(8~Imvk$-iUgnPdv?#?^J-ufxg*Iq^T{_CVZ zx=+e7frQEuy1KgP>gsxa0r4cvt*>TxNiKW(7X`8x9+LL(UDEDdCHeMSB!6D}35ho@ zl5+0~Dfh0B@#P&d7akCI+}+E>{_~X;0$X$B$d6a8KL^CJn6peEdznD$y(=W&ev`y&KOte6fMQ7?RuotY z{z(GycNYbsmjq(({^Hvc5Pwff`}i0}r=6zZA;SArg!i`~|KklZzWhD%&u)@@=N*zh z{5gs5zd^!#uaiIANU6Gnn!Y;pb}M?Dl@5JB9r`|wb|0s>;~+VfdSY+BM$FBN#QyG0 zVn2MFgnzkC^1uBP@qfBOKvz8hUGyRTAImrZ4MFdcP8QlH~;xp28$v>eZ;JTs7j z6B)?nFCd%0KKk<)82F*`ep!{I=!R@2eZvHmw8 zVs<$=&``sHh8hws&3_Sh^*l)*{+zVW-y`MzRpOmJ#5udEu1%$_d=K5VnV9q)m~L<0Y@Nt#oy6b$1qq+sK=!*giMo82eQ%s19m;fcs$tc zcKZ7I=Q z=H}*@o0}tCS-`g3bSgVkQtvc7JIm@VEb^@g=yWgnc4YctjDDu3xtTah16ZqhCerukEqy_>4+ z-82@5&{!OTQW3y`gq<8JOqBYh>UI^C%?-5oYNc%=-nl0xCYYI-VRCX(+P>=&7#SJC zYPCwM`!tqc%BxEgDbEZfH_4Bfa35mAeds+gCP{t1cySl^{c_xH zH#0Lccz-;e_2+=t`VJ2dV>X+ySS-?qtPb30G|;1NqDS3GQ$-y02SX@T1V{q41;Nx7 z1W7bi#G%u)q0_WsHVv)02#FJk(a}*RCnp&j8~f%0BID!Z(!pf0SXQjMuCGT*RLjXI zrn+RPtHPvGDblJ8VN$&xb6o_b@?Dh5cQNL&t$*0})6>%{s?KV@6#=u^{6qm|Mj)1x zk&=KIcy!nnqQkb(stjR5y&uz(K#AOsG1u^lr2WPG;a@w za(^S}Y&wj?;lSy1u9-jC?RGjlJL&A~e13tRo*sI7dN7$xYbudQ$H@wm8G%%01xksU z5wln-OY-GXqR!3DF*`fUp|S%+hi*n8+lIR0Mbs59Qm*i$ByA_E+7fIw8+N;WP3g4T z?R0c>tgjamw};tm#%i^q*Y#3;xPn%-n(kM}6`F{a5 zJ3EU}r)6KrCiaDF!dxGYr#%vNc`(JPz7!;FCn|U&QNbH&YN$c4*E29Mu>Kqn$9q<* z6_d$Cdut;Jd$*CWcN-O%fgE{hH|okzY)z32)b1rECWw@nAlg)oQf(JmK0}?FnnK^N zAtB0-_((tcj)r2X52vjxh^kCK%75g($U-+E3*CgOsg8kx0Zb;7v>n$iFgZEN+}s>? zvks*q0Hq=TXG;{5ozc`51Q8v!g=AUaiV2!H&wSG1WH1=$@9&rPbVAfFqJlS4o$HUM zJrZYA1jVVo6sP)P9qj$)t;Ev=%F_LDHb*k4-cN18?xzY^ES9GV^!4@q-+u{+<&uWZ7<_f;Vy?ej7Ep z{+uXy5w)rgwW~{N_RTVju8%e2r7a6kclEBke+h8!P>FHfA zm$ag(F+oHHZ$!R-E5)h4D1S3Uq#>4wn8d@w!_PIH-XI9V4wK3Bc=^P6IVX?iQ(KWi zc|i&}8F3Wl%GY#~7K=sdmsX#q4u?bf-9cHDO@4MFW)aBvWl$%M^j z!(y>KUK04)-v>4bg0MxUQoXUd9IoyfwOTD|wVIxuo;7=Qc?bD*7=H|gH7hQ%yn(dY zY;<;Zz9tC5mS+hFf*|~G^XAPF4Gj%H(`Yo0#kOKKYPFh{mKNIE+ok?q#OZXd$cv|; z)oP`Y$!ZJ+1A~Ku7z~ETDwXP|n>TNc5Cq|e&kA15gN=e91POw$PY{F{K@j4;BVv|f z2wIBixqoimAPB-gEHC}jj|4&3{2lS5r5Jv&p5UJ*^j+}%^Z)+&FVpJ$oRjhiumAu6 M07*qoM6N<$f_JB!d;kCd diff --git a/android/res/drawable-xhdpi/ic_launcher.png b/android/res/drawable-xhdpi/ic_launcher.png index 190d16dfa68d6e5c0bebfd299121e381622fd63e..739b6ce82745dd172c6ed26db009b0a2a79d1203 100644 GIT binary patch literal 7397 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

A$UnaE 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 diff --git a/android/res/drawable-xxhdpi/ic_launcher.png b/android/res/drawable-xxhdpi/ic_launcher.png index b58006bd4b9e4d0a80dbf1086265c7f0ef48ead2..1c1aa9054a0fa6751dffc61f94391636f10ab060 100644 GIT binary patch literal 11243 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 z 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 diff --git a/android/res/drawable/ic_launcher_background.xml b/android/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..bae566f --- /dev/null +++ b/android/res/drawable/ic_launcher_background.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + diff --git a/android/res/drawable/ic_launcher_foreground.xml b/android/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..a30acde --- /dev/null +++ b/android/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopLauncher.java b/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopLauncher.java index 146d52a..5903920 100644 --- a/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopLauncher.java +++ b/desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopLauncher.java @@ -8,7 +8,8 @@ import ru.deadsoftware.cavedroid.CaveGame; class DesktopLauncher { public static void main(String[] arg) { Lwjgl3ApplicationConfiguration config = new Lwjgl3ApplicationConfiguration(); - config.setWindowIcon(Files.FileType.Internal, "icons/icon256.png", "icons/icon128.png"); + config.setWindowIcon(Files.FileType.Internal, + "icons/icon512.png", "icons/icon256.png", "icons/icon128.png"); config.setTitle("CaveDroid"); config.setWindowedMode(960, 540); config.useVsync(true); -- 2.29.2 From f094aae367211d5b5f48468762a9fe9696288e89 Mon Sep 17 00:00:00 2001 From: fredboy Date: Wed, 15 May 2024 23:57:25 +0700 Subject: [PATCH 14/16] Fluids updater in kotlin --- .../GameWorldFluidsLogicControllerTask.java | 223 ------------------ .../GameWorldFluidsLogicControllerTask.kt | 189 +++++++++++++++ 2 files changed, 189 insertions(+), 223 deletions(-) delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/world/GameWorldFluidsLogicControllerTask.java create mode 100644 core/src/ru/deadsoftware/cavedroid/game/world/GameWorldFluidsLogicControllerTask.kt diff --git a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldFluidsLogicControllerTask.java b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldFluidsLogicControllerTask.java deleted file mode 100644 index 416721f..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldFluidsLogicControllerTask.java +++ /dev/null @@ -1,223 +0,0 @@ -package ru.deadsoftware.cavedroid.game.world; - -import com.badlogic.gdx.utils.Timer; -import ru.deadsoftware.cavedroid.game.GameItemsHolder; -import ru.deadsoftware.cavedroid.game.GameScope; -import ru.deadsoftware.cavedroid.game.mobs.MobsController; -import ru.deadsoftware.cavedroid.game.model.block.Block; - -import javax.annotation.CheckForNull; -import javax.inject.Inject; -import java.util.*; - -@GameScope -public class GameWorldFluidsLogicControllerTask extends Timer.Task { - - public static final float FLUID_UPDATE_INTERVAL_SEC = 0.25f; - - private short mUpdateTick = 0; - - private final GameWorld mGameWorld; - private final MobsController mMobsController; - private final GameItemsHolder mGameItemsHolder; - - private final Map, List> mFluidStatesMap; - - private final class UpdateCommand { - final Runnable command; - final int priority; - - private UpdateCommand(int priority, Runnable command) { - this.priority = priority; - this.command = command; - } - - private UpdateCommand(Block block, int x, int y, int priority) { - this(priority, () -> mGameWorld.setForeMap(x, y, block)); - } - - private UpdateCommand(Block.Fluid fluid, int x, int y) { - this(fluid, x, y, ((5 -fluid.getState() )+ 1) * (fluid.isLava() ? 2 : 1)); - } - - private int getPriority() { - return priority; - } - - private void exec() { - command.run(); - } - } - - private final PriorityQueue mUpdateQueue - = new PriorityQueue<>(Comparator.comparingInt(UpdateCommand::getPriority)); - - @Inject - GameWorldFluidsLogicControllerTask(GameWorld gameWorld, - MobsController mobsController, - GameItemsHolder gameItemsHolder) { - mGameWorld = gameWorld; - mMobsController = mobsController; - mGameItemsHolder = gameItemsHolder; - - final List waters = mGameItemsHolder.getBlocksByType(Block.Water.class); - waters.sort(Comparator.comparingInt(Block.Water::getState)); - - final List lavas = mGameItemsHolder.getBlocksByType(Block.Lava.class); - lavas.sort(Comparator.comparingInt(Block.Lava::getState)); - - mFluidStatesMap = new HashMap<>(); - mFluidStatesMap.put(Block.Water.class, waters); - mFluidStatesMap.put(Block.Lava.class, lavas); - } - - @CheckForNull - private List getFluidStateList(Block.Fluid fluid) { - return mFluidStatesMap.get(fluid.getClass()); - } - - private int getCurrentStateIndex(Block.Fluid fluid) { - @CheckForNull final List stateList = getFluidStateList(fluid); - - if (stateList == null) { - return -1; - } - - return stateList.indexOf(fluid); - } - - @CheckForNull - private Block.Fluid getNextStateBlock(Block.Fluid fluid) { - @CheckForNull final List stateList = getFluidStateList(fluid); - - if (stateList == null) { - return null; - } - - int currentState = stateList.indexOf(fluid); - - if (currentState < 0) { - return null; - } - - int nextState = currentState + 1; - - if (nextState == 1) { - nextState++; - } - - if (nextState < stateList.size()) { - return stateList.get(nextState); - } - - return null; - } - - private boolean noFluidNearby(int x, int y) { - return !mGameWorld.getForeMap(x, y - 1).isFluid() && - (!mGameWorld.getForeMap(x - 1, y).isFluid() || ((Block.Fluid)mGameWorld.getForeMap(x - 1, y)).getState() >= ((Block.Fluid)mGameWorld.getForeMap(x, y)).getState()) && - (!mGameWorld.getForeMap(x + 1, y).isFluid() || ((Block.Fluid)mGameWorld.getForeMap(x + 1, y)).getState() >= ((Block.Fluid)mGameWorld.getForeMap(x, y)).getState()); - } - - private boolean drainFluid(int x, int y) { - final Block block = mGameWorld.getForeMap(x, y); - - if (!(block instanceof Block.Fluid fluid)) { - return true; - } - - if (fluid.getState() > 0) { - if (noFluidNearby(x, y)) { - @CheckForNull final Block.Fluid nextState = getNextStateBlock(fluid); - if (nextState == null) { - mUpdateQueue.offer(new UpdateCommand(-1, () -> mGameWorld.resetForeMap(x, y))); - return true; - } - - mUpdateQueue.offer(new UpdateCommand(nextState, x, y)); - } - } - return false; - } - - private boolean fluidCanFlowThere(Block.Fluid fluid, Block targetBlock) { - return targetBlock == mGameItemsHolder.getFallbackBlock() || - (!targetBlock.getParams().getHasCollision() && !targetBlock.isFluid()) || - (fluid.getClass() == targetBlock.getClass() && fluid.getState() < ((Block.Fluid)targetBlock).getState()); - } - - private void flowFluidTo(Block.Fluid currentFluid, int x, int y, Block.Fluid nextStateFluid) { - final Block targetBlock = mGameWorld.getForeMap(x, y); - - if (fluidCanFlowThere(currentFluid, targetBlock)) { - mUpdateQueue.offer(new UpdateCommand(nextStateFluid, x, y)); - } else if (currentFluid.isWater() && targetBlock.isLava()) { - if (((Block.Lava)targetBlock).getState() > 0) { - mUpdateQueue.offer(new UpdateCommand(100, () -> mGameWorld.setForeMap(x, y, mGameItemsHolder.getBlock("cobblestone")))); - } else { - mUpdateQueue.offer(new UpdateCommand(300, () -> mGameWorld.setForeMap(x, y, mGameItemsHolder.getBlock("obsidian")))); - } - } else if (currentFluid.isLava() && targetBlock.isWater()) { - mUpdateQueue.offer(new UpdateCommand(200, () -> mGameWorld.setForeMap(x, y, mGameItemsHolder.getBlock("stone")))); - } - } - - private void flowFluid(int x, int y) { - Block.Fluid fluid = (Block.Fluid) mGameWorld.getForeMap(x, y); - @CheckForNull final List stateList = getFluidStateList(fluid); - - if (stateList == null) { - return; - } - - if (fluid.getState() < stateList.size() - 1 && mGameWorld.getForeMap(x, y + 1).hasCollision()) { - @CheckForNull Block.Fluid nextState = getNextStateBlock(fluid); - - if (nextState == null) { - return; - } - - flowFluidTo(fluid, x - 1, y, nextState); - flowFluidTo(fluid, x + 1, y, nextState); - } else { - flowFluidTo(fluid, x, y + 1, stateList.get(1)); - } - - } - - private void updateFluids(int x, int y) { - final Block block = mGameWorld.getForeMap(x, y); - if (!block.isFluid() || (block.isLava() && mUpdateTick % 2 == 0)) { - return; - } - if (drainFluid(x, y)) { - return; - } - flowFluid(x, y); - } - - private void fluidUpdater() { - int midScreen = (int) mMobsController.getPlayer().x / 16; - for (int y = mGameWorld.getHeight() - 1; y >= 0; y--) { - for (int x = 0; x <= Math.min(mGameWorld.getWidth() / 2, 32); x++) { - updateFluids(midScreen + x, y); - updateFluids(midScreen - x, y); - } - } - - while (!mUpdateQueue.isEmpty()) { - final UpdateCommand command = mUpdateQueue.poll(); - command.exec(); - } - } - - @Override - public void run() { - if (mUpdateTick < 0xFF) { - mUpdateTick ++; - } else { - mUpdateTick = 0; - } - fluidUpdater(); - } -} diff --git a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldFluidsLogicControllerTask.kt b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldFluidsLogicControllerTask.kt new file mode 100644 index 0000000..d0f4eaa --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorldFluidsLogicControllerTask.kt @@ -0,0 +1,189 @@ +package ru.deadsoftware.cavedroid.game.world + +import com.badlogic.gdx.utils.Timer +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.model.block.Block +import ru.deadsoftware.cavedroid.misc.utils.bl +import java.util.PriorityQueue +import javax.inject.Inject +import kotlin.math.min +import kotlin.reflect.KClass + +@GameScope +class GameWorldFluidsLogicControllerTask @Inject constructor( + private val gameWorld: GameWorld, + private val mobsController: MobsController, + private val gameItemsHolder: GameItemsHolder, +) : Timer.Task() { + + private var updateTick: Short = 0; + + private val fluidStatesMap = mutableMapOf, List>() + + private val updateQueue = PriorityQueue(16) { c1, c2 -> + c1.priority.compareTo(c2.priority) + } + + init { + val waters = gameItemsHolder.getBlocksByType(Block.Water::class.java) + .sortedBy(Block.Water::state) + val lavas = gameItemsHolder.getBlocksByType(Block.Lava::class.java) + .sortedBy(Block.Lava::state) + + fluidStatesMap[Block.Water::class] = waters + fluidStatesMap[Block.Lava::class] = lavas + } + + private fun getNextStateBlock(fluid: Block.Fluid): Block.Fluid? { + val stateList = fluidStatesMap[fluid::class] ?: return null + val currentState = stateList.indexOf(fluid) + .takeIf { it >= 0 } ?: return null + + var nextState = currentState + 1 + + if (nextState == 1) { + nextState++ + } + + if (nextState < stateList.size) { + return stateList[nextState] + } + + return null + } + + private fun noFluidNearby(x: Int, y: Int): Boolean { + val current = gameWorld.getForeMap(x, y) + + if (current !is Block.Fluid) { + throw IllegalArgumentException("block at $x;$y is not a fluid") + } + + val onTop = gameWorld.getForeMap(x, y - 1) + val onLeft = gameWorld.getForeMap(x - 1, y) + val onRight = gameWorld.getForeMap(x + 1, y) + + return !onTop.isFluid() && + (onLeft !is Block.Fluid || onLeft.state >= current.state) && + (onRight !is Block.Fluid || onRight.state >= current.state) + } + + private fun drainFluid(x: Int, y: Int): Boolean { + val fluid = (gameWorld.getForeMap(x, y) as? Block.Fluid) + ?: return true + + if (fluid.state > 0) { + if (noFluidNearby(x, y)) { + val nexState = getNextStateBlock(fluid) + if (nexState == null) { + updateQueue.offer(UpdateCommand(-1) { gameWorld.resetForeMap(x, y) }) + return true + } + updateQueue.offer(UpdateCommand(nexState, x, y)) + } + } + + return false + } + + private fun fluidCanFlowThere(fluid: Block.Fluid, targetBlock: Block): Boolean { + return targetBlock.isNone() || + (!targetBlock.params.hasCollision && !targetBlock.isFluid()) || + (fluid::class == targetBlock::class && fluid.state < (targetBlock as Block.Fluid).state) + } + + private fun flowFluidTo(currentFluid: Block.Fluid, x: Int, y: Int, nextStateFluid: Block.Fluid) { + val targetBlock = gameWorld.getForeMap(x, y) + + val command = when { + fluidCanFlowThere(currentFluid, targetBlock) -> UpdateCommand(nextStateFluid, x, y) + + currentFluid.isWater() && targetBlock is Block.Lava && targetBlock.state > 0 -> + UpdateCommand(100) { gameWorld.setForeMap(x, y, gameItemsHolder.getBlock("cobblestone")) } + + currentFluid.isWater() && targetBlock.isLava() -> + UpdateCommand(100) { gameWorld.setForeMap(x, y, gameItemsHolder.getBlock("obsidian")) } + + currentFluid.isLava() && targetBlock.isWater() -> + UpdateCommand(200) { gameWorld.setForeMap(x, y, gameItemsHolder.getBlock("stone")) } + + else -> null + } + + command?.let(updateQueue::offer) + } + + private fun flowFluid(x: Int, y: Int) { + val fluid = gameWorld.getForeMap(x, y) as Block.Fluid + val stateList = fluidStatesMap[fluid::class] ?: return + + if (fluid.state < stateList.lastIndex && gameWorld.getForeMap(x, y + 1).params.hasCollision) { + val nextState = getNextStateBlock(fluid) ?: return + + flowFluidTo(fluid, x - 1, y, nextState) + flowFluidTo(fluid, x + 1, y, nextState) + } else { + flowFluidTo(fluid, x, y + 1, stateList[1]) + } + } + + fun updateFluids(x: Int, y: Int) { + val block = gameWorld.getForeMap(x, y) + if (!block.isFluid() || (block.isLava() && updateTick % 2 == 0)) { + return + } + + if (drainFluid(x, y)) { + return + } + + flowFluid(x, y) + } + + private fun fluidUpdater() { + val midScreen = mobsController.player.x.bl + + for (y in gameWorld.height - 1 downTo 0) { + for (x in 0 ..< min(gameWorld.width / 2, 32)) { + updateFluids(midScreen + x, y) + updateFluids(midScreen - x, y) + } + } + + while (!updateQueue.isEmpty()) { + updateQueue.poll().exec() + } + } + + override fun run() { + if (updateTick < 0xFF) { + updateTick++ + } else { + updateTick = 1 + } + + fluidUpdater() + } + + private inner class UpdateCommand( + val priority: Int, + val command: Runnable + ) { + + constructor(block: Block, x: Int, y: Int, priority: Int) : + this(priority, Runnable { gameWorld.setForeMap(x, y, block) }) + + constructor(fluid: Block.Fluid, x: Int, y: Int) : + this(fluid, x, y, ((5 - fluid.state) + 1) * (if (fluid.isLava()) 2 else 1)) + + fun exec() = command.run() + + } + + companion object { + const val FLUID_UPDATE_INTERVAL_SEC = 0.25f + } + +} \ No newline at end of file -- 2.29.2 From 947f14cbeb9db09ca1ed5e80f6a66ebba193e855 Mon Sep 17 00:00:00 2001 From: fredboy Date: Wed, 15 May 2024 23:59:04 +0700 Subject: [PATCH 15/16] Lower min android api --- android/build.gradle | 4 +++- core/build.gradle | 2 +- .../ru/deadsoftware/cavedroid/game/GameRenderer.java | 11 +++++++++-- .../cavedroid/game/objects/drop/DropController.java | 8 ++++++-- core/src/ru/deadsoftware/cavedroid/misc/Assets.java | 4 +++- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index bf1af00..d52b9e9 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -37,10 +37,12 @@ android { } defaultConfig { applicationId "ru.deadsoftware.cavedroid" - minSdkVersion 24 + minSdkVersion 19 targetSdkVersion 34 versionCode 25 versionName "alpha0.9.2" + + multiDexEnabled true } applicationVariants.all { variant -> variant.outputs.all { diff --git a/core/build.gradle b/core/build.gradle index 7aff468..3b061a7 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -22,5 +22,5 @@ dependencies { implementation 'org.jetbrains:annotations:23.1.0' implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlinVersion" implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinSerializationVersion" - annotationProcessor "com.google.dagger:dagger-compiler:$daggerVersion" + ksp "com.google.dagger:dagger-compiler:$daggerVersion" } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java index 0dcbefc..93dc8b9 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java @@ -82,7 +82,12 @@ public class GameRenderer extends Renderer { mMobsController = mobsController; mGameWorld = gameWorld; mRenderers = new ArrayList<>(renderers); - mRenderers.sort(Comparator.comparingInt(IGameRenderer::getRenderLayer)); + kotlin.collections.CollectionsKt.sortWith(mRenderers, new Comparator() { + @Override + public int compare(IGameRenderer o1, IGameRenderer o2) { + return o1.getRenderLayer() - o2.getRenderLayer(); + } + }); mCursorMouseInputHandler = cursorMouseInputHandler; mMouseInputActionMapper = mouseInputActionMapper; mKeyboardInputActionMapper = keyboardInputActionMapper; @@ -375,7 +380,9 @@ public class GameRenderer extends Renderer { Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); spriter.begin(); - mRenderers.forEach(iGameRenderer -> iGameRenderer.draw(spriter, shaper, getCameraViewport(), delta)); + for (IGameRenderer iGameRenderer : mRenderers) { + iGameRenderer.draw(spriter, shaper, getCameraViewport(), delta); + } handleMousePosition(); spriter.end(); diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/drop/DropController.java b/core/src/ru/deadsoftware/cavedroid/game/objects/drop/DropController.java index 6666fc8..0213c97 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/objects/drop/DropController.java +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/drop/DropController.java @@ -25,7 +25,9 @@ public class DropController implements Serializable { } public void initDrops(GameItemsHolder gameItemsHolder) { - mDrops.forEach((drop) -> drop.initItem(gameItemsHolder)); + for (Drop drop : mDrops) { + drop.initItem(gameItemsHolder); + } } public void addDrop(float x, float y, Item item) { @@ -48,7 +50,9 @@ public class DropController implements Serializable { } public void forEach(Callback callback) { - mDrops.forEach(callback::run); + for (Drop drop : mDrops) { + callback.run(drop); + } } public Iterator getIterator() { diff --git a/core/src/ru/deadsoftware/cavedroid/misc/Assets.java b/core/src/ru/deadsoftware/cavedroid/misc/Assets.java index 71cad7a..893414b 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/Assets.java +++ b/core/src/ru/deadsoftware/cavedroid/misc/Assets.java @@ -49,7 +49,9 @@ public class Assets { public static void dispose() { minecraftFont.dispose(); - loadedTextures.forEach(Texture::dispose); + for (Texture texture : loadedTextures) { + texture.dispose(); + } loadedTextures.clear(); } -- 2.29.2 From 1e285247085ba04351feb486a0be6aa577f43093 Mon Sep 17 00:00:00 2001 From: fredboy Date: Thu, 16 May 2024 01:43:26 +0700 Subject: [PATCH 16/16] Add my repo for automultibind --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 1e317b0..60a1bb3 100644 --- a/build.gradle +++ b/build.gradle @@ -39,5 +39,6 @@ allprojects { maven { url "https://oss.sonatype.org/content/repositories/snapshots/" } maven { url "https://oss.sonatype.org/content/repositories/releases/" } maven { url "https://jitpack.io" } + maven { url "https://mvn.fredboy.ru/releases/" } } } -- 2.29.2