From cb0605053ce3de493b0d1f43cd7ec1e4a9cf0ac5 Mon Sep 17 00:00:00 2001 From: fredboy Date: Fri, 10 May 2024 22:20:13 +0700 Subject: [PATCH] Add chest --- android/assets/chest.png | Bin 3075 -> 2940 bytes android/assets/chest_large.png | Bin 0 -> 3075 bytes android/assets/json/game_items.json | 21 +++ android/assets/json/texture_regions.json | 6 + android/assets/textures/blocks/chest.png | Bin 0 -> 442 bytes .../cavedroid/game/GameModule.java | 12 +- .../deadsoftware/cavedroid/game/GameProc.java | 10 +- .../cavedroid/game/GameSaver.java | 34 +++-- .../game/actions/UseBlockActionsModule.kt | 9 ++ .../game/actions/useblock/UseChestAction.kt | 26 ++++ .../game/actions/useblock/UseFurnaceAction.kt | 6 +- .../game/debug/DebugInfoStringsProvider.kt | 5 +- .../game/input/MouseInputHandlersModule.kt | 7 + .../keyboard/PauseGameKeyboardInputHandler.kt | 6 +- .../mouse/CloseGameWindowMouseInputHandler.kt | 2 + ...lectChestInventoryItemMouseInputHandler.kt | 131 ++++++++++++++++++ ...ctFurnaceInventoryItemMouseInputHandler.kt | 25 ++-- .../cavedroid/game/model/block/Block.kt | 18 ++- .../game/model/item/InventoryItem.kt | 4 +- .../game/model/mapper/BlockMapper.kt | 1 + .../cavedroid/game/objects/container/Chest.kt | 14 ++ .../game/objects/container/Container.kt | 24 ++++ .../objects/container/ContainerController.kt | 86 ++++++++++++ .../objects/{furnace => container}/Furnace.kt | 51 ++++--- .../game/objects/furnace/FurnaceController.kt | 43 ------ .../cavedroid/game/render/BlocksRenderer.kt | 4 +- .../cavedroid/game/render/WindowsRenderer.kt | 7 +- .../render/windows/ChestWindowRenderer.kt | 93 +++++++++++++ .../render/windows/FurnaceWindowRenderer.kt | 2 - .../game/ui/windows/GameWindowsConfigs.kt | 20 +++ .../game/ui/windows/GameWindowsManager.kt | 7 +- .../windows/inventory/ChestInventoryWindow.kt | 13 ++ .../inventory/FurnaceInventoryWindow.kt | 2 +- .../cavedroid/game/world/GameWorld.java | 82 +++++++---- 34 files changed, 617 insertions(+), 154 deletions(-) create mode 100644 android/assets/chest_large.png create mode 100644 android/assets/textures/blocks/chest.png create mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseChestAction.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectChestInventoryItemMouseInputHandler.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/objects/container/Chest.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/objects/container/Container.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/objects/container/ContainerController.kt rename core/src/ru/deadsoftware/cavedroid/game/objects/{furnace => container}/Furnace.kt (71%) delete mode 100644 core/src/ru/deadsoftware/cavedroid/game/objects/furnace/FurnaceController.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/render/windows/ChestWindowRenderer.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/ChestInventoryWindow.kt diff --git a/android/assets/chest.png b/android/assets/chest.png index 961891f208d6ec2683ac56668344b7f7e5eb69b3..2c6d0c6b69b62d25ab98655cf0093ecd56e87269 100644 GIT binary patch literal 2940 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 Sx6xAhV@9L6ItsUQlK%;hhk{4| diff --git a/android/assets/chest_large.png b/android/assets/chest_large.png new file mode 100644 index 0000000000000000000000000000000000000000..961891f208d6ec2683ac56668344b7f7e5eb69b3 GIT binary patch literal 3075 zcmeHJdpK0<8eeP8Ow7n}8?@Om#Y~fHTNk9us*Ew2H0`l5VV;p&E<+85P!=JIh+;=F zR7x_4uw61dJ9ODhx=1#osE9Oe(`7`?%-Nm&bpAU3pR>Q`ThI5d_qV?Fyz716-|t%) z3|Fc;&Hx7hfI7|D@kamv6($I%q7+N$HBUFif)3iYYa0O6W~(-`S*}zz%OjM-;)aLBL`9y=Oh13FK!N@}{?5Sva0X(8YW_;1ME&T>T>SqY0P~{? zQBi8_0cTbu0Q^Iwyugsh8CZqWAd2D{#f%7yit*(I01V&Y@F*)+iW`By)@r@g4{O%Q zc%=ZK5=3*{<`&C-Q+y)7Y@;USZF*MkV&VbG)rT}VY%-?;M-J-Srd5%R?vlNRq8_H5*&Xpqa*ZmQBM|y~2w|Yg)0sEh1z~+MA_E^K+J`$AZaN zO;qe~#?{}VH3jOs7vmDYP_+oM@Mf;m4&oV4q=!%MyA?erL%w8Qm-}HS-uSh8TbtYo zO$gCop!D0s9hC(MLS*U_waME`ZaTl#*kaVIYBA3$2IJV5a2=4#61Of*s7HKbH)=i6 z9Sl3Bsw;>eMeUF{8XVWhdXd%}M>sF{!%TF&{C$qp-)ir<T?tXXV#IUgZv6%!Y0w41SLNj0IQDZ@RwZqtnz-^Hz78BKT{vMJa`S!#jgQZn zi#x*4aQ?2VLGiwLTu%A(NaOCaV0+gi(-xfgNVb2&*7^;XEC)Rhy8YRuO4B|Qnd}*O zdb+{X8%Sd#?jS|pV|{)0l_PqzSZ>pGy2p$e%sor@(YD}l=}wrX_V;%?u}$5bc>b%+ zuURm!>@151dU>g5_7ut-eC|vIxUJsl_1OE z!PzT2J24ZbfzRLVb6Y65=#8ysKWrezt7^Vus#u&cb7@e9SE14a+R<|K<(-WdlLJkK z{*68`CbL2^_VVk!Ey%MQFiZ;Wvv!$VuSm>pARL)JES*H31_{gTiV)WMFW3C|JEj$T zFV+EV22`z{S0%maY3EiHMT9=h9mf3LZzR|Z7nUq>o;UEwo3S2oDYOU2M=q$Rw_f48{M9fFgpMZ|o~Uf{=w~79tP83iT))Lgzz%D;5?Og* z_eEAPTh8o&o;&f_qFIiIHghIQPv9{| zPHxlr2Ft^W#A;$Qf#TDIJeRO&K2a^*@b*EMeVFeHWyY@WwZyw_eNZoEiKsH9{^bXC zBI@lhD(caTA={l5aYx(Y;JLt*W&Y-C!G==xp%eN!TgqTiW3jE~OhcG(hlV(t%mBW` z`{HlZ1cz?sCk@(SNSZCBl6IR#38isxh5(z{`6R8Jbu5Vh-?!XoiMCTMe|zlU;^^AC z59U<7AbS4NLc5hTm-0E=j4^rCL zv1n42?Yz*$I=SqT|4&mHdI(>ay``@2FuXsZUy`4q)P`zfcX~WLWpc7%d<{gJBPk02 zgYH2dWSE4@$+EP)(if=IgKzyh9NWq7s-WY9EvNY916!?iEC|wHjzpI|a;{GFCN-;Y zMlaO_*I$-KWJDzmNX)b?MO{85sGH9wHP?Af9t%+L=kcn)$`Z>2$pL!@W`)psqm?&= z@?Drs51IpU6XtMr*B&(Y_UzGzkJq}5HxGhd1ant#1 zEpeeDRJ58%YW`>IDp@_;MeKk^KwP?xl$3%Mh4W)O(Fvv5%g_D$Ap3N@`$A-kSFz6? z@NycoW~(J0kq4Io_japcI7jx9f!PP!!JkX?aH9Eo2JrH7>VJRa#W-}ceNpAwM}ZMH Sx6xAhV@9L6ItsUQlK%;hhk{4| literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..a2ca371c7f13ffaa44486cdea72e334f857dafb1 GIT binary patch literal 442 zcmV;r0Y(0aP)j*R5KeysPI&1N{~ z$n$)!=fNaN0MIHDvQ`n<(S&ql0?cy(`aY?u3IKDOkd6#D4+YLS0F+W(T213RUSHpY z3$Wv$cxeG}&S9;^S}Q_+oE-;BDRFVf57@S?klME8*$sq~B#Hd#1C(V+S(efnAdX`Z zh~t>~d@f?1D*{(%hv;Y+Z2dNWVLL944Ou!4M!8-rHcQNoCK%mAtB8EDL@6a*yHdcU)RcI!dL^i;W|rdve-7fR2U&PLctQGjenPp;!%RTu0-=MuCH9uqhkYZ3+A= z^u!(ju&maC_qP7Ctk!hv4~kVyI*v)lF~4yievyFyK;3-ObZ^wn=gu2IxBmEhgnY3K k&gg5O1KdA7%PD<)1Na83NDZbEi2wiq07*qoM6N<$f-?KRBLDyZ literal 0 HcmV?d00001 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 -- 2.29.2