From: fredboy Date: Fri, 10 May 2024 15:20:13 +0000 (+0700) Subject: Add chest X-Git-Tag: alpha0.9.0~5 X-Git-Url: http://deadsoftware.ru/gitweb?a=commitdiff_plain;h=cb0605053ce3de493b0d1f43cd7ec1e4a9cf0ac5;p=cavedroid.git Add chest --- diff --git a/android/assets/chest.png b/android/assets/chest.png index 961891f..2c6d0c6 100644 Binary files a/android/assets/chest.png and b/android/assets/chest.png differ diff --git a/android/assets/chest_large.png b/android/assets/chest_large.png new file mode 100644 index 0000000..961891f Binary files /dev/null and b/android/assets/chest_large.png differ diff --git a/android/assets/json/game_items.json b/android/assets/json/game_items.json index 7749345..95d4c7a 100644 --- a/android/assets/json/game_items.json +++ b/android/assets/json/game_items.json @@ -780,6 +780,22 @@ "tool_level": 1, "tool_type": "pickaxe", "meta": "furnace" + }, + "chest": { + "hp": 180, + "collision": true, + "transparent": true, + "drop": "chest", + "texture": "chest", + "tool_level": 0, + "tool_type": "axe", + "meta": "chest", + "top": 2, + "left": 1, + "right": 1, + "sprite_top": 2, + "sprite_left": 1, + "sprite_right": 1 } }, "items": { @@ -838,6 +854,11 @@ "type": "block", "texture": "furnace_off" }, + "chest": { + "name": "Chest", + "type": "block", + "texture": "chest" + }, "sapling_spruce": { "name": "Spruce Sapling", "type": "block", diff --git a/android/assets/json/texture_regions.json b/android/assets/json/texture_regions.json index 1800acd..1042b61 100644 --- a/android/assets/json/texture_regions.json +++ b/android/assets/json/texture_regions.json @@ -89,6 +89,12 @@ "h": 14 } }, + "chest": { + "chest": { + "w": 176, + "h": 168 + } + }, "buttons": { "button_0": { "w": 200, diff --git a/android/assets/textures/blocks/chest.png b/android/assets/textures/blocks/chest.png new file mode 100644 index 0000000..a2ca371 Binary files /dev/null and b/android/assets/textures/blocks/chest.png differ diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameModule.java b/core/src/ru/deadsoftware/cavedroid/game/GameModule.java index 2385230..d57ab33 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameModule.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameModule.java @@ -6,7 +6,7 @@ import ru.deadsoftware.cavedroid.MainConfig; import ru.deadsoftware.cavedroid.game.mobs.MobsController; import ru.deadsoftware.cavedroid.game.model.block.Block; import ru.deadsoftware.cavedroid.game.objects.drop.DropController; -import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController; +import ru.deadsoftware.cavedroid.game.objects.container.ContainerController; import ru.deadsoftware.cavedroid.game.ui.TooltipManager; import ru.deadsoftware.cavedroid.game.world.GameWorld; @@ -46,11 +46,11 @@ public class GameModule { @Provides @GameScope - public static FurnaceController provideFurnaceController(MainConfig mainConfig, GameItemsHolder gameItemsHolder) { + public static ContainerController provideFurnaceController(MainConfig mainConfig, DropController dropController, GameItemsHolder gameItemsHolder) { load(mainConfig, gameItemsHolder); - FurnaceController controller = data != null ? data.retrueveFurnaceController() : new FurnaceController(); + ContainerController controller = data != null ? data.retrieveFurnaceController() : new ContainerController(dropController, gameItemsHolder); makeDataNullIfEmpty(); - controller.init(gameItemsHolder); + controller.init(dropController, gameItemsHolder); return controller; } @@ -74,12 +74,12 @@ public class GameModule { DropController dropController, MobsController mobsController, GameItemsHolder gameItemsHolder, - FurnaceController furnaceController) { + ContainerController containerController) { load(mainConfig, gameItemsHolder); Block[][] fm = data != null ? data.retrieveForeMap() : null; Block[][] bm = data != null ? data.retrieveBackMap() : null; makeDataNullIfEmpty(); - return new GameWorld(dropController, mobsController, gameItemsHolder, furnaceController, fm, bm); + return new GameWorld(dropController, mobsController, gameItemsHolder, containerController, fm, bm); } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameProc.java b/core/src/ru/deadsoftware/cavedroid/game/GameProc.java index a3fcabb..29062a4 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameProc.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameProc.java @@ -6,7 +6,7 @@ import com.badlogic.gdx.utils.Timer; import ru.deadsoftware.cavedroid.MainConfig; import ru.deadsoftware.cavedroid.game.mobs.MobsController; import ru.deadsoftware.cavedroid.game.mobs.player.Player; -import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController; +import ru.deadsoftware.cavedroid.game.objects.container.ContainerController; import ru.deadsoftware.cavedroid.game.world.GameWorldBlocksLogicControllerTask; import ru.deadsoftware.cavedroid.game.world.GameWorldFluidsLogicControllerTask; import ru.deadsoftware.cavedroid.game.world.GameWorldMobDamageControllerTask; @@ -19,7 +19,7 @@ public class GameProc implements Disposable { private final GamePhysics mGamePhysics; private final GameRenderer mGameRenderer; private final MobsController mMobsController; - private final FurnaceController mFurnaceController; + private final ContainerController mContainerController; private final GameItemsHolder mGameItemsHolder; private final GameWorldFluidsLogicControllerTask mGameWorldFluidsLogicControllerTask; private final GameWorldBlocksLogicControllerTask mGameWorldBlocksLogicControllerTask; @@ -32,7 +32,7 @@ public class GameProc implements Disposable { GamePhysics gamePhysics, GameRenderer gameRenderer, MobsController mobsController, - FurnaceController furnaceController, + ContainerController containerController, GameItemsHolder gameItemsHolder, GameWorldFluidsLogicControllerTask gameWorldFluidsLogicControllerTask, GameWorldBlocksLogicControllerTask gameWorldBlocksLogicControllerTask, @@ -41,7 +41,7 @@ public class GameProc implements Disposable { mGamePhysics = gamePhysics; mGameRenderer = gameRenderer; mMobsController = mobsController; - mFurnaceController = furnaceController; + mContainerController = containerController; mGameItemsHolder = gameItemsHolder; mGameWorldFluidsLogicControllerTask = gameWorldFluidsLogicControllerTask; mGameWorldBlocksLogicControllerTask = gameWorldBlocksLogicControllerTask; @@ -64,7 +64,7 @@ public class GameProc implements Disposable { public void update(float delta) { mGamePhysics.update(delta); mGameRenderer.render(delta); - mFurnaceController.update(mGameItemsHolder); + mContainerController.update(); } public void show() { diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java b/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java index dd16186..39d2278 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java @@ -6,7 +6,7 @@ import ru.deadsoftware.cavedroid.MainConfig; import ru.deadsoftware.cavedroid.game.mobs.MobsController; import ru.deadsoftware.cavedroid.game.model.block.Block; import ru.deadsoftware.cavedroid.game.objects.drop.DropController; -import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController; +import ru.deadsoftware.cavedroid.game.objects.container.ContainerController; import ru.deadsoftware.cavedroid.game.world.GameWorld; import javax.annotation.CheckForNull; @@ -25,18 +25,18 @@ public class GameSaver { @CheckForNull private DropController mDropController; @CheckForNull - private FurnaceController mFurnaceController; + private ContainerController mContainerController; @CheckForNull private Block[][] mForeMap, mBackMap; public Data(MobsController mobsController, DropController dropController, - FurnaceController furnaceController, + ContainerController containerController, Block[][] foreMap, Block[][] backMap) { mMobsController = mobsController; mDropController = dropController; - mFurnaceController = furnaceController; + mContainerController = containerController; mForeMap = foreMap; mBackMap = backMap; } @@ -55,11 +55,11 @@ public class GameSaver { return dropController; } - public FurnaceController retrueveFurnaceController() { - assert mFurnaceController != null; - FurnaceController furnaceController = mFurnaceController; - mFurnaceController = null; - return furnaceController; + public ContainerController retrieveFurnaceController() { + assert mContainerController != null; + ContainerController containerController = mContainerController; + mContainerController = null; + return containerController; } public Block[][] retrieveForeMap() { @@ -77,7 +77,11 @@ public class GameSaver { } public boolean isEmpty() { - return mMobsController == null && mDropController == null && mForeMap == null && mBackMap == null; + return mMobsController == null && + mDropController == null && + mContainerController == null && + mForeMap == null && + mBackMap == null; } } @@ -198,12 +202,12 @@ public class GameSaver { int version = in.readInt(); DropController dropController; MobsController mobsController; - FurnaceController furnaceController; + ContainerController containerController; if (SAVE_VERSION == version) { dropController = (DropController) in.readObject(); mobsController = (MobsController) in.readObject(); - furnaceController = (FurnaceController) in.readObject(); + containerController = (ContainerController) in.readObject(); } else { throw new Exception("version mismatch"); } @@ -218,7 +222,7 @@ public class GameSaver { throw new Exception("couldn't load"); } - return new Data(mobsController, dropController, furnaceController, foreMap, backMap); + return new Data(mobsController, dropController, containerController, foreMap, backMap); } catch (Exception e) { Gdx.app.error("GameSaver", e.getMessage()); } @@ -229,7 +233,7 @@ public class GameSaver { public static void save(MainConfig mainConfig, DropController dropController, MobsController mobsController, - FurnaceController furnaceController, + ContainerController containerController, GameWorld gameWorld) { String folder = mainConfig.getGameFolder(); FileHandle file = Gdx.files.absolute(folder + "/saves/"); @@ -247,7 +251,7 @@ public class GameSaver { out.writeInt(SAVE_VERSION); out.writeObject(dropController); out.writeObject(mobsController); - out.writeObject(furnaceController); + out.writeObject(containerController); out.close(); saveDict(Gdx.files.absolute(folder + "/saves/dict"), dict); diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt index 5b2a169..7458dfc 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt @@ -6,6 +6,7 @@ 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 @@ -27,4 +28,12 @@ class UseBlockActionsModule { 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/useblock/UseChestAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseChestAction.kt new file mode 100644 index 0000000..fa50c94 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseChestAction.kt @@ -0,0 +1,26 @@ +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.objects.container.Chest +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.game.world.GameWorld +import javax.inject.Inject + +@GameScope +class UseChestAction @Inject constructor( + private val gameWorld: GameWorld, + private val gameWindowsManager: GameWindowsManager, +) : IUseBlockAction { + + override fun perform(block: Block, x: Int, y: Int) { + val chest = (gameWorld.getForegroundContainer(x, y) as? Chest) + ?: (gameWorld.getBackgroundContainer(x, y) as? Chest) + ?: return + gameWindowsManager.openChest(chest) + } + + companion object { + const val KEY = "chest" + } +} \ No newline at end of file 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 88a6a7f..7c30402 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt @@ -2,18 +2,18 @@ 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.objects.furnace.FurnaceController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @GameScope class UseFurnaceAction @Inject constructor( - private val furnaceController: FurnaceController, + private val gameWorld: GameWorld, private val gameWindowsManager: GameWindowsManager, ) : IUseBlockAction { override fun perform(block: Block, x: Int, y: Int) { - val furnace = furnaceController.getFurnace(x, y, 0) ?: furnaceController.getFurnace(x, y, 1) ?: return + val furnace = gameWorld.getForegroundFurnace(x, y) ?: gameWorld.getBackgroundFurnace(x, y) ?: return gameWindowsManager.openFurnace(furnace) } diff --git a/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt b/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt index df1dd06..51dc335 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt @@ -3,6 +3,7 @@ package ru.deadsoftware.cavedroid.game.debug import com.badlogic.gdx.Gdx import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.objects.container.ContainerController import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @@ -11,7 +12,8 @@ import javax.inject.Inject class DebugInfoStringsProvider @Inject constructor( private val mobsController: MobsController, private val dropController: DropController, - private val gameWorld: GameWorld + private val containerController: ContainerController, + private val gameWorld: GameWorld, ) { fun getDebugStrings(): List { @@ -27,6 +29,7 @@ class DebugInfoStringsProvider @Inject constructor( "Swim: ${player.swim}", "Mobs: ${mobsController.mobs.size}", "Drops: ${dropController.size}", + "Containers: ${containerController.size}", "Block: ${gameWorld.getForeMap(player.cursorX, player.cursorY).params.key}", "Hand: ${player.inventory.activeItem.item.params.key}", "Game mode: ${player.gameMode}", diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt b/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt index fe9bba6..f0c3b3b 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt @@ -87,4 +87,11 @@ object MouseInputHandlersModule { 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/PauseGameKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt index 8ba35c1..8f0f494 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 @@ -8,7 +8,7 @@ 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.objects.furnace.FurnaceController +import ru.deadsoftware.cavedroid.game.objects.container.ContainerController import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @@ -18,7 +18,7 @@ class PauseGameKeyboardInputHandler @Inject constructor( private val dropController: DropController, private val mobsController: MobsController, private val gameWorld: GameWorld, - private val furnaceController: FurnaceController, + private val containerController: ContainerController, ) : IGameInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { @@ -26,7 +26,7 @@ class PauseGameKeyboardInputHandler @Inject constructor( } override fun handle(action: KeyboardInputAction) { - GameSaver.save(mainConfig, dropController, mobsController, furnaceController, gameWorld) + GameSaver.save(mainConfig, dropController, mobsController, containerController, gameWorld) mainConfig.caveGame.quitGame() } } \ No newline at end of file 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 ddc41e2..f6f6cfc 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 @@ -24,6 +24,7 @@ class CloseGameWindowMouseInputHandler @Inject constructor( private val survivalInventoryTexture get() = requireNotNull(Assets.textureRegions["survival"]) private val craftingInventoryTexture get() = requireNotNull(Assets.textureRegions["crafting_table"]) private val furnaceInventoryTexture get() = requireNotNull(Assets.textureRegions["furnace"]) + private val chestInventoryTexture get() = requireNotNull(Assets.textureRegions["chest"]) override fun checkConditions(action: MouseInputAction): Boolean { return gameWindowsManager.getCurrentWindow() != GameUiWindow.NONE && @@ -38,6 +39,7 @@ class CloseGameWindowMouseInputHandler @Inject constructor( GameUiWindow.SURVIVAL_INVENTORY -> survivalInventoryTexture GameUiWindow.CRAFTING_TABLE -> craftingInventoryTexture GameUiWindow.FURNACE -> furnaceInventoryTexture + GameUiWindow.CHEST -> chestInventoryTexture else -> throw UnsupportedOperationException("Cant close window ${window.name}") } } 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 new file mode 100644 index 0000000..3d1bfae --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectChestInventoryItemMouseInputHandler.kt @@ -0,0 +1,131 @@ +package ru.deadsoftware.cavedroid.game.input.handler.mouse + +import com.badlogic.gdx.Gdx +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.action.MouseInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey +import ru.deadsoftware.cavedroid.game.input.isInsideWindow +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem +import ru.deadsoftware.cavedroid.game.objects.drop.DropController +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.game.ui.windows.inventory.ChestInventoryWindow +import ru.deadsoftware.cavedroid.game.ui.windows.inventory.SurvivalInventoryWindow +import ru.deadsoftware.cavedroid.misc.Assets +import javax.inject.Inject + +@GameScope +class SelectChestInventoryItemMouseInputHandler @Inject constructor( + private val gameWindowsManager: GameWindowsManager, + private val mobsController: MobsController, + private val gameItemsHolder: GameItemsHolder, + private val dropController: DropController, +) : IGameInputHandler { + + private val chestWindowTexture get() = requireNotNull(Assets.textureRegions["chest"]) + + override fun checkConditions(action: MouseInputAction): Boolean { + return gameWindowsManager.getCurrentWindow() == GameUiWindow.CHEST && + isInsideWindow(action, chestWindowTexture) && + (action.actionKey is MouseInputActionKey.Left || action.actionKey is MouseInputActionKey.Right || action.actionKey is MouseInputActionKey.Screen) + && (action.actionKey.touchUp || action.actionKey is MouseInputActionKey.Screen) + } + + private fun handleInsideContentGrid(action: MouseInputAction, xOnGrid: Int, yOnGrid: Int) { + val window = gameWindowsManager.currentWindow as ChestInventoryWindow + + val itemIndex = ((xOnGrid.toInt() + yOnGrid.toInt() * GameWindowsConfigs.Chest.contentsInRow)) + + if (action.actionKey is MouseInputActionKey.Screen) { + if (!action.actionKey.touchUp) { + window.onLeftCLick(window.chest.items as MutableList, gameItemsHolder, itemIndex, action.actionKey.pointer) + } else { + if (action.actionKey.pointer == window.selectItemPointer) { + window.onLeftCLick(window.chest.items as MutableList, gameItemsHolder, itemIndex, action.actionKey.pointer) + } else { + window.onRightClick(window.chest.items as MutableList, itemIndex) + } + } + } else if (action.actionKey is MouseInputActionKey.Left) { + window.onLeftCLick(window.chest.items as MutableList, gameItemsHolder, itemIndex) + } else { + window.onRightClick(window.chest.items as MutableList, itemIndex) + } + + Gdx.app.debug( + TAG, + "selected item: ${window.selectedItem?.item?.params?.key ?: "null"}; index $itemIndex, grid ($xOnGrid;$yOnGrid)" + ) + } + + private fun handleInsideInventoryGrid(action: MouseInputAction, xOnGrid: Int, yOnGrid: Int) { + val window = gameWindowsManager.currentWindow as ChestInventoryWindow + + var itemIndex = ((xOnGrid.toInt() + yOnGrid.toInt() * GameWindowsConfigs.Chest.itemsInRow)) + itemIndex += GameWindowsConfigs.Chest.hotbarCells + + if (itemIndex >= mobsController.player.inventory.size) { + itemIndex -= mobsController.player.inventory.size + } + + if (action.actionKey is MouseInputActionKey.Screen) { + if (!action.actionKey.touchUp) { + window.onLeftCLick(mobsController.player.inventory.items as MutableList, gameItemsHolder, itemIndex, action.actionKey.pointer) + } else { + if (action.actionKey.pointer == window.selectItemPointer) { + window.onLeftCLick(mobsController.player.inventory.items as MutableList, gameItemsHolder, itemIndex, action.actionKey.pointer) + } else { + window.onRightClick(mobsController.player.inventory.items as MutableList, itemIndex) + } + } + } else if (action.actionKey is MouseInputActionKey.Left) { + window.onLeftCLick(mobsController.player.inventory.items as MutableList, gameItemsHolder, itemIndex) + } else { + window.onRightClick(mobsController.player.inventory.items as MutableList, itemIndex) + } + + Gdx.app.debug( + TAG, + "selected item: ${window.selectedItem?.item?.params?.key ?: "null"}; index $itemIndex, grid ($xOnGrid;$yOnGrid)" + ) + } + + override fun handle(action: MouseInputAction) { + val chestTexture = chestWindowTexture + + val xOnWindow = action.screenX - (action.cameraViewport.width / 2 - chestTexture.regionWidth / 2) + val yOnWindow = action.screenY - (action.cameraViewport.height / 2 - chestTexture.regionHeight / 2) + + val xOnGrid = (xOnWindow - GameWindowsConfigs.Chest.itemsGridMarginLeft) / + GameWindowsConfigs.Chest.itemsGridColWidth + val yOnGrid = (yOnWindow - GameWindowsConfigs.Chest.itemsGridMarginTop) / + GameWindowsConfigs.Chest.itemsGridRowHeight + + val xOnContent = (xOnWindow - GameWindowsConfigs.Chest.contentsMarginLeft) / + GameWindowsConfigs.Chest.itemsGridColWidth + val yOnContent = (yOnWindow - GameWindowsConfigs.Chest.contentsMarginTop) / + GameWindowsConfigs.Chest.itemsGridRowHeight + + val isInsideInventoryGrid = xOnGrid >= 0 && xOnGrid < GameWindowsConfigs.Chest.itemsInRow && + yOnGrid >= 0 && yOnGrid < GameWindowsConfigs.Chest.itemsInCol + + val isInsideContentGrid = xOnContent >= 0 && xOnContent < GameWindowsConfigs.Chest.contentsInRow && + yOnContent >= 0 && yOnContent < GameWindowsConfigs.Chest.contentsInCol + + + if (isInsideInventoryGrid) { + handleInsideInventoryGrid(action, xOnGrid.toInt(), yOnGrid.toInt()) + } else if (isInsideContentGrid) { + handleInsideContentGrid(action, xOnContent.toInt(), yOnContent.toInt()) + } + } + + companion object { + private const val TAG = "SelectChestInventoryItemMouseInputHandler" + + } +} \ No newline at end of file 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 839135e..e11c433 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,7 +1,6 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse import com.badlogic.gdx.Gdx -import com.badlogic.gdx.utils.TimeUtils import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow @@ -13,7 +12,7 @@ import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.InventoryItem import ru.deadsoftware.cavedroid.game.model.item.InventoryItem.Companion.isNoneOrNull import ru.deadsoftware.cavedroid.game.objects.drop.DropController -import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace +import ru.deadsoftware.cavedroid.game.objects.container.Furnace import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import ru.deadsoftware.cavedroid.game.ui.windows.inventory.FurnaceInventoryWindow @@ -78,18 +77,18 @@ class SelectFurnaceInventoryItemMouseInputHandler @Inject constructor( if (action.actionKey is MouseInputActionKey.Screen) { if (!action.actionKey.touchUp) { - window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.FUEL_INDEX, action.actionKey.pointer) + window.onLeftCLick(window.furnace.items as MutableList, gameItemsHolder, Furnace.FUEL_INDEX, action.actionKey.pointer) } else { if (action.actionKey.pointer == window.selectItemPointer) { - window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.FUEL_INDEX, action.actionKey.pointer) + window.onLeftCLick(window.furnace.items as MutableList, gameItemsHolder, Furnace.FUEL_INDEX, action.actionKey.pointer) } else { - window.onRightClick(window.furnace.items, Furnace.FUEL_INDEX) + window.onRightClick(window.furnace.items as MutableList, Furnace.FUEL_INDEX) } } } else if (action.actionKey is MouseInputActionKey.Left || action.actionKey is MouseInputActionKey.Screen) { - window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.FUEL_INDEX) + window.onLeftCLick(window.furnace.items as MutableList, gameItemsHolder, Furnace.FUEL_INDEX) } else { - window.onRightClick(window.furnace.items, Furnace.FUEL_INDEX) + window.onRightClick(window.furnace.items as MutableList, Furnace.FUEL_INDEX) } } @@ -98,18 +97,18 @@ class SelectFurnaceInventoryItemMouseInputHandler @Inject constructor( if (action.actionKey is MouseInputActionKey.Screen) { if (!action.actionKey.touchUp) { - window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.INPUT_INDEX, action.actionKey.pointer) + window.onLeftCLick(window.furnace.items as MutableList, gameItemsHolder, Furnace.INPUT_INDEX, action.actionKey.pointer) } else { if (action.actionKey.pointer == window.selectItemPointer) { - window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.INPUT_INDEX, action.actionKey.pointer) + window.onLeftCLick(window.furnace.items as MutableList, gameItemsHolder, Furnace.INPUT_INDEX, action.actionKey.pointer) } else { - window.onRightClick(window.furnace.items, Furnace.INPUT_INDEX) + window.onRightClick(window.furnace.items as MutableList, Furnace.INPUT_INDEX) } } } else if (action.actionKey is MouseInputActionKey.Left || action.actionKey is MouseInputActionKey.Screen) { - window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.INPUT_INDEX) + window.onLeftCLick(window.furnace.items as MutableList, gameItemsHolder, Furnace.INPUT_INDEX) } else { - window.onRightClick(window.furnace.items, Furnace.INPUT_INDEX) + window.onRightClick(window.furnace.items as MutableList, Furnace.INPUT_INDEX) } } @@ -159,7 +158,7 @@ class SelectFurnaceInventoryItemMouseInputHandler @Inject constructor( } else { window.selectedItem = window.furnace.result } - window.furnace.items[Furnace.RESULT_INDEX] = null + window.furnace.items[Furnace.RESULT_INDEX] = gameItemsHolder.fallbackItem.toInventoryItem() } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt b/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt index 2e268d0..fa99bfd 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt @@ -111,11 +111,21 @@ sealed class Block { return this is Slab } + fun isContainer(): Boolean { + contract { returns(true) implies (this@Block is Container) } + return this is Container + } + fun isFurnace(): Boolean { contract { returns(true) implies (this@Block is Furnace) } return this is Furnace } + fun isChest(): Boolean { + contract { returns(true) implies (this@Block is Chest) } + return this is Chest + } + fun isNone(): Boolean { contract { returns(true) implies (this@Block is None) } return this is None @@ -130,6 +140,8 @@ sealed class Block { ) } + sealed class Container() : Block() + data class None( override val params: CommonBlockParams ) : Block() @@ -140,7 +152,7 @@ sealed class Block { data class Furnace( override val params: CommonBlockParams, - ): Block() { + ): Container() { override val sprite: Sprite get() = getSprite(false) @@ -169,6 +181,10 @@ sealed class Block { } + data class Chest( + override val params: CommonBlockParams + ): Container() + data class Slab( override val params: CommonBlockParams, val fullBlockKey: String, diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt b/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt index acc0d29..44d3179 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt @@ -91,7 +91,9 @@ class InventoryItem @JvmOverloads constructor( } val sprite = item.sprite - spriteBatch.drawSprite(sprite, x, y) + val placeableMarginTop = (item as? Item.Placeable)?.block?.params?.spriteMargins?.top ?: 0 + val placeableMarginLeft = (item as? Item.Placeable)?.block?.params?.spriteMargins?.left ?: 0 + spriteBatch.drawSprite(sprite, x + placeableMarginLeft, y + placeableMarginTop) if (amount < 2) { return diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt b/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt index 2ec9727..1b641ed 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt @@ -24,6 +24,7 @@ class BlockMapper @Inject constructor( "lava" -> Lava(commonBlockParams, requireNotNull(dto.state)) "slab" -> Slab(commonBlockParams, requireNotNull(dto.fullBlock), requireNotNull(dto.otherPart)) "furnace" -> Furnace(commonBlockParams) + "chest" -> Chest(commonBlockParams) "none" -> None(commonBlockParams) else -> Normal(commonBlockParams) } diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/container/Chest.kt b/core/src/ru/deadsoftware/cavedroid/game/objects/container/Chest.kt new file mode 100644 index 0000000..be820bc --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/container/Chest.kt @@ -0,0 +1,14 @@ +package ru.deadsoftware.cavedroid.game.objects.container + +import ru.deadsoftware.cavedroid.game.GameItemsHolder + +class Chest(gameItemsHolder: GameItemsHolder) : Container(SIZE, gameItemsHolder) { + + override fun update(gameItemsHolder: GameItemsHolder) { + // no-op + } + + companion object { + private const val SIZE = 27 + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/container/Container.kt b/core/src/ru/deadsoftware/cavedroid/game/objects/container/Container.kt new file mode 100644 index 0000000..1e13c64 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/container/Container.kt @@ -0,0 +1,24 @@ +package ru.deadsoftware.cavedroid.game.objects.container + +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem +import java.io.Serializable +import javax.annotation.OverridingMethodsMustInvokeSuper + +abstract class Container( + val size: Int, + gameItemsHolder: GameItemsHolder +) : Serializable { + + private val _items = Array(size) { gameItemsHolder.fallbackItem.toInventoryItem() } + + val items get() = _items.asList() as MutableList + + @OverridingMethodsMustInvokeSuper + open fun initItems(gameItemsHolder: GameItemsHolder) { + _items.forEach { it.init(gameItemsHolder) } + } + + abstract fun update(gameItemsHolder: GameItemsHolder) + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/container/ContainerController.kt b/core/src/ru/deadsoftware/cavedroid/game/objects/container/ContainerController.kt new file mode 100644 index 0000000..3facb6f --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/container/ContainerController.kt @@ -0,0 +1,86 @@ +package ru.deadsoftware.cavedroid.game.objects.container + +import com.badlogic.gdx.Gdx +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.model.block.Block +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem.Companion.isNoneOrNull +import ru.deadsoftware.cavedroid.game.objects.drop.DropController +import ru.deadsoftware.cavedroid.misc.utils.px +import java.io.Serializable +import javax.inject.Inject + +@GameScope +class ContainerController @Inject constructor( + _dropController: DropController, + _gameItemsHolder: GameItemsHolder +) : Serializable { + + @Suppress("UNNECESSARY_LATEINIT") + @Transient + private lateinit var dropController: DropController + + @Suppress("UNNECESSARY_LATEINIT") + @Transient + private lateinit var gameItemsHolder: GameItemsHolder + + private val containerMap = mutableMapOf() + + val size get() = containerMap.size + + init { + dropController = _dropController + gameItemsHolder = _gameItemsHolder + } + + fun init(dropController: DropController, gameItemsHolder: GameItemsHolder) { + this.dropController = dropController + this.gameItemsHolder = gameItemsHolder + containerMap.forEach { (_, container) -> container.initItems(gameItemsHolder) } + } + + fun getContainer(x: Int, y: Int, z: Int): Container? { + return containerMap["$x;$y;$z"] + } + + fun addContainer(x: Int, y: Int, z: Int, clazz: Class) { + val container = when (clazz) { + Block.Furnace::class.java -> Furnace(gameItemsHolder) + Block.Chest::class.java -> Chest(gameItemsHolder) + else -> { + Gdx.app.error(TAG, "Unknown container class $clazz") + return + } + } + containerMap["$x;$y;$z"] = container + } + + @JvmOverloads + fun destroyContainer(x: Int, y: Int, z: Int, dropItems: Boolean = true) { + val container = containerMap.remove("$x;$y;$z") ?: return + + if (!dropItems) { + return + } + + val xPx = (x + .5f).px + val yPx = (y + .5f).px + + container.items.forEach { item -> + if (!item.isNoneOrNull()) { + dropController.addDrop(xPx, yPx, item) + } + } + } + + fun update() { + containerMap.forEach { (_, container) -> + container.update(gameItemsHolder) + } + } + + companion object { + private const val TAG = "ContainerController" + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/Furnace.kt b/core/src/ru/deadsoftware/cavedroid/game/objects/container/Furnace.kt similarity index 71% rename from core/src/ru/deadsoftware/cavedroid/game/objects/furnace/Furnace.kt rename to core/src/ru/deadsoftware/cavedroid/game/objects/container/Furnace.kt index 0265cb0..1a75e89 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/Furnace.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/container/Furnace.kt @@ -1,4 +1,4 @@ -package ru.deadsoftware.cavedroid.game.objects.furnace +package ru.deadsoftware.cavedroid.game.objects.container import com.badlogic.gdx.Gdx import com.badlogic.gdx.math.MathUtils @@ -7,25 +7,22 @@ import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.model.item.InventoryItem import ru.deadsoftware.cavedroid.game.model.item.InventoryItem.Companion.isNoneOrNull import ru.deadsoftware.cavedroid.game.model.item.Item -import java.io.Serializable -class Furnace : Serializable { - - val items = MutableList(3) { null } - - var fuel: InventoryItem? +class Furnace(gameItemsHolder: GameItemsHolder) : Container(SIZE, gameItemsHolder) { + + var fuel: InventoryItem get() = items[FUEL_INDEX] set(value) { items[FUEL_INDEX] = value } - var input: InventoryItem? + var input: InventoryItem get() = items[INPUT_INDEX] set(value) { items[INPUT_INDEX] = value } - var result: InventoryItem? + var result: InventoryItem get() = items[RESULT_INDEX] set(value) { items[RESULT_INDEX] = value @@ -56,27 +53,27 @@ class Furnace : Serializable { fun init(gameItemsHolder: GameItemsHolder) { currentFuel = currentFuelKey?.let { gameItemsHolder.getItem(it) } - items.forEach { it?.init(gameItemsHolder) } + items.forEach { it.init(gameItemsHolder) } } fun canSmelt(): Boolean { - return (result.isNoneOrNull() || (result?.item?.params?.key == input?.item?.params?.smeltProductKey) )&& - !input.isNoneOrNull() && input?.item?.params?.smeltProductKey != null && + return (result.isNoneOrNull() || (result.item.params.key == input.item.params.smeltProductKey) )&& + !input.isNoneOrNull() && input.item.params.smeltProductKey != null && (!fuel.isNoneOrNull() || burnProgress > 0f) } - private fun startBurning() { - requireNotNull(fuel?.item?.params?.burningTimeMs) { "Cant start burning without fuel" } - currentFuel = fuel!!.item - fuel!!.subtract() - if (fuel!!.amount <= 0) { - fuel = null + private fun startBurning(gameItemsHolder: GameItemsHolder) { + requireNotNull(fuel.item.params.burningTimeMs) { "Cant start burning without fuel" } + currentFuel = fuel.item + fuel.subtract() + if (fuel.amount <= 0) { + fuel = gameItemsHolder.fallbackItem.toInventoryItem() } startBurnTimeMs = TimeUtils.millis() burnProgress = 0f } - fun update(gameItemsHolder: GameItemsHolder) { + override fun update(gameItemsHolder: GameItemsHolder) { if (currentFuel?.isNone() == true) { currentFuel = null } @@ -96,7 +93,7 @@ class Furnace : Serializable { if (currentFuel?.isNone() == false && burnProgress >= 1f) { if (canSmelt()) { - startBurning() + startBurning(gameItemsHolder) } else { currentFuel = null burnProgress = 0f @@ -108,7 +105,7 @@ class Furnace : Serializable { return } if (currentFuel == null && !fuel.isNoneOrNull()) { - startBurning() + startBurning(gameItemsHolder) smeltStarTimeMs = startBurnTimeMs smeltProgress = 0f } @@ -119,15 +116,16 @@ class Furnace : Serializable { } if (isActive && smeltProgress >= 1f) { - val res = gameItemsHolder.getItem(input!!.item.params.smeltProductKey!!) + val productKey = requireNotNull(input.item.params.smeltProductKey) + val res = gameItemsHolder.getItem(productKey) if (result.isNoneOrNull()) { result = res.toInventoryItem() } else { - result!!.add() + result.add() } - input!!.subtract() - if (input!!.amount <= 0) { - input = null + input.subtract() + if (input.amount <= 0) { + input = gameItemsHolder.fallbackItem.toInventoryItem() } smeltStarTimeMs = TimeUtils.millis() smeltProgress = 0f @@ -135,6 +133,7 @@ class Furnace : Serializable { } companion object { + private const val SIZE = 3 private const val TAG = "Furnace" const val FUEL_INDEX = 0 diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/FurnaceController.kt b/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/FurnaceController.kt deleted file mode 100644 index ccc3972..0000000 --- a/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/FurnaceController.kt +++ /dev/null @@ -1,43 +0,0 @@ -package ru.deadsoftware.cavedroid.game.objects.furnace - -import ru.deadsoftware.cavedroid.game.GameItemsHolder -import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.objects.drop.DropController -import ru.deadsoftware.cavedroid.misc.utils.px -import java.io.Serializable -import javax.inject.Inject - -@GameScope -class FurnaceController @Inject constructor() : Serializable { - - private val furnaceMap = mutableMapOf() - - fun init(gameItemsHolder: GameItemsHolder) { - furnaceMap.forEach { _, fur -> fur.init(gameItemsHolder) } - } - - fun getFurnace(x: Int, y: Int, z: Int): Furnace? { - return furnaceMap["$x;$y;$z"] - } - - fun addFurnace(x: Int, y: Int, z: Int) { - furnaceMap["$x;$y;$z"] = Furnace() - } - - fun destroyFurnace(x: Int, y: Int, z: Int, dropController: DropController) { - val furnace = furnaceMap.remove("$x;$y;$z") ?: return - val xPx = (x + .5f).px - val yPx = (y + .5f).px - - furnace.input?.let { dropController.addDrop(xPx, yPx, it) } - furnace.fuel?.let { dropController.addDrop(xPx, yPx, it) } - furnace.result?.let { dropController.addDrop(xPx, yPx, it) } - } - - fun update(gameItemsHolder: GameItemsHolder) { - furnaceMap.forEach { _, furnace -> - furnace.update(gameItemsHolder) - } - } - -} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/BlocksRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/BlocksRenderer.kt index 5af20e8..68af67b 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/BlocksRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/BlocksRenderer.kt @@ -86,7 +86,7 @@ abstract class BlocksRenderer( if (foregroundBlock.canSeeThrough && !backgroundBlock.isNone()) { val drawX = x.px - viewport.x val drawY = y.px - viewport.y - if (backgroundBlock.isFurnace()) { + if (backgroundBlock is Block.Furnace) { backgroundBlock.draw(spriteBatch, drawX, drawY, gameWorld.getBackgroundFurnace(x, y)?.isActive ?: false) } else { backgroundBlock.draw(spriteBatch, drawX, drawY) @@ -101,7 +101,7 @@ abstract class BlocksRenderer( val drawX = x.px - viewport.x val drawY = y.px - viewport.y - if (foregroundBlock.isFurnace()) { + if (foregroundBlock is Block.Furnace) { foregroundBlock.draw(spriteBatch, drawX, drawY, gameWorld.getForegroundFurnace(x, y)?.isActive ?: false) } else { foregroundBlock.draw(spriteBatch, drawX, drawY) diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt index f87c5bd..fa37f8d 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt @@ -6,10 +6,7 @@ import com.badlogic.gdx.graphics.glutils.ShapeRenderer import com.badlogic.gdx.math.Rectangle import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow -import ru.deadsoftware.cavedroid.game.render.windows.CraftingWindowRenderer -import ru.deadsoftware.cavedroid.game.render.windows.CreativeWindowRenderer -import ru.deadsoftware.cavedroid.game.render.windows.FurnaceWindowRenderer -import ru.deadsoftware.cavedroid.game.render.windows.SurvivalWindowRenderer +import ru.deadsoftware.cavedroid.game.render.windows.* import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject @@ -20,6 +17,7 @@ class WindowsRenderer @Inject constructor( private val craftingWindowRenderer: CraftingWindowRenderer, private val gameWindowsManager: GameWindowsManager, private val furnaceWindowRenderer: FurnaceWindowRenderer, + private val chestWindowRenderer: ChestWindowRenderer, ) : IGameRenderer { override val renderLayer get() = RENDER_LAYER @@ -30,6 +28,7 @@ class WindowsRenderer @Inject constructor( GameUiWindow.SURVIVAL_INVENTORY -> survivalWindowRenderer.draw(spriteBatch, shapeRenderer, viewport, delta) GameUiWindow.CRAFTING_TABLE -> craftingWindowRenderer.draw(spriteBatch, shapeRenderer, viewport, delta) GameUiWindow.FURNACE -> furnaceWindowRenderer.draw(spriteBatch, shapeRenderer, viewport, delta) + GameUiWindow.CHEST -> chestWindowRenderer.draw(spriteBatch, shapeRenderer, viewport, delta) GameUiWindow.NONE -> return else -> Gdx.app.error(TAG, "Cannot draw window: ${windowType.name}") } diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/windows/ChestWindowRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/windows/ChestWindowRenderer.kt new file mode 100644 index 0000000..78178bc --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/render/windows/ChestWindowRenderer.kt @@ -0,0 +1,93 @@ +package ru.deadsoftware.cavedroid.game.render.windows + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import com.badlogic.gdx.graphics.glutils.ShapeRenderer +import com.badlogic.gdx.math.MathUtils +import com.badlogic.gdx.math.Rectangle +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameItemsHolder +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.render.IGameRenderer +import ru.deadsoftware.cavedroid.game.render.WindowsRenderer +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.game.ui.windows.inventory.ChestInventoryWindow +import ru.deadsoftware.cavedroid.game.ui.windows.inventory.SurvivalInventoryWindow +import ru.deadsoftware.cavedroid.misc.Assets +import javax.inject.Inject +import kotlin.math.atan + +@GameScope +class ChestWindowRenderer @Inject constructor( + private val mainConfig: MainConfig, + private val mobsController: MobsController, + private val gameWindowsManager: GameWindowsManager, + private val gameItemsHolder: GameItemsHolder, +) : AbstractWindowRenderer(), IGameRenderer { + + override val renderLayer get() = WindowsRenderer.RENDER_LAYER + + private val chestWindowTexture get() = requireNotNull(Assets.textureRegions[CHEST_WINDOW_KEY]) + + + override fun draw(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, viewport: Rectangle, delta: Float) { + val windowTexture = chestWindowTexture + val window = gameWindowsManager.currentWindow as ChestInventoryWindow + + val windowX = viewport.width / 2 - windowTexture.regionWidth / 2 + val windowY = viewport.height / 2 - windowTexture.regionHeight / 2 + + spriteBatch.draw(windowTexture, windowX, windowY) + + drawItemsGrid( + spriteBatch = spriteBatch, + shapeRenderer = shapeRenderer, + gridX = windowX + GameWindowsConfigs.Chest.contentsMarginLeft, + gridY = windowY + GameWindowsConfigs.Chest.contentsMarginTop, + items = window.chest.items, + itemsInRow = GameWindowsConfigs.Chest.itemsInRow, + cellWidth = GameWindowsConfigs.Chest.itemsGridColWidth, + cellHeight = GameWindowsConfigs.Chest.itemsGridRowHeight, + ) + + drawItemsGrid( + spriteBatch = spriteBatch, + shapeRenderer = shapeRenderer, + gridX = windowX + GameWindowsConfigs.Chest.itemsGridMarginLeft, + gridY = windowY + GameWindowsConfigs.Chest.itemsGridMarginTop, + items = mobsController.player.inventory.items.asSequence() + .drop(GameWindowsConfigs.Chest.hotbarCells) + .take(GameWindowsConfigs.Chest.itemsInCol * GameWindowsConfigs.Chest.itemsInRow) + .asIterable(), + itemsInRow = GameWindowsConfigs.Chest.itemsInRow, + cellWidth = GameWindowsConfigs.Chest.itemsGridColWidth, + cellHeight = GameWindowsConfigs.Chest.itemsGridRowHeight, + ) + + drawItemsGrid( + spriteBatch = spriteBatch, + shapeRenderer = shapeRenderer, + gridX = windowX + GameWindowsConfigs.Chest.itemsGridMarginLeft, + gridY = windowY + windowTexture.regionHeight - GameWindowsConfigs.Chest.hotbarOffsetFromBottom, + items = mobsController.player.inventory.items.asSequence() + .take(GameWindowsConfigs.Chest.hotbarCells) + .asIterable(), + itemsInRow = GameWindowsConfigs.Chest.hotbarCells, + cellWidth = GameWindowsConfigs.Chest.itemsGridColWidth, + cellHeight = GameWindowsConfigs.Chest.itemsGridRowHeight, + ) + + window.selectedItem?.drawSelected( + spriteBatch = spriteBatch, + x = Gdx.input.x * (viewport.width / Gdx.graphics.width), + y = Gdx.input.y * (viewport.height / Gdx.graphics.height) + ) + } + + companion object { + private const val CHEST_WINDOW_KEY = "chest" + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/windows/FurnaceWindowRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/windows/FurnaceWindowRenderer.kt index a963502..3037009 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/windows/FurnaceWindowRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/windows/FurnaceWindowRenderer.kt @@ -4,12 +4,10 @@ import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShapeRenderer import com.badlogic.gdx.math.Rectangle -import com.badlogic.gdx.utils.TimeUtils import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace import ru.deadsoftware.cavedroid.game.render.IGameRenderer import ru.deadsoftware.cavedroid.game.render.WindowsRenderer import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs diff --git a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt index 0a8ddf8..2f1d264 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt @@ -101,4 +101,24 @@ object GameWindowsConfigs { const val progressMarginTop = 34f const val progressWidth = 24f } + + data object Chest { + const val itemsGridMarginLeft = 8f + const val itemsGridMarginTop = 86f + + const val itemsGridRowHeight = 18f + const val itemsGridColWidth = 18f + + const val hotbarCells = 9 + const val hotbarOffsetFromBottom = 24f + + const val itemsInRow = 9 + const val itemsInCol = 5 + + const val contentsMarginLeft = 8f + const val contentsMarginTop = 18f + + const val contentsInRow = 9 + const val contentsInCol = 3 + } } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt index 1b6611a..32494ed 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt @@ -3,8 +3,9 @@ package ru.deadsoftware.cavedroid.game.ui.windows import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.objects.container.Chest import ru.deadsoftware.cavedroid.game.objects.drop.DropController -import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace +import ru.deadsoftware.cavedroid.game.objects.container.Furnace import ru.deadsoftware.cavedroid.game.ui.TooltipManager import ru.deadsoftware.cavedroid.game.ui.windows.inventory.* import javax.inject.Inject @@ -38,6 +39,10 @@ class GameWindowsManager @Inject constructor( currentWindow = FurnaceInventoryWindow(furnace) } + fun openChest(chest: Chest) { + currentWindow = ChestInventoryWindow(chest) + } + fun openCrafting() { currentWindow = CraftingInventoryWindow() } diff --git a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/ChestInventoryWindow.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/ChestInventoryWindow.kt new file mode 100644 index 0000000..6f4a4fe --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/ChestInventoryWindow.kt @@ -0,0 +1,13 @@ +package ru.deadsoftware.cavedroid.game.ui.windows.inventory + +import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem +import ru.deadsoftware.cavedroid.game.objects.container.Chest + +class ChestInventoryWindow(val chest: Chest) : AbstractInventoryWindow() { + + override val type = GameUiWindow.CHEST + + override var selectedItem: InventoryItem? = null + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/FurnaceInventoryWindow.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/FurnaceInventoryWindow.kt index 5adaac6..42f7038 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/FurnaceInventoryWindow.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/FurnaceInventoryWindow.kt @@ -2,7 +2,7 @@ package ru.deadsoftware.cavedroid.game.ui.windows.inventory import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.model.item.InventoryItem -import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace +import ru.deadsoftware.cavedroid.game.objects.container.Furnace class FurnaceInventoryWindow( val furnace: Furnace, diff --git a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java index 0d5a80a..c038f15 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java +++ b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java @@ -8,9 +8,10 @@ import ru.deadsoftware.cavedroid.game.model.block.Block; import ru.deadsoftware.cavedroid.game.model.item.InventoryItem; import ru.deadsoftware.cavedroid.game.model.item.Item; import ru.deadsoftware.cavedroid.game.model.world.generator.WorldGeneratorConfig; +import ru.deadsoftware.cavedroid.game.objects.container.Container; import ru.deadsoftware.cavedroid.game.objects.drop.DropController; -import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace; -import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController; +import ru.deadsoftware.cavedroid.game.objects.container.Furnace; +import ru.deadsoftware.cavedroid.game.objects.container.ContainerController; import ru.deadsoftware.cavedroid.misc.utils.MeasureUnitsUtilsKt; import javax.annotation.CheckForNull; @@ -19,10 +20,13 @@ import javax.inject.Inject; @GameScope public class GameWorld { + private static final int FOREGROUND_Z = 0; + private static final int BACKGROUND_Z = 1; + private final DropController mDropController; private final MobsController mMobsController; private final GameItemsHolder mGameItemsHolder; - private final FurnaceController mFurnaceController; + private final ContainerController mContainerController; private final int mWidth; private final int mHeight; @@ -35,13 +39,13 @@ public class GameWorld { public GameWorld(DropController dropController, MobsController mobsController, GameItemsHolder gameItemsHolder, - FurnaceController furnaceController, + ContainerController containerController, @CheckForNull Block[][] foreMap, @CheckForNull Block[][] backMap) { mDropController = dropController; mMobsController = mobsController; mGameItemsHolder = gameItemsHolder; - mFurnaceController = furnaceController; + mContainerController = containerController; boolean isNewGame = foreMap == null || backMap == null; @@ -129,6 +133,12 @@ public class GameWorld { return; } + mContainerController.destroyContainer(x, y, layer, false); + + if (value.isContainer()) { + mContainerController.addContainer(x, y, layer, (Class) value.getClass()); + } + if (layer == 0) { mForeMap[x][y] = value; } else { @@ -146,19 +156,19 @@ public class GameWorld { } public boolean hasForeAt(int x, int y) { - return getMap(x, y, 0) != mGameItemsHolder.getFallbackBlock(); + return getMap(x, y, FOREGROUND_Z) != mGameItemsHolder.getFallbackBlock(); } public boolean hasBackAt(int x, int y) { - return getMap(x, y, 1) != mGameItemsHolder.getFallbackBlock(); + return getMap(x, y, BACKGROUND_Z) != mGameItemsHolder.getFallbackBlock(); } public Block getForeMap(int x, int y) { - return getMap(x, y, 0); + return getMap(x, y, FOREGROUND_Z); } public void setForeMap(int x, int y, Block block) { - setMap(x, y, 0, block); + setMap(x, y, FOREGROUND_Z, block); } public void resetForeMap(int x, int y) { @@ -166,20 +176,15 @@ public class GameWorld { } public Block getBackMap(int x, int y) { - return getMap(x, y, 1); + return getMap(x, y, BACKGROUND_Z); } public void setBackMap(int x, int y, Block block) { - setMap(x, y, 1, block); + setMap(x, y, BACKGROUND_Z, block); } public boolean placeToForeground(int x, int y, Block value) { if (!hasForeAt(x, y) || value == mGameItemsHolder.getFallbackBlock() || !getForeMap(x, y).hasCollision()) { - - if (value.isFurnace()) { - mFurnaceController.addFurnace(x, y, 0); - } - setForeMap(x, y, value); return true; } else if (value instanceof Block.Slab && isSameSlab(value, getForeMap(x, y))) { @@ -191,10 +196,7 @@ public class GameWorld { public boolean placeToBackground(int x, int y, Block value) { if (value == mGameItemsHolder.getFallbackBlock() || (getBackMap(x, y) == mGameItemsHolder.getFallbackBlock() && value.hasCollision()) && - (!value.isTransparent() || value == mGameItemsHolder.getBlock("glass"))) { - if (value.isFurnace()) { - mFurnaceController.addFurnace(x, y, 1); - } + (!value.isTransparent() || value == mGameItemsHolder.getBlock("glass") || value.isChest() || value.isSlab())) { setBackMap(x, y, value); return true; } @@ -219,8 +221,8 @@ public class GameWorld { public void destroyForeMap(int x, int y) { Block block = getForeMap(x, y); - if (block.isFurnace()) { - mFurnaceController.destroyFurnace(x, y, 0, mDropController); + if (block.isContainer()) { + mContainerController.destroyContainer(x, y, FOREGROUND_Z); } if (block.hasDrop() && shouldDrop(block)) { for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) { @@ -237,9 +239,6 @@ public class GameWorld { public void destroyBackMap(int x, int y) { Block block = getBackMap(x, y); - if (block.isFurnace()) { - mFurnaceController.destroyFurnace(x, y, 0, mDropController); - } if (block.hasDrop() && shouldDrop(block)) { for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) { mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, mGameItemsHolder.getItem(block.getDrop())); @@ -249,13 +248,42 @@ public class GameWorld { placeToBackground(x, y, mGameItemsHolder.getFallbackBlock()); } + @CheckForNull + private Container getContainerAt(int x, int y, int z) { + return mContainerController.getContainer(transformX(x), y, z); + } + + @CheckForNull + public Container getForegroundContainer(int x, int y) { + return getContainerAt(x, y, FOREGROUND_Z); + } + + @CheckForNull + public Container getBackgroundContainer(int x, int y) { + return getContainerAt(x, y, BACKGROUND_Z); + } + @CheckForNull public Furnace getForegroundFurnace(int x, int y) { - return mFurnaceController.getFurnace(x, y, 0); + @CheckForNull + final Container container = getForegroundContainer(x, y); + + if (container instanceof Furnace) { + return (Furnace) container; + } + + return null; } @CheckForNull public Furnace getBackgroundFurnace(int x, int y) { - return mFurnaceController.getFurnace(x, y, 1); + @CheckForNull + final Container container = getBackgroundContainer(x, y); + + if (container instanceof Furnace) { + return (Furnace) container; + } + + return null; } } \ No newline at end of file