DEADSOFTWARE

Add preferences
authorfredboy <fredboy@protonmail.com>
Mon, 13 May 2024 13:31:34 +0000 (20:31 +0700)
committerfredboy <fredboy@protonmail.com>
Mon, 13 May 2024 13:31:34 +0000 (20:31 +0700)
14 files changed:
android/assets/json/menu_options_buttons.json
android/src/ru/deadsoftware/cavedroid/AndroidLauncher.java
android/src/ru/deadsoftware/cavedroid/AndroidPreferencesStore.kt [new file with mode: 0644]
core/src/ru/deadsoftware/cavedroid/CaveGame.java
core/src/ru/deadsoftware/cavedroid/MainComponent.java
core/src/ru/deadsoftware/cavedroid/MainConfig.java
core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt
core/src/ru/deadsoftware/cavedroid/menu/MenuProc.java
core/src/ru/deadsoftware/cavedroid/menu/objects/BooleanOptionButton.kt [new file with mode: 0644]
core/src/ru/deadsoftware/cavedroid/menu/submenus/Menu.java
core/src/ru/deadsoftware/cavedroid/menu/submenus/MenuOptions.kt
core/src/ru/deadsoftware/cavedroid/prefs/PreferencesStore.kt [new file with mode: 0644]
desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopLauncher.java
desktop/src/ru/deadsoftware/cavedroid/desktop/DesktopPreferencesStore.kt [new file with mode: 0644]

index ebe1bf7561612f5d43bd23d80928d5366439cbf3..bb956cdfbe296d13fe50b7fb60e408f872317d90 100644 (file)
@@ -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"
index e7aad50df8c3df8deab19206bf22d5fee456f3ef..3f38ad401d37bd40cefdf1f78b1aeddb04254d6a 100644 (file)
@@ -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 (file)
index 0000000..4b16659
--- /dev/null
@@ -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
index 934055296938f3a4e2eb2533fbf1649fd6ce9893..9ca34b8e0507a5a42523accf769469847185661a 100644 (file)
@@ -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) {
index c640fb6c2abae2e5b5d12bc4574622419ab2e9b1..b487c6ddafef2901801f1cdd44855f46a45c8fe1 100644 (file)
@@ -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();
 
index 64950f2d43e17325d3afd348d073c066ae989088..3ffb506285028aada2dd994cc104f772fc4ff59d 100644 (file)
@@ -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<String, String> 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);
     }
 }
index 585a5ab09d181a62cb0ff1767664118282c4047c..454337eefb744f6f8a4803283299ddd28a2e694a 100644 (file)
@@ -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
index 5314809e4d483deb763b266c7158df91487e91a9..aa3888a5b0c26181b38f1102694b8344e6ba7b9b 100644 (file)
@@ -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 (file)
index 0000000..56329d5
--- /dev/null
@@ -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
index 587d0f622ebbc5df347d482734e75996bc006c3a..7e793b7b1db1d77a21a85dbb2faf30e4437974bd 100644 (file)
@@ -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);
         }
     }
 
index 2b72bd621f474cb094905982a1ac4d70fc0905ac..7cc8a9021a855ebbdf8d0e8cc1c21f136e852fda 100644 (file)
@@ -17,7 +17,6 @@ class MenuOptions(
 
     override fun getButtonEventListeners(): HashMap<String, ButtonEventListener> {
         val map = HashMap<String, ButtonEventListener>()
-        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 (file)
index 0000000..edc9517
--- /dev/null
@@ -0,0 +1,9 @@
+package ru.deadsoftware.cavedroid.prefs
+
+interface PreferencesStore {
+
+    fun getPreference(key: String): String?
+
+    fun setPreference(key: String, value: String?)
+
+}
index fe78235dd8fe5bc0ec937561b82ae1a9b4f6e87e..146d52a467a709edcb210841374ea45337ae7185 100644 (file)
@@ -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 (file)
index 0000000..03591bb
--- /dev/null
@@ -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