DEADSOFTWARE

New items data structure
authorfredboy <fredboy@protonmail.com>
Sat, 20 Apr 2024 09:48:42 +0000 (16:48 +0700)
committerfredboy <fredboy@protonmail.com>
Sat, 20 Apr 2024 09:48:42 +0000 (16:48 +0700)
22 files changed:
android/assets/json/game_items.json
core/src/ru/deadsoftware/cavedroid/game/GameComponent.java
core/src/ru/deadsoftware/cavedroid/game/GameInput.java
core/src/ru/deadsoftware/cavedroid/game/GameItems.java
core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java
core/src/ru/deadsoftware/cavedroid/game/actions/CommonBlockActionUtils.kt
core/src/ru/deadsoftware/cavedroid/game/actions/PlaceBlockActionsModule.kt [new file with mode: 0644]
core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt
core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/IPlaceBlockAction.kt [new file with mode: 0644]
core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToBackgroundAction.kt [new file with mode: 0644]
core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToForegroundAction.kt [new file with mode: 0644]
core/src/ru/deadsoftware/cavedroid/game/actions/useitem/IUseItemAction.kt
core/src/ru/deadsoftware/cavedroid/game/actions/useitem/PlaceBlockItemToBackgroundAction.kt [deleted file]
core/src/ru/deadsoftware/cavedroid/game/actions/useitem/PlaceBlockItemToForegroundAction.kt [deleted file]
core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseLavaBucketAction.kt
core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UseWaterBucketAction.kt
core/src/ru/deadsoftware/cavedroid/game/mobs/Player.java
core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt
core/src/ru/deadsoftware/cavedroid/game/model/block/CommonBlockParams.kt
core/src/ru/deadsoftware/cavedroid/game/model/item/CommonItemParams.kt [new file with mode: 0644]
core/src/ru/deadsoftware/cavedroid/game/model/item/Item.kt [new file with mode: 0644]
core/src/ru/deadsoftware/cavedroid/game/objects/Item.kt [deleted file]

index 48b612fa88543a925313c8310f3a5290cd41408e..cd2fae927034f94013c763bb11fa7f36e4770be5 100644 (file)
       "id": 66,
       "name": "Empty Bucket",
       "origin_x": 0.25,
-      "type": "bucket"
+      "type": "bucket",
+      "action_key": "use_empty_bucket"
     },
     "bucket_lava": {
       "id": 68,
       "id": 64,
       "name": "Diamond Shovel",
       "origin_x": 0.125,
-      "type": "tool"
+      "type": "shovel"
     },
     "diamond_sword": {
       "id": 59,
       "name": "Diamond Sword",
       "origin_x": 0.125,
-      "type": "tool"
+      "type": "sword"
     },
     "dirt": {
       "id": 3,
       "id": 65,
       "name": "Golden Shovel",
       "origin_x": 0.125,
-      "type": "tool"
+      "type": "shovel"
     },
     "gold_sword": {
       "id": 60,
       "name": "Golden Sword",
       "origin_x": 0.125,
-      "type": "tool"
+      "type": "sword"
     },
     "grass": {
       "id": 2,
       "id": 63,
       "name": "Iron Shovel",
       "origin_x": 0.125,
-      "type": "tool"
+      "type": "shovel"
     },
     "iron_sword": {
       "id": 58,
       "name": "Iron Sword",
       "origin_x": 0.125,
-      "type": "tool"
+      "type": "sword"
     },
     "lapis_block": {
       "id": 19,
       "id": 62,
       "name": "Stone Shovel",
       "origin_x": 0.125,
-      "type": "tool"
+      "type": "shovel"
     },
     "stone_slab": {
       "id": 47,
       "id": 57,
       "name": "Stone Sword",
       "origin_x": 0.125,
-      "type": "tool"
+      "type": "sword"
     },
     "stonebrick": {
       "id": 52,
       "id": 61,
       "name": "Wooden Shovel",
       "origin_x": 0.125,
-      "type": "tool"
+      "type": "shovel"
     },
     "wood_sword": {
       "id": 56,
       "name": "Wooden Sword",
       "origin_x": 0.125,
-      "type": "tool"
+      "type": "sword"
     },
     "wool_colored_black": {
       "id": 44,
index 81f4b88d9f52571677dd22e608127a214ea0ce68..a0562ce3dcec25b5cfa17e516ecf20c5c502c783 100644 (file)
@@ -2,11 +2,12 @@ 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.UseItemActionsModule;
 
 @GameScope
-@Component(dependencies = MainComponent.class, modules = { GameModule.class, UseItemActionsModule.class, UpdateBlockActionsModule.class })
+@Component(dependencies = MainComponent.class, modules = {GameModule.class, UseItemActionsModule.class, UpdateBlockActionsModule.class, PlaceBlockActionsModule.class})
 public interface GameComponent {
     GameProc getGameProc();
 
index 17d6ad1ac758820a32f02f1fdedbac58c612f39d..fd225742fadbe16affe54246965bb40c9cff9e0d 100644 (file)
@@ -9,13 +9,14 @@ import com.badlogic.gdx.utils.TimeUtils;
 import com.google.common.collect.Range;
 import ru.deadsoftware.cavedroid.MainConfig;
 import ru.deadsoftware.cavedroid.game.actions.CommonBlockActionUtilsKt;
+import ru.deadsoftware.cavedroid.game.actions.placeblock.IPlaceBlockAction;
 import ru.deadsoftware.cavedroid.game.actions.useitem.IUseItemAction;
 import ru.deadsoftware.cavedroid.game.mobs.Mob;
 import ru.deadsoftware.cavedroid.game.mobs.MobsController;
 import ru.deadsoftware.cavedroid.game.mobs.Pig;
 import ru.deadsoftware.cavedroid.game.mobs.Player;
+import ru.deadsoftware.cavedroid.game.model.item.Item;
 import ru.deadsoftware.cavedroid.game.objects.DropController;
-import ru.deadsoftware.cavedroid.game.objects.Item;
 import ru.deadsoftware.cavedroid.game.world.GameWorld;
 import ru.deadsoftware.cavedroid.misc.Assets;
 import ru.deadsoftware.cavedroid.misc.ControlMode;
@@ -37,6 +38,7 @@ public class GameInput {
     private final DropController mDropController;
     private final MobsController mMobsController;
     private final Map<String, IUseItemAction> mUseItemActionMap;
+    private final Map<String, IPlaceBlockAction> mPlaceBlockActionMap;
 
     private final Player mPlayer;
 
@@ -62,12 +64,14 @@ public class GameInput {
                      GameWorld gameWorld,
                      DropController dropController,
                      MobsController mobsController,
-                     Map<String, IUseItemAction> useItemActionMap) {
+                     Map<String, IUseItemAction> useItemActionMap,
+                     Map<String, IPlaceBlockAction> placeBlockActionMap) {
         mMainConfig = mainConfig;
         mGameWorld = gameWorld;
         mDropController = dropController;
         mMobsController = mobsController;
         mUseItemActionMap = useItemActionMap;
+        mPlaceBlockActionMap = placeBlockActionMap;
 
         mPlayer = mMobsController.getPlayer();
 
@@ -209,20 +213,21 @@ public class GameInput {
 
         if (id > 0) {
             final Item item = getItem(id);
-            @CheckForNull final String actionKey = item.getActionKey();
-            if (item.isBlock()) {
+
+            if (item instanceof Item.Placeable) {
                 if (!bg) {
-                    CommonBlockActionUtilsKt.placeToForegroundAction(mUseItemActionMap, item, x, y);
+                    CommonBlockActionUtilsKt.placeToForegroundAction(mPlaceBlockActionMap, (Item.Placeable) item, x, y);
                 } else {
-                    CommonBlockActionUtilsKt.placeToBackgroundAction(mUseItemActionMap, item, x, y);
+                    CommonBlockActionUtilsKt.placeToBackgroundAction(mPlaceBlockActionMap, (Item.Placeable) item, x, y);
                 }
-            } else if (actionKey != null) {
+            } else if (item instanceof Item.Usable) {
+                final String actionKey = ((Item.Usable)item).getUseActionKey();
                 final IUseItemAction useItemAction = mUseItemActionMap.get(actionKey);
 
                 if (useItemAction != null) {
-                    useItemAction.perform(item, x, y);
+                    useItemAction.perform((Item.Usable) item, x, y);
                 } else {
-                    Gdx.app.error(TAG, "use item action " + actionKey + "not found");
+                    Gdx.app.error(TAG, "use item action " + actionKey + " not found");
                 }
             }
         }
index 8392efdb786602ca0e874d11ce185895ca74c494..7cf525263a52dec4c252f87d6e91129b45ada223 100644 (file)
@@ -8,7 +8,8 @@ import com.badlogic.gdx.utils.ArrayMap;
 import com.badlogic.gdx.utils.GdxRuntimeException;
 import com.badlogic.gdx.utils.JsonValue;
 import ru.deadsoftware.cavedroid.game.model.block.*;
-import ru.deadsoftware.cavedroid.game.objects.Item;
+import ru.deadsoftware.cavedroid.game.model.item.CommonItemParams;
+import ru.deadsoftware.cavedroid.game.model.item.Item;
 import ru.deadsoftware.cavedroid.misc.Assets;
 import ru.deadsoftware.cavedroid.misc.utils.AssetLoader;
 import ru.deadsoftware.cavedroid.misc.utils.SpriteOrigin;
@@ -111,15 +112,11 @@ public class GameItems {
         return getBlock(id).getTexture();
     }
 
-    public static Sprite getItemTex(int id) {
-        return items.getValueAt(id).getType().equals("block") ? getBlockTex(id) : getItem(id).getTexture();
-    }
-
     public static void load(AssetLoader assetLoader) {
         JsonValue json = Assets.jsonReader.parse(assetLoader.getAssetHandle("json/game_items.json"));
 
         TreeSet<Block> blocksSet = new TreeSet<>(Comparator.comparingInt(a -> a.getParams().getId()));
-        TreeSet<Item> itemsSet = new TreeSet<>(Comparator.comparingInt(Item::getId));
+        TreeSet<Item> itemsSet = new TreeSet<>(Comparator.comparingInt(a -> a.getParams().getId()));
 
 
         int count = 0;
@@ -193,6 +190,8 @@ public class GameItems {
             }
         }
 
+        blocksSet.forEach((block -> blocks.put(block.getParams().getKey(), block)));
+
         count = 0;
         for (JsonValue item = json.get("items").child(); item != null; item = item.next()) {
             try {
@@ -203,6 +202,10 @@ public class GameItems {
                 Sprite sprite = type.equals("block") ? null :
                         new Sprite(new Texture(assetLoader.getAssetHandle("textures/items/" + texture + ".png")));
 
+                if (sprite != null) {
+                    sprite.flip(false, true);
+                }
+
                 float originX = Assets.getFloatFromJson(item, "origin_x", 0f);
                 float originY = Assets.getFloatFromJson(item, "origin_y", 1f);
                 originX = MathUtils.clamp(originX, 0f, 1f);
@@ -213,19 +216,31 @@ public class GameItems {
 
                 String actionKey = Assets.getStringFromJson(item, "action_key", null);
 
+                float mobDamage = Assets.getFloatFromJson(item, "mob_damage_multiplier", 1f);
+                float blockDamage = Assets.getFloatFromJson(item, "block_damage_multiplier", 1f);
+
                 if (count >= id) {
                     count++;
                 }
 
+                CommonItemParams params = new CommonItemParams(id, key, name, origin);
+
+                Item newItem = switch (type) {
+                    case "bucket" -> new Item.Bucket(params, sprite, actionKey);
+                    case "shovel" -> new Item.Shovel(params, sprite, mobDamage, blockDamage);
+                    case "sword" -> new Item.Sword(params, sprite, mobDamage, blockDamage);
+                    case "block" -> new Item.Placeable(params, blocks.get(key));
+                    default -> throw new RuntimeException("Unknown item type: " + type);
+                };
+
                 itemsIds.put(key, id);
-                itemsSet.add(new Item(id, key, name, type, sprite, origin, actionKey));
+                itemsSet.add(newItem);
             } catch (GdxRuntimeException e) {
                 Gdx.app.error(TAG, e.getMessage());
             }
         }
 
-        blocksSet.forEach((block -> blocks.put(block.getParams().getKey(), block)));
-        itemsSet.forEach((item -> items.put(item.getKey(), item)));
+        itemsSet.forEach((item -> items.put(item.getParams().getKey(), item)));
     }
 
 }
\ No newline at end of file
index 06e9b624fae8fd2570fae96e342eeb8fe0e2e646..dd136b8aa2a75aba3bcdf11c3e3422b854f9f8f0 100644 (file)
@@ -9,20 +9,17 @@ import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
 import com.badlogic.gdx.math.Intersector;
 import com.badlogic.gdx.math.MathUtils;
 import com.badlogic.gdx.math.Rectangle;
-import com.badlogic.gdx.math.Vector2;
-import com.badlogic.gdx.scenes.scene2d.utils.ScissorStack;
 import ru.deadsoftware.cavedroid.MainConfig;
 import ru.deadsoftware.cavedroid.game.mobs.Mob;
 import ru.deadsoftware.cavedroid.game.mobs.MobsController;
 import ru.deadsoftware.cavedroid.game.mobs.Player;
 import ru.deadsoftware.cavedroid.game.model.block.Block;
+import ru.deadsoftware.cavedroid.game.model.item.Item;
 import ru.deadsoftware.cavedroid.game.objects.Drop;
 import ru.deadsoftware.cavedroid.game.objects.DropController;
-import ru.deadsoftware.cavedroid.game.objects.Item;
 import ru.deadsoftware.cavedroid.game.world.GameWorld;
 import ru.deadsoftware.cavedroid.misc.ControlMode;
 import ru.deadsoftware.cavedroid.misc.Renderer;
-import ru.deadsoftware.cavedroid.misc.utils.SpriteUtilsKt;
 
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
@@ -187,14 +184,7 @@ public class GameRenderer extends Renderer {
         }
 
         final Item item = GameItems.getItem(drop.getId());
-        @CheckForNull final Block block = GameItems.getBlock(GameItems.getItemKey(drop.getId()));
-        @CheckForNull final Sprite sprite = item.isBlock()
-                ? block.getTexture()
-                : item.getSprite();
-
-        if (sprite == null) {
-            return;
-        }
+        final Sprite sprite = item.getSprite();
 
         sprite.setPosition(drawingRect.x, drawingRect.y);
         sprite.setSize(drawingRect.width, drawingRect.height);
@@ -211,26 +201,15 @@ public class GameRenderer extends Renderer {
                 y + 18 + (mGameInput.getCreativeScroll() * (72f / GameProc.MAX_CREATIVE_SCROLL)));
         for (int i = mGameInput.getCreativeScroll() * 8; i < mGameInput.getCreativeScroll() * 8 + 40; i++) {
             if (i > 0 && i < GameItems.getItemsSize()) {
-                if (GameItems.getItem(i).isBlock()) {
-                    spriter.draw(GameItems.getBlock(GameItems.getBlockIdByItemId(i)).getTexture(),
-                            x + 8 + ((i - mGameInput.getCreativeScroll() * 8) % 8) * 18,
-                            y + 18 + ((i - mGameInput.getCreativeScroll() * 8) / 8) * 18);
-                } else {
-                    spriter.draw(GameItems.getItem(i).getTexture(),
-                            x + 8 + ((i - mGameInput.getCreativeScroll() * 8) % 8) * 18,
-                            y + 18 + ((i - mGameInput.getCreativeScroll() * 8) / 8) * 18);
-                }
+                spriter.draw(GameItems.getItem(i).getSprite(),
+                        x + 8 + ((i - mGameInput.getCreativeScroll() * 8) % 8) * 18,
+                        y + 18 + ((i - mGameInput.getCreativeScroll() * 8) / 8) * 18);
             }
         }
         for (int i = 0; i < 9; i++) {
             if (mMobsController.getPlayer().inventory[i] > 0) {
-                if (GameItems.getItem(mMobsController.getPlayer().inventory[i]).isBlock()) {
-                    spriter.draw(GameItems.getBlock(GameItems.getBlockIdByItemId(mMobsController.getPlayer().inventory[i])).getTexture(),
-                            x + 8 + i * 18, y + creative.getRegionHeight() - 24);
-                } else {
-                    spriter.draw(GameItems.getItem(mMobsController.getPlayer().inventory[i]).getTexture(),
-                            x + 8 + i * 18, y + creative.getRegionHeight() - 24);
-                }
+                spriter.draw(GameItems.getItem(mMobsController.getPlayer().inventory[i]).getSprite(),
+                        x + 8 + i * 18, y + creative.getRegionHeight() - 24);
             }
         }
 
@@ -274,15 +253,9 @@ public class GameRenderer extends Renderer {
 
         for (int i = 0; i < 9; i++) {
             if (mMobsController.getPlayer().inventory[i] > 0) {
-                if (GameItems.getItem(mMobsController.getPlayer().inventory[i]).isBlock()) {
-                    spriter.draw(GameItems.getBlock(GameItems.getBlockIdByItemId(mMobsController.getPlayer().inventory[i])).getTexture(),
-                            getWidth() / 2 - (float) hotbar.getRegionWidth() / 2 + 3 + i * 20,
-                            3);
-                } else {
-                    spriter.draw(GameItems.getItem(mMobsController.getPlayer().inventory[i]).getTexture(),
-                            getWidth() / 2 - (float) hotbar.getRegionWidth() / 2 + 3 + i * 20,
-                            3);
-                }
+                spriter.draw(GameItems.getItem(mMobsController.getPlayer().inventory[i]).getSprite(),
+                        getWidth() / 2 - (float) hotbar.getRegionWidth() / 2 + 3 + i * 20,
+                        3);
             }
         }
         spriter.draw(hotbarSelector,
@@ -306,7 +279,9 @@ public class GameRenderer extends Renderer {
 
         drawWorld(true);
         player.draw(spriter, player.getX() - getCamX() - player.getWidth() / 2, player.getY() - getCamY(), delta);
-        mMobsController.getMobs().forEach( (mob) -> { drawMob(mob, delta); });
+        mMobsController.getMobs().forEach((mob) -> {
+            drawMob(mob, delta);
+        });
         mDropController.forEach(this::drawDrop);
         drawWorld(false);
         drawGUI();
@@ -354,8 +329,7 @@ public class GameRenderer extends Renderer {
                 final int worldX = (int) (mMobsController.getPlayer().getMapX() - size / 2 + x);
                 final int worldY = (int) (mMobsController.getPlayer().getUpperMapY() - size / 2 + y);
 
-                @Nullable
-                final Color color = getMinimapColor(worldX, worldY);
+                @Nullable final Color color = getMinimapColor(worldX, worldY);
 
                 if (color != null) {
                     shaper.setColor(color);
index 43094309395f70e094031f760a0957e458c4ccef..2803ef04e9fbcf21cd9b13a6a8d3f4e991727e1a 100644 (file)
@@ -1,22 +1,22 @@
 package ru.deadsoftware.cavedroid.game.actions
 
 import com.badlogic.gdx.Gdx
+import ru.deadsoftware.cavedroid.game.actions.placeblock.IPlaceBlockAction
 import ru.deadsoftware.cavedroid.game.actions.updateblock.IUpdateBlockAction
 import ru.deadsoftware.cavedroid.game.actions.updateblock.UpdateRequiresBlockAction
-import ru.deadsoftware.cavedroid.game.actions.useitem.IUseItemAction
-import ru.deadsoftware.cavedroid.game.actions.useitem.PlaceBlockItemToBackgroundAction
-import ru.deadsoftware.cavedroid.game.actions.useitem.PlaceBlockItemToForegroundAction
-import ru.deadsoftware.cavedroid.game.objects.Item
+import ru.deadsoftware.cavedroid.game.actions.placeblock.PlaceBlockItemToBackgroundAction
+import ru.deadsoftware.cavedroid.game.actions.placeblock.PlaceBlockItemToForegroundAction
+import ru.deadsoftware.cavedroid.game.model.item.Item
 
 private const val TAG = "PlaceBlockActionUtils"
 
-fun Map<String, IUseItemAction>.placeToForegroundAction(item: Item, x: Int, y: Int) {
-    get(PlaceBlockItemToForegroundAction.ACTION_KEY)?.perform(item, x, y)
+fun Map<String, IPlaceBlockAction>.placeToForegroundAction(item: Item.Placeable, x: Int, y: Int) {
+    get(PlaceBlockItemToForegroundAction.ACTION_KEY)?.place(item, x, y)
         ?: Gdx.app.error(TAG, "action place_foreground_block not found")
 }
 
-fun Map<String, IUseItemAction>.placeToBackgroundAction(item: Item, x: Int, y: Int) {
-    get(PlaceBlockItemToBackgroundAction.ACTION_KEY)?.perform(item, x, y)
+fun Map<String, IPlaceBlockAction>.placeToBackgroundAction(item: Item.Placeable, x: Int, y: Int) {
+    get(PlaceBlockItemToBackgroundAction.ACTION_KEY)?.place(item, x, y)
         ?: Gdx.app.error(TAG, "action place_background_block not found")
 }
 
diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/PlaceBlockActionsModule.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/PlaceBlockActionsModule.kt
new file mode 100644 (file)
index 0000000..23f711a
--- /dev/null
@@ -0,0 +1,31 @@
+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
+
+@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
+    }
+
+}
\ No newline at end of file
index a54e4a77e31403e9e2f7c1583221af2a8ddf42f3..aeb64f07459a966917b08ea3ba7a24ff92f7149e 100644 (file)
@@ -26,21 +26,4 @@ class UseItemActionsModule {
         return action
     }
 
-    @Binds
-    @IntoMap
-    @StringKey(PlaceBlockItemToForegroundAction.ACTION_KEY)
-    @GameScope
-    fun bindPlaceBlockItemToForegroundAction(action: PlaceBlockItemToForegroundAction): IUseItemAction {
-        return action
-    }
-
-    @Binds
-    @IntoMap
-    @StringKey(PlaceBlockItemToBackgroundAction.ACTION_KEY)
-    @GameScope
-    fun bindPlaceBlockItemToBackgroundAction(action: PlaceBlockItemToBackgroundAction): 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
new file mode 100644 (file)
index 0000000..06c70c4
--- /dev/null
@@ -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/PlaceBlockItemToBackgroundAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToBackgroundAction.kt
new file mode 100644 (file)
index 0000000..dd61e0b
--- /dev/null
@@ -0,0 +1,21 @@
+package ru.deadsoftware.cavedroid.game.actions.placeblock
+
+import ru.deadsoftware.cavedroid.game.GameScope
+import ru.deadsoftware.cavedroid.game.model.item.Item
+import ru.deadsoftware.cavedroid.game.world.GameWorld
+import javax.inject.Inject
+
+@GameScope
+class PlaceBlockItemToBackgroundAction @Inject constructor(
+    private val gameWorld: GameWorld,
+) : IPlaceBlockAction {
+
+    override fun place(item: Item.Placeable, x: Int, y: Int) {
+        gameWorld.placeToBackground(x, y, item.block.params.id)
+    }
+
+    companion object {
+        const val ACTION_KEY = "place_background_block"
+    }
+
+}
diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToForegroundAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/placeblock/PlaceBlockItemToForegroundAction.kt
new file mode 100644 (file)
index 0000000..75c7bcb
--- /dev/null
@@ -0,0 +1,21 @@
+package ru.deadsoftware.cavedroid.game.actions.placeblock
+
+import ru.deadsoftware.cavedroid.game.GameScope
+import ru.deadsoftware.cavedroid.game.model.item.Item
+import ru.deadsoftware.cavedroid.game.world.GameWorld
+import javax.inject.Inject
+
+@GameScope
+class PlaceBlockItemToForegroundAction @Inject constructor(
+    private val gameWorld: GameWorld,
+) : IPlaceBlockAction {
+
+    override fun place(item: Item.Placeable, x: Int, y: Int) {
+        gameWorld.placeToForeground(x, y, item.block.params.id)
+    }
+
+    companion object {
+        const val ACTION_KEY = "place_foreground_block"
+    }
+
+}
index 809055a94fa3f6335b78c4862f3428a3fa336b98..d963aeedb187e0be94b527608ece434ce807f050 100644 (file)
@@ -1,9 +1,9 @@
 package ru.deadsoftware.cavedroid.game.actions.useitem
 
-import ru.deadsoftware.cavedroid.game.objects.Item
+import ru.deadsoftware.cavedroid.game.model.item.Item
 
 interface IUseItemAction {
 
-    fun perform(item: Item, x: Int, y: Int)
+    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/PlaceBlockItemToBackgroundAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/PlaceBlockItemToBackgroundAction.kt
deleted file mode 100644 (file)
index e4af8df..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-package ru.deadsoftware.cavedroid.game.actions.useitem
-
-import ru.deadsoftware.cavedroid.game.GameScope
-import ru.deadsoftware.cavedroid.game.objects.Item
-import ru.deadsoftware.cavedroid.game.world.GameWorld
-import javax.inject.Inject
-
-@GameScope
-class PlaceBlockItemToBackgroundAction @Inject constructor(
-    private val gameWorld: GameWorld,
-) : IUseItemAction {
-
-    override fun perform(item: Item, x: Int, y: Int) {
-        val block = item.toBlock()
-        requireNotNull(block) { "error: trying to place non block item" }
-        gameWorld.placeToBackground(x, y, block.params.id)
-    }
-
-    companion object {
-        const val ACTION_KEY = "place_background_block"
-    }
-
-}
diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/PlaceBlockItemToForegroundAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/PlaceBlockItemToForegroundAction.kt
deleted file mode 100644 (file)
index 978eb00..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-package ru.deadsoftware.cavedroid.game.actions.useitem
-
-import ru.deadsoftware.cavedroid.game.GameScope
-import ru.deadsoftware.cavedroid.game.objects.Item
-import ru.deadsoftware.cavedroid.game.world.GameWorld
-import javax.inject.Inject
-
-@GameScope
-class PlaceBlockItemToForegroundAction @Inject constructor(
-    private val gameWorld: GameWorld,
-) : IUseItemAction {
-
-    override fun perform(item: Item, x: Int, y: Int) {
-        val block = item.toBlock()
-        requireNotNull(block) { "error: trying to place non block item" }
-        gameWorld.placeToForeground(x, y, block.params.id)
-    }
-
-    companion object {
-        const val ACTION_KEY = "place_foreground_block"
-    }
-
-}
index f9e09f52cbc46717ab8164dc1723a4641400884b..0bbc0429c0df8e1c1635076d87d0b2ad737ad46f 100644 (file)
@@ -3,7 +3,7 @@ package ru.deadsoftware.cavedroid.game.actions.useitem
 import ru.deadsoftware.cavedroid.game.GameItems
 import ru.deadsoftware.cavedroid.game.GameScope
 import ru.deadsoftware.cavedroid.game.mobs.MobsController
-import ru.deadsoftware.cavedroid.game.objects.Item
+import ru.deadsoftware.cavedroid.game.model.item.Item
 import ru.deadsoftware.cavedroid.game.world.GameWorld
 import javax.inject.Inject
 
@@ -13,7 +13,7 @@ class UseLavaBucketAction @Inject constructor(
     private val mobsController: MobsController,
 ) : IUseItemAction {
 
-    override fun perform(item: Item, x: Int, y: Int) {
+    override fun perform(item: Item.Usable, x: Int, y: Int) {
         gameWorld.placeToForeground(x, y, GameItems.getBlockId("lava"))
         mobsController.player.setCurrentInventorySlotItem(GameItems.getItemId("bucket_empty"))
     }
index fecb77f51f0cf98db42187684a11b1758cac7f49..9668c4aa7fc4d90775f0f2079ac3d02af5d9cda0 100644 (file)
@@ -3,7 +3,7 @@ package ru.deadsoftware.cavedroid.game.actions.useitem
 import ru.deadsoftware.cavedroid.game.GameItems
 import ru.deadsoftware.cavedroid.game.GameScope
 import ru.deadsoftware.cavedroid.game.mobs.MobsController
-import ru.deadsoftware.cavedroid.game.objects.Item
+import ru.deadsoftware.cavedroid.game.model.item.Item
 import ru.deadsoftware.cavedroid.game.world.GameWorld
 import javax.inject.Inject
 
@@ -13,7 +13,7 @@ class UseWaterBucketAction @Inject constructor(
     private val mobsController: MobsController,
 ) : IUseItemAction {
 
-    override fun perform(item: Item, x: Int, y: Int) {
+    override fun perform(item: Item.Usable, x: Int, y: Int) {
         gameWorld.placeToForeground(x, y, GameItems.getBlockId("water"))
         mobsController.player.setCurrentInventorySlotItem(GameItems.getItemId("bucket_empty"))
     }
index 70013367928b170cd8296542983c7780f2879b84..6563fd9f7cdace58920e325301815b9577087c2c 100644 (file)
@@ -5,8 +5,8 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch;
 import com.badlogic.gdx.math.MathUtils;
 import com.badlogic.gdx.math.Vector2;
 import ru.deadsoftware.cavedroid.game.GameItems;
+import ru.deadsoftware.cavedroid.game.model.item.Item;
 import ru.deadsoftware.cavedroid.game.objects.Drop;
-import ru.deadsoftware.cavedroid.game.objects.Item;
 import ru.deadsoftware.cavedroid.game.world.GameWorld;
 import ru.deadsoftware.cavedroid.misc.Assets;
 import ru.deadsoftware.cavedroid.misc.utils.SpriteOrigin;
@@ -116,23 +116,21 @@ public class Player extends Mob {
 
     private void drawItem(SpriteBatch spriteBatch, float x, float y, float anim) {
         final int itemId = inventory[slot];
-        final Item item = GameItems.getItem(itemId);
-
-        @CheckForNull final Sprite sprite = item.isBlock()
-                ? item.toBlock().getTexture()
-                : item.getSprite();
 
-        if (sprite == null) {
+        if (itemId == 0) {
             return;
         }
 
+        final Item item = GameItems.getItem(itemId);
+        final Sprite sprite = item.getSprite();
+
         if (!item.isTool()) {
             sprite.setSize(Drop.DROP_SIZE, Drop.DROP_SIZE);
         }
 
         final float handLength = Assets.playerSprite[0][2].getHeight();
 
-        final SpriteOrigin spriteOrigin = item.getDefaultOrigin();
+        final SpriteOrigin spriteOrigin = item.getParams().getInHandSpriteOrigin();
         final int handMultiplier = -getDirection().getBasis();
         final float xOffset = (-1 + getDirection().getIndex()) * sprite.getWidth() + 4 + handMultiplier * (sprite.getWidth() * spriteOrigin.getX());
         final float yOffset = item.isTool() ? -sprite.getHeight() / 2 : 0;
index 440d258eb94bbb832df8bedd9e060c3661382079..62c6f493e0f8d66221bc54d1a297dc506a28f688 100644 (file)
@@ -20,11 +20,14 @@ sealed class Block {
 
     private var animation: Array<Sprite>? = null
 
-    private var sprite: Sprite? = null
+    private var _sprite: Sprite? = null
         get() {
             return animation?.get(currentAnimationFrame) ?: field
         }
 
+    val sprite: Sprite
+        get() = requireNotNull(_sprite)
+
     private val currentAnimationFrame: Int
         get() {
             return params.animationInfo?.let { animInfo ->
@@ -50,7 +53,7 @@ sealed class Block {
     }
 
     private fun initSprite() {
-        sprite = animation?.get(0) ?: params.texture?.let { tex ->
+        _sprite = animation?.get(0) ?: params.texture?.let { tex ->
             val width = 16 - params.spriteMargins.left - params.spriteMargins.right
             val height = 16 - params.spriteMargins.top - params.spriteMargins.bottom
             Sprite(tex, params.spriteMargins.left, params.spriteMargins.top, width, height)
@@ -61,7 +64,7 @@ sealed class Block {
     fun requireSprite() = requireNotNull(sprite)
 
     fun draw(spriter: SpriteBatch, x: Float, y: Float) {
-        sprite?.apply {
+        sprite.apply {
             setBounds(
                 /* x = */ x + params.spriteMargins.left,
                 /* y = */ y + params.spriteMargins.top,
@@ -112,7 +115,7 @@ sealed class Block {
         val fullBlockKey: String,
     ): Block()
 
-    abstract class Fluid: Block() {
+    sealed class Fluid: Block() {
         abstract val statesCount: Int
     }
     
index 2f4de93213925d17a66959b7e377b758663822f2..1c9c5105560280708fe7988b8b8c4589e969ebb6 100644 (file)
@@ -3,7 +3,7 @@ package ru.deadsoftware.cavedroid.game.model.block
 import com.badlogic.gdx.graphics.Texture
 
 data class CommonBlockParams(
-    @Deprecated(ID_DEPRECATION_MESSAGE) val id: Int,
+    @Deprecated("numeric id's will be removed") val id: Int,
     val key: String,
     val collisionMargins: BlockMargins,
     val hitPoints: Int,
@@ -15,8 +15,4 @@ data class CommonBlockParams(
     val animationInfo: BlockAnimationInfo?,
     val texture: Texture?,
     val spriteMargins: BlockMargins,
-) {
-    companion object {
-        private const val ID_DEPRECATION_MESSAGE = "numeric id's will be removed"
-    }
-}
+)
diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/item/CommonItemParams.kt b/core/src/ru/deadsoftware/cavedroid/game/model/item/CommonItemParams.kt
new file mode 100644 (file)
index 0000000..57480c8
--- /dev/null
@@ -0,0 +1,10 @@
+package ru.deadsoftware.cavedroid.game.model.item
+
+import ru.deadsoftware.cavedroid.misc.utils.SpriteOrigin
+
+data class CommonItemParams(
+    @Deprecated("numeric id's will be removed") val id: Int,
+    val key: String,
+    val name: String,
+    val inHandSpriteOrigin: SpriteOrigin,
+)
\ No newline at end of file
diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/item/Item.kt b/core/src/ru/deadsoftware/cavedroid/game/model/item/Item.kt
new file mode 100644 (file)
index 0000000..42dae7e
--- /dev/null
@@ -0,0 +1,65 @@
+package ru.deadsoftware.cavedroid.game.model.item
+
+import com.badlogic.gdx.graphics.g2d.Sprite
+import ru.deadsoftware.cavedroid.game.model.block.Block
+import kotlin.contracts.ExperimentalContracts
+import kotlin.contracts.contract
+
+@OptIn(ExperimentalContracts::class)
+sealed class Item {
+
+    abstract val params: CommonItemParams
+    abstract val sprite: Sprite
+
+    fun isPlaceable(): Boolean {
+        contract { returns(true) implies (this@Item is Placeable) }
+        return this is Placeable
+    }
+
+    fun isTool(): Boolean {
+        contract { returns(true) implies (this@Item is Tool) }
+        return this is Tool
+    }
+
+    fun isUsable(): Boolean {
+        contract { returns(true) implies (this@Item is Placeable) }
+        return this is Placeable
+    }
+    
+    sealed class Tool : Item() {
+        abstract val mobDamageMultiplier: Float
+        abstract val blockDamageMultiplier: Float
+    }
+
+    sealed class Usable : Item() {
+        abstract val useActionKey: String
+    }
+    
+    data class Placeable(
+        override val params: CommonItemParams,
+        val block: Block
+    ) : Item() {
+        override val sprite: Sprite get() = block.sprite
+    }
+    
+    data class Sword(
+        override val params: CommonItemParams,
+        override val sprite: Sprite,
+        override val mobDamageMultiplier: Float,
+        override val blockDamageMultiplier: Float,
+    ) : Tool()
+
+    data class Shovel(
+        override val params: CommonItemParams,
+        override val sprite: Sprite,
+        override val mobDamageMultiplier: Float,
+        override val blockDamageMultiplier: Float,
+    ) : Tool()
+    
+    data class Bucket(
+        override val params: CommonItemParams,
+        override val sprite: Sprite,
+        override val useActionKey: String
+    ) : Usable()
+
+}
\ No newline at end of file
diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/Item.kt b/core/src/ru/deadsoftware/cavedroid/game/objects/Item.kt
deleted file mode 100644 (file)
index a2dbfc5..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-package ru.deadsoftware.cavedroid.game.objects
-
-import com.badlogic.gdx.graphics.g2d.Sprite
-import ru.deadsoftware.cavedroid.game.GameItems
-import ru.deadsoftware.cavedroid.game.model.block.Block
-import ru.deadsoftware.cavedroid.misc.utils.SpriteOrigin
-
-data class Item(
-    val id: Int,
-    val key: String,
-    val name: String,
-    val type: String,
-    val sprite: Sprite?,
-    val defaultOrigin: SpriteOrigin,
-    val actionKey: String?,
-) {
-
-    init {
-        sprite?.flip(false, true)
-    }
-
-    fun requireSprite() = sprite ?: throw IllegalStateException("Sprite is null")
-
-    fun isBlock() = type == "block"
-
-    fun isTool() = type == "tool"
-
-    /**
-     * Returns block associated with this item. Null if this is not a block
-     */
-    fun toBlock(): Block? {
-        if (!isBlock()) {
-            return null
-        }
-
-        return GameItems.getBlock(GameItems.getBlockIdByItemId(id))
-    }
-
-    fun getItemOrBlockSprite(): Sprite {
-        return requireNotNull(sprite ?: toBlock()?.requireSprite()) { "wtf: sprite is null" }
-    }
-
-    fun isNone(): Boolean {
-        return id == 0;
-    }
-
-    @Deprecated("Was renamed to Sprite to comply with variable type.", ReplaceWith("requireSprite()"))
-    fun getTexture() = sprite
-}
\ No newline at end of file