From: fredboy <fredboy@protonmail.com>
Date: Tue, 7 May 2024 20:43:29 +0000 (+0700)
Subject: Add tooltips
X-Git-Tag: alpha0.8.0~7
X-Git-Url: http://deadsoftware.ru/gitweb?a=commitdiff_plain;h=13157246344c2b94d24354040f0f2d2fb5beb7ea;p=cavedroid.git

Add tooltips
---

diff --git a/android/assets/textures/items/charcoal.png b/android/assets/textures/items/charcoal.png
new file mode 100644
index 0000000..9fe49a7
Binary files /dev/null and b/android/assets/textures/items/charcoal.png differ
diff --git a/android/assets/textures/items/coal.png b/android/assets/textures/items/coal.png
new file mode 100644
index 0000000..c94ebad
Binary files /dev/null and b/android/assets/textures/items/coal.png differ
diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameModule.java b/core/src/ru/deadsoftware/cavedroid/game/GameModule.java
index 29175da..fbbd294 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/GameModule.java
+++ b/core/src/ru/deadsoftware/cavedroid/game/GameModule.java
@@ -6,6 +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.DropController;
+import ru.deadsoftware.cavedroid.game.ui.TooltipManager;
 import ru.deadsoftware.cavedroid.game.world.GameWorld;
 
 import javax.annotation.CheckForNull;
@@ -44,11 +45,15 @@ public class GameModule {
 
     @Provides
     @GameScope
-    public static MobsController provideMobsController(MainConfig mainConfig, GameItemsHolder gameItemsHolder) {
+    public static MobsController provideMobsController(MainConfig mainConfig,
+                                                       GameItemsHolder gameItemsHolder,
+                                                       TooltipManager tooltipManager) {
         load(mainConfig, gameItemsHolder);
-        MobsController controller = data != null ? data.retrieveMobsController() : new MobsController(gameItemsHolder);
+        MobsController controller = data != null
+                ? data.retrieveMobsController()
+                : new MobsController(gameItemsHolder, tooltipManager);
         makeDataNullIfEmpty();
-        controller.getPlayer().initInventory(gameItemsHolder);
+        controller.getPlayer().initInventory(gameItemsHolder, tooltipManager);
         return controller;
     }
 
diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java
index 35f318a..4b418a7 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java
+++ b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java
@@ -1,8 +1,12 @@
 package ru.deadsoftware.cavedroid.game;
 
 import com.badlogic.gdx.Gdx;
+import com.badlogic.gdx.graphics.Color;
 import com.badlogic.gdx.graphics.GL20;
 import com.badlogic.gdx.math.Rectangle;
+import com.badlogic.gdx.scenes.scene2d.ui.Label;
+import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
+import com.badlogic.gdx.utils.Align;
 import com.badlogic.gdx.utils.ObjectMap;
 import ru.deadsoftware.cavedroid.MainConfig;
 import ru.deadsoftware.cavedroid.game.input.IGameInputHandler;
@@ -16,7 +20,8 @@ import ru.deadsoftware.cavedroid.game.mobs.MobsController;
 import ru.deadsoftware.cavedroid.game.mobs.player.Player;
 import ru.deadsoftware.cavedroid.game.objects.TouchButton;
 import ru.deadsoftware.cavedroid.game.render.IGameRenderer;
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager;
+import ru.deadsoftware.cavedroid.game.ui.TooltipManager;
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager;
 import ru.deadsoftware.cavedroid.misc.Assets;
 import ru.deadsoftware.cavedroid.misc.Renderer;
 
@@ -41,6 +46,7 @@ public class GameRenderer extends Renderer {
     private final Set<IGameInputHandler<MouseInputAction>> mMouseInputHandlers;
     private final Set<IGameInputHandler<KeyboardInputAction>> mKeyboardInputHandlers;
     private final GameWindowsManager mGameWindowsManager;
+    private final TooltipManager mTooltipManager;
 
     @Inject
     GameRenderer(MainConfig mainConfig,
@@ -51,7 +57,8 @@ public class GameRenderer extends Renderer {
                  KeyboardInputActionMapper keyboardInputActionMapper,
                  Set<IGameInputHandler<MouseInputAction>> mouseInputHandlers,
                  Set<IGameInputHandler<KeyboardInputAction>> keyboardInputHandlers,
-                 GameWindowsManager gameWindowsManager) {
+                 GameWindowsManager gameWindowsManager,
+                 TooltipManager tooltipManager) {
         super(mainConfig.getWidth(), mainConfig.getHeight());
 
         mMainConfig = mainConfig;
@@ -64,6 +71,7 @@ public class GameRenderer extends Renderer {
         mMouseInputHandlers = mouseInputHandlers;
         mKeyboardInputHandlers = keyboardInputHandlers;
         mGameWindowsManager = gameWindowsManager;
+        mTooltipManager = tooltipManager;
 
         Gdx.gl.glClearColor(0f, .6f, .6f, 1f);
     }
@@ -86,13 +94,28 @@ public class GameRenderer extends Renderer {
 
     private void handleMousePosition() {
         final Rectangle viewport = getCameraViewport();
+
+        final float screenX = transformScreenX(Gdx.input.getX());
+        final float screenY = transformScreenY(Gdx.input.getY());
+
         final MouseInputAction action = new MouseInputAction(
-                Gdx.input.getX() * (viewport.width / Gdx.graphics.getWidth()),
-                Gdx.input.getY() * (viewport.height / Gdx.graphics.getHeight()),
+                screenX,
+                screenY,
                 MouseInputActionKey.None.INSTANCE,
                 viewport);
 
         mCursorMouseInputHandler.handle(action);
+
+        if (!mTooltipManager.getCurrentMouseTooltip().isEmpty()) {
+            final Label.LabelStyle style = new Label.LabelStyle(Assets.minecraftFont, Color.WHITE);
+            style.background = new TextureRegionDrawable(Assets.textureRegions.get("background"));
+            final Label label = new Label(mTooltipManager.getCurrentMouseTooltip(), style);
+            label.setX(screenX);
+            label.setY(screenY);
+//            label.setHeight(10f);
+//            label.setAlignment(Align.left, Align.top);
+            label.draw(spriter, 1f);
+        }
     }
 
     private boolean handleMouseAction(@CheckForNull  MouseInputAction action) {
@@ -226,14 +249,14 @@ public class GameRenderer extends Renderer {
     @Override
     public void render(float delta) {
         updateCameraPosition();
-        handleMousePosition();
-//        mGameInput.moveCursor(this);
 
         Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
 
         spriter.begin();
         mRenderers.forEach(iGameRenderer -> iGameRenderer.draw(spriter, shaper, getCameraViewport(), delta));
+        handleMousePosition();
         spriter.end();
+
     }
 
 }
diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt
index 7c41364..3ce42b9 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseCraftingTableAction.kt
@@ -2,7 +2,7 @@ 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.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 import javax.inject.Inject
 
 @GameScope
diff --git a/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt b/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt
index f34903b..0886a07 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt
@@ -20,7 +20,7 @@ class DebugInfoStringsProvider @Inject constructor(
         return listOf(
             "FPS: ${Gdx.graphics.framesPerSecond}",
             "X: ${player.mapX}",
-            "Y: ${gameWorld.height - player.upperMapY}",
+            "Y: ${player.upperMapY} (${gameWorld.height - player.upperMapY})",
             "CurX: ${player.cursorX}",
             "CurY: ${player.cursorY}",
             "Velocity: ${player.velocity}",
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/KeyboardInputHandlersModule.kt b/core/src/ru/deadsoftware/cavedroid/game/input/KeyboardInputHandlersModule.kt
index 0a33d93..a58e522 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/KeyboardInputHandlersModule.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/KeyboardInputHandlersModule.kt
@@ -129,4 +129,11 @@ object KeyboardInputHandlersModule {
         return handler
     }
 
+    @Binds
+    @IntoSet
+    @GameScope
+    fun bindSelectHotbarSlotKeyboardInputHandler(handler: SelectHotbarSlotKeyboardInputHandler): IGameInputHandler<KeyboardInputAction> {
+        return handler
+    }
+
 }
\ No newline at end of file
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/action/keys/KeyboardInputActionKey.kt b/core/src/ru/deadsoftware/cavedroid/game/input/action/keys/KeyboardInputActionKey.kt
index 89ff506..fd14fc4 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/action/keys/KeyboardInputActionKey.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/action/keys/KeyboardInputActionKey.kt
@@ -21,4 +21,8 @@ sealed interface KeyboardInputActionKey {
     data object SpawnPig : KeyboardInputActionKey
     data object SwitchGameMode : KeyboardInputActionKey
     data object ShowMap : KeyboardInputActionKey
+
+    data class SelectHotbarSlot(
+        val slot: Int
+    ) : KeyboardInputActionKey
 }
\ No newline at end of file
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt
index 705f9aa..b2d1244 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt
@@ -7,7 +7,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.DropController
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 import javax.inject.Inject
 
 @GameScope
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt
index 7e6454c..4003271 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt
@@ -9,7 +9,7 @@ import ru.deadsoftware.cavedroid.game.mobs.MobsController
 import ru.deadsoftware.cavedroid.game.model.item.Item
 import ru.deadsoftware.cavedroid.game.objects.Drop
 import ru.deadsoftware.cavedroid.game.objects.DropController
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 import javax.inject.Inject
 
 @GameScope
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt
index 0e2c11b..50aa5b0 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt
@@ -7,7 +7,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.DropController
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 import javax.inject.Inject
 
 @GameScope
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SelectHotbarSlotKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SelectHotbarSlotKeyboardInputHandler.kt
new file mode 100644
index 0000000..45e04da
--- /dev/null
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/SelectHotbarSlotKeyboardInputHandler.kt
@@ -0,0 +1,24 @@
+package ru.deadsoftware.cavedroid.game.input.handler.keyboard
+
+import ru.deadsoftware.cavedroid.game.GameScope
+import ru.deadsoftware.cavedroid.game.input.IGameInputHandler
+import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction
+import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey
+import ru.deadsoftware.cavedroid.game.mobs.MobsController
+import javax.inject.Inject
+
+@GameScope
+class SelectHotbarSlotKeyboardInputHandler @Inject constructor(
+    private val mobsController: MobsController,
+) : IGameInputHandler<KeyboardInputAction> {
+
+    override fun checkConditions(action: KeyboardInputAction): Boolean {
+        return action.actionKey is KeyboardInputActionKey.SelectHotbarSlot &&
+                action.isKeyDown
+    }
+
+    override fun handle(action: KeyboardInputAction) {
+        mobsController.player.inventory.activeSlot = (action.actionKey as KeyboardInputActionKey.SelectHotbarSlot).slot
+    }
+
+}
\ No newline at end of file
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt
index a0bfa4c..2afc3d5 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/AttackMouseInputHandler.kt
@@ -7,7 +7,7 @@ import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction
 import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey
 import ru.deadsoftware.cavedroid.game.input.isInsideHotbar
 import ru.deadsoftware.cavedroid.game.mobs.MobsController
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 import ru.deadsoftware.cavedroid.game.world.GameWorld
 import javax.inject.Inject
 
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 e80ff47..bee22dc 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
@@ -3,7 +3,7 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse
 import com.badlogic.gdx.graphics.g2d.TextureRegion
 import ru.deadsoftware.cavedroid.game.GameScope
 import ru.deadsoftware.cavedroid.game.GameUiWindow
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 import ru.deadsoftware.cavedroid.game.input.IGameInputHandler
 import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction
 import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt
index 01cc4e2..352d04b 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CreativeInventoryScrollMouseInputHandler.kt
@@ -5,7 +5,7 @@ import ru.deadsoftware.cavedroid.MainConfig
 import ru.deadsoftware.cavedroid.game.GameItemsHolder
 import ru.deadsoftware.cavedroid.game.GameScope
 import ru.deadsoftware.cavedroid.game.GameUiWindow
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 import ru.deadsoftware.cavedroid.game.input.IGameInputHandler
 import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction
 import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt
index 062859c..6a4b5a4 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CursorMouseInputHandler.kt
@@ -2,7 +2,9 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse
 
 import com.badlogic.gdx.math.MathUtils
 import ru.deadsoftware.cavedroid.MainConfig
+import ru.deadsoftware.cavedroid.game.GameItemsHolder
 import ru.deadsoftware.cavedroid.game.GameScope
+import ru.deadsoftware.cavedroid.game.GameUiWindow
 import ru.deadsoftware.cavedroid.game.input.IGameInputHandler
 import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction
 import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey
@@ -10,7 +12,11 @@ import ru.deadsoftware.cavedroid.game.mobs.Mob
 import ru.deadsoftware.cavedroid.game.mobs.MobsController
 import ru.deadsoftware.cavedroid.game.mobs.player.Player
 import ru.deadsoftware.cavedroid.game.model.block.Block
+import ru.deadsoftware.cavedroid.game.ui.TooltipManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 import ru.deadsoftware.cavedroid.game.world.GameWorld
+import ru.deadsoftware.cavedroid.misc.Assets
 import ru.deadsoftware.cavedroid.misc.utils.bl
 import ru.deadsoftware.cavedroid.misc.utils.px
 import javax.inject.Inject
@@ -20,10 +26,15 @@ class CursorMouseInputHandler @Inject constructor(
     private val mainConfig: MainConfig,
     private val mobsController: MobsController,
     private val gameWorld: GameWorld,
+    private val gameWindowsManager: GameWindowsManager,
+    private val gameItemsHolder: GameItemsHolder,
+    private val tooltipManager: TooltipManager,
 ) : IGameInputHandler<MouseInputAction> {
 
     private val player get() = mobsController.player
 
+    private val creativeInventoryTexture get() = requireNotNull(Assets.textureRegions["creative"])
+
     private val Block.isAutoselectable
         get() = !isNone() && params.hasCollision
 
@@ -92,6 +103,27 @@ class CursorMouseInputHandler @Inject constructor(
         player.headRotation = getPlayerHeadRotation(worldX, worldY)
     }
 
+    private fun getCreativeTooltip(action: MouseInputAction): String? {
+        val creativeTexture = creativeInventoryTexture
+        val xOnGrid = (action.screenX - (action.cameraViewport.width / 2 - creativeTexture.regionWidth / 2 +
+                GameWindowsConfigs.Creative.itemsGridMarginLeft)) /
+                GameWindowsConfigs.Creative.itemsGridColWidth
+        val yOnGrid = (action.screenY - (action.cameraViewport.height / 2 - creativeTexture.regionHeight / 2 +
+                GameWindowsConfigs.Creative.itemsGridMarginTop)) /
+                GameWindowsConfigs.Creative.itemsGridRowHeight
+
+        if (xOnGrid < 0 || xOnGrid >= GameWindowsConfigs.Creative.itemsInRow ||
+            yOnGrid < 0 || yOnGrid >= GameWindowsConfigs.Creative.itemsInCol) {
+            return null
+        }
+
+        val itemIndex = (gameWindowsManager.creativeScrollAmount * GameWindowsConfigs.Creative.itemsInRow +
+                (xOnGrid.toInt() + yOnGrid.toInt() * GameWindowsConfigs.Creative.itemsInRow))
+        val item = gameItemsHolder.getItemFromCreativeInventory(itemIndex)
+
+        return item.params.name
+    }
+
     override fun checkConditions(action: MouseInputAction): Boolean {
         return action.actionKey is MouseInputActionKey.None
     }
@@ -111,6 +143,10 @@ class CursorMouseInputHandler @Inject constructor(
         if (player.cursorX != pastCursorX || player.cursorY != pastCursorY) {
             player.blockDamage = 0f
         }
+
+        if (gameWindowsManager.getCurrentWindow() == GameUiWindow.CREATIVE_INVENTORY) {
+            tooltipManager.showMouseTooltip(getCreativeTooltip(action).orEmpty())
+        }
     }
 
     companion object {
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt
index c7f54ac..0725abe 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt
@@ -3,7 +3,7 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse
 import com.badlogic.gdx.utils.Timer
 import ru.deadsoftware.cavedroid.game.GameScope
 import ru.deadsoftware.cavedroid.game.GameUiWindow
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 import ru.deadsoftware.cavedroid.game.input.IGameInputHandler
 import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction
 import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt
index 4395337..89c0ce1 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt
@@ -10,9 +10,9 @@ 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.windows.GameWindowsConfigs
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
-import ru.deadsoftware.cavedroid.game.windows.inventory.CraftingInventoryWindow
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.inventory.CraftingInventoryWindow
 import ru.deadsoftware.cavedroid.misc.Assets
 import javax.inject.Inject
 
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt
index 032bade..9ccbf6e 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCreativeInventoryItemMouseInputHandler.kt
@@ -3,13 +3,13 @@ package ru.deadsoftware.cavedroid.game.input.handler.mouse
 import ru.deadsoftware.cavedroid.game.GameItemsHolder
 import ru.deadsoftware.cavedroid.game.GameScope
 import ru.deadsoftware.cavedroid.game.GameUiWindow
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 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.windows.GameWindowsConfigs
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs
 import ru.deadsoftware.cavedroid.misc.Assets
 import javax.inject.Inject
 
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt
index 828f02f..ab65fb8 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt
@@ -10,9 +10,9 @@ 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.windows.GameWindowsConfigs
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
-import ru.deadsoftware.cavedroid.game.windows.inventory.SurvivalInventoryWindow
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.inventory.SurvivalInventoryWindow
 import ru.deadsoftware.cavedroid.misc.Assets
 import javax.inject.Inject
 
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt
index da59bc6..04bc619 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/UseItemMouseInputHandler.kt
@@ -15,7 +15,7 @@ import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey
 import ru.deadsoftware.cavedroid.game.input.isInsideHotbar
 import ru.deadsoftware.cavedroid.game.mobs.MobsController
 import ru.deadsoftware.cavedroid.game.model.item.Item
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 import ru.deadsoftware.cavedroid.game.world.GameWorld
 import javax.inject.Inject
 
diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/mapper/KeyboardInputActionMapper.kt b/core/src/ru/deadsoftware/cavedroid/game/input/mapper/KeyboardInputActionMapper.kt
index 61e9793..8d18d07 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/input/mapper/KeyboardInputActionMapper.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/input/mapper/KeyboardInputActionMapper.kt
@@ -27,6 +27,16 @@ class KeyboardInputActionMapper @Inject constructor() {
 
             Input.Keys.Q -> KeyboardInputActionKey.DropItem
 
+            Input.Keys.NUM_1 -> KeyboardInputActionKey.SelectHotbarSlot(0)
+            Input.Keys.NUM_2 -> KeyboardInputActionKey.SelectHotbarSlot(1)
+            Input.Keys.NUM_3 -> KeyboardInputActionKey.SelectHotbarSlot(2)
+            Input.Keys.NUM_4 -> KeyboardInputActionKey.SelectHotbarSlot(3)
+            Input.Keys.NUM_5 -> KeyboardInputActionKey.SelectHotbarSlot(4)
+            Input.Keys.NUM_6 -> KeyboardInputActionKey.SelectHotbarSlot(5)
+            Input.Keys.NUM_7 -> KeyboardInputActionKey.SelectHotbarSlot(6)
+            Input.Keys.NUM_8 -> KeyboardInputActionKey.SelectHotbarSlot(7)
+            Input.Keys.NUM_9 -> KeyboardInputActionKey.SelectHotbarSlot(8)
+
             else -> null
         }
 
diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/MobsController.kt b/core/src/ru/deadsoftware/cavedroid/game/mobs/MobsController.kt
index df2a6de..158d22a 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/mobs/MobsController.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/MobsController.kt
@@ -3,19 +3,21 @@ package ru.deadsoftware.cavedroid.game.mobs
 import ru.deadsoftware.cavedroid.game.GameItemsHolder
 import ru.deadsoftware.cavedroid.game.GameScope
 import ru.deadsoftware.cavedroid.game.mobs.player.Player
+import ru.deadsoftware.cavedroid.game.ui.TooltipManager
 import java.io.Serializable
 import java.util.*
 import javax.inject.Inject
 
 @GameScope
 class MobsController @Inject constructor(
-    gameItemsHolder: GameItemsHolder
+    gameItemsHolder: GameItemsHolder,
+    tooltipManager: TooltipManager,
 ) : Serializable {
 
     private val _mobs = LinkedList<Mob>()
 
     val player: Player =
-        Player(gameItemsHolder)
+        Player(gameItemsHolder, tooltipManager)
 
     val mobs: List<Mob>
         get() = _mobs
diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Inventory.kt b/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Inventory.kt
index b82aa44..44ee6dd 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Inventory.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Inventory.kt
@@ -4,19 +4,26 @@ import ru.deadsoftware.cavedroid.game.GameItemsHolder
 import ru.deadsoftware.cavedroid.game.model.item.InventoryItem
 import ru.deadsoftware.cavedroid.game.model.item.Item
 import ru.deadsoftware.cavedroid.game.objects.Drop
+import ru.deadsoftware.cavedroid.game.ui.TooltipManager
 import java.io.Serializable
 
 class Inventory(
     val size: Int,
     val hotbarSize: Int,
-    gameItemsHolder: GameItemsHolder
+    gameItemsHolder: GameItemsHolder,
+    tooltipManager: TooltipManager,
 ) : Serializable {
 
+    @Transient
+    private lateinit var tooltipManager: TooltipManager
+
     @Transient
     private lateinit var fallbackItem: InventoryItem
 
     init {
         fallbackItem = gameItemsHolder.fallbackItem.toInventoryItem()
+        this.tooltipManager = tooltipManager
+
         if (size < 0 || hotbarSize < 0 || hotbarSize > size) {
             throw IllegalArgumentException("Invalid inventory sizes: hotbarSize=$hotbarSize; size=$size")
         }
@@ -32,12 +39,18 @@ class Inventory(
         set(value) {
             if (value in 0 ..< hotbarSize) {
                 field = value
+                showCurrentItemTooltip()
             }
         }
 
+    fun showCurrentItemTooltip() {
+        tooltipManager.showHotbarTooltip(activeItem.item.params.name)
+    }
+
     val activeItem get() = items[activeSlot]
 
-    fun initItems(gameItemsHolder: GameItemsHolder) {
+    fun initItems(gameItemsHolder: GameItemsHolder, tooltipManager: TooltipManager) {
+        this.tooltipManager = tooltipManager
         fallbackItem = gameItemsHolder.fallbackItem.toInventoryItem()
         items.forEach { item ->
             item.init(gameItemsHolder)
@@ -70,11 +83,14 @@ class Inventory(
 
         if (inventoryItem.item == drop.item) {
             inventoryItem.add()
-            drop.pickedUp = true
         } else {
             _items[slot] = drop.item.toInventoryItem()
-            drop.pickedUp = true
+            if (slot == activeSlot) {
+                showCurrentItemTooltip()
+            }
         }
+
+        drop.pickedUp = true
     }
 
     fun addItem(item: Item) {
@@ -86,6 +102,7 @@ class Inventory(
         )
 
         _items[0] = item.toInventoryItem(item.params.maxStack)
+        showCurrentItemTooltip()
     }
 
     @JvmOverloads
diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Player.java b/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Player.java
index dcc77ef..241714a 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Player.java
+++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Player.java
@@ -10,6 +10,7 @@ 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.objects.Drop;
+import ru.deadsoftware.cavedroid.game.ui.TooltipManager;
 import ru.deadsoftware.cavedroid.game.world.GameWorld;
 import ru.deadsoftware.cavedroid.misc.Assets;
 import ru.deadsoftware.cavedroid.misc.utils.SpriteOrigin;
@@ -50,14 +51,14 @@ public class Player extends Mob {
         CURSOR
     }
 
-    public Player(GameItemsHolder gameItemsHolder) {
+    public Player(GameItemsHolder gameItemsHolder, TooltipManager tooltipManager) {
         super(0, 0, 4, 30, randomDir(), Type.MOB, MAX_HEALTH);
-        inventory = new Inventory(INVENTORY_SIZE, HOTBAR_SIZE, gameItemsHolder);
+        inventory = new Inventory(INVENTORY_SIZE, HOTBAR_SIZE, gameItemsHolder, tooltipManager);
         swim = false;
     }
 
-    public void initInventory(GameItemsHolder gameItemsHolder) {
-        inventory.initItems(gameItemsHolder);
+    public void initInventory(GameItemsHolder gameItemsHolder, TooltipManager tooltipManager) {
+        inventory.initItems(gameItemsHolder, tooltipManager);
     }
 
     public void respawn(GameWorld gameWorld, GameItemsHolder itemsHolder) {
diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/DropController.java b/core/src/ru/deadsoftware/cavedroid/game/objects/DropController.java
index 798a84c..639a2aa 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/objects/DropController.java
+++ b/core/src/ru/deadsoftware/cavedroid/game/objects/DropController.java
@@ -33,6 +33,12 @@ public class DropController implements Serializable {
         mDrops.add(new Drop(x, y, item));
     }
 
+    public void addDrop(float x, float y, Item item, int count) {
+        for (int i = 0 ; i < count; i++) {
+            addDrop(x, y, item);
+        }
+    }
+
     public int getSize() {
         return mDrops.size();
     }
diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt
index 1053a9f..a2570e2 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/render/HudRenderer.kt
@@ -7,8 +7,10 @@ import ru.deadsoftware.cavedroid.game.GameScope
 import ru.deadsoftware.cavedroid.game.mobs.MobsController
 import ru.deadsoftware.cavedroid.game.mobs.player.Player
 import ru.deadsoftware.cavedroid.game.mobs.player.Player.ControlMode
+import ru.deadsoftware.cavedroid.game.ui.TooltipManager
 import ru.deadsoftware.cavedroid.game.world.GameWorld
 import ru.deadsoftware.cavedroid.misc.Assets
+import ru.deadsoftware.cavedroid.misc.utils.drawString
 import ru.deadsoftware.cavedroid.misc.utils.px
 import javax.inject.Inject
 
@@ -16,6 +18,7 @@ import javax.inject.Inject
 class HudRenderer @Inject constructor(
     private val gameWorld: GameWorld,
     private val mobsController: MobsController,
+    private val tooltipManager: TooltipManager,
 ) : IGameRenderer {
 
     override val renderLayer = RENDER_LAYER
@@ -102,6 +105,15 @@ class HudRenderer @Inject constructor(
         drawHealth(spriteBatch, hotbarX, hotbarTexture.regionHeight.toFloat())
         drawHotbarSelector(spriteBatch, hotbarX)
         drawHotbarItems(spriteBatch, shapeRenderer, hotbarX)
+
+        val tooltip = tooltipManager.currentHotbarTooltip
+        if (tooltip.isNotBlank()) {
+            spriteBatch.drawString(
+                str = tooltip,
+                x = viewport.width / 2 - Assets.getStringWidth(tooltip) / 2,
+                y = hotbarTexture.regionHeight.toFloat()
+            )
+        }
     }
 
     override fun draw(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, viewport: Rectangle, delta: Float) {
diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt
index c768d5f..ad68bce 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/render/TouchControlsRenderer.kt
@@ -8,7 +8,7 @@ import ru.deadsoftware.cavedroid.game.GameScope
 import ru.deadsoftware.cavedroid.game.GameUiWindow
 import ru.deadsoftware.cavedroid.game.mobs.MobsController
 import ru.deadsoftware.cavedroid.game.mobs.player.Player.ControlMode
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 import ru.deadsoftware.cavedroid.misc.Assets
 import ru.deadsoftware.cavedroid.misc.utils.ArrayMapExtensions.component1
 import ru.deadsoftware.cavedroid.misc.utils.ArrayMapExtensions.component2
diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt
index 2fa093f..03df48f 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt
@@ -9,7 +9,7 @@ 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.SurvivalWindowRenderer
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 import javax.inject.Inject
 
 @GameScope
diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/windows/CraftingWindowRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/windows/CraftingWindowRenderer.kt
index cc8c1ba..6772282 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/render/windows/CraftingWindowRenderer.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/render/windows/CraftingWindowRenderer.kt
@@ -10,9 +10,9 @@ import ru.deadsoftware.cavedroid.game.GameScope
 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.windows.GameWindowsConfigs
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
-import ru.deadsoftware.cavedroid.game.windows.inventory.CraftingInventoryWindow
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.inventory.CraftingInventoryWindow
 import ru.deadsoftware.cavedroid.misc.Assets
 import javax.inject.Inject
 
diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/windows/CreativeWindowRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/windows/CreativeWindowRenderer.kt
index dede82f..6bfac42 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/render/windows/CreativeWindowRenderer.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/render/windows/CreativeWindowRenderer.kt
@@ -6,11 +6,11 @@ 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.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
 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.windows.GameWindowsConfigs
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs
 import ru.deadsoftware.cavedroid.misc.Assets
 import javax.inject.Inject
 import kotlin.math.min
diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/windows/SurvivalWindowRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/windows/SurvivalWindowRenderer.kt
index ef23be5..7ee3b27 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/render/windows/SurvivalWindowRenderer.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/render/windows/SurvivalWindowRenderer.kt
@@ -12,9 +12,9 @@ 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.windows.GameWindowsConfigs
-import ru.deadsoftware.cavedroid.game.windows.GameWindowsManager
-import ru.deadsoftware.cavedroid.game.windows.inventory.SurvivalInventoryWindow
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs
+import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
+import ru.deadsoftware.cavedroid.game.ui.windows.inventory.SurvivalInventoryWindow
 import ru.deadsoftware.cavedroid.misc.Assets
 import javax.inject.Inject
 import kotlin.math.atan
diff --git a/core/src/ru/deadsoftware/cavedroid/game/ui/TooltipManager.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/TooltipManager.kt
new file mode 100644
index 0000000..a8f5a9b
--- /dev/null
+++ b/core/src/ru/deadsoftware/cavedroid/game/ui/TooltipManager.kt
@@ -0,0 +1,41 @@
+package ru.deadsoftware.cavedroid.game.ui
+
+import com.badlogic.gdx.utils.Timer
+import ru.deadsoftware.cavedroid.MainConfig
+import ru.deadsoftware.cavedroid.game.GameScope
+import javax.inject.Inject
+
+@GameScope
+class TooltipManager @Inject constructor(
+    private val mainConfig: MainConfig
+) {
+
+    private val resetTask = object : Timer.Task() {
+        override fun run() {
+            currentHotbarTooltip = ""
+        }
+    }
+
+    var currentHotbarTooltip: String = ""
+        private set
+
+    var currentMouseTooltip: String = ""
+        private set
+
+    fun showHotbarTooltip(tooltip: String) {
+        currentHotbarTooltip = tooltip
+        if (resetTask.isScheduled) {
+            resetTask.cancel()
+        }
+        Timer.schedule(resetTask, TOOLTIP_TIME_S)
+    }
+
+    fun showMouseTooltip(tooltip: String) {
+        currentMouseTooltip = tooltip
+    }
+
+    companion object {
+        private const val TOOLTIP_TIME_S = 2f
+    }
+
+}
\ No newline at end of file
diff --git a/core/src/ru/deadsoftware/cavedroid/game/windows/GameWindowsConfigs.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt
similarity index 97%
rename from core/src/ru/deadsoftware/cavedroid/game/windows/GameWindowsConfigs.kt
rename to core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt
index a6cff63..8fa3fb2 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/windows/GameWindowsConfigs.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt
@@ -1,4 +1,4 @@
-package ru.deadsoftware.cavedroid.game.windows
+package ru.deadsoftware.cavedroid.game.ui.windows
 
 object GameWindowsConfigs {
     data object Creative {
diff --git a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt
new file mode 100644
index 0000000..56d92d6
--- /dev/null
+++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt
@@ -0,0 +1,64 @@
+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.DropController
+import ru.deadsoftware.cavedroid.game.ui.TooltipManager
+import ru.deadsoftware.cavedroid.game.ui.windows.inventory.AbstractInventoryWindow
+import ru.deadsoftware.cavedroid.game.ui.windows.inventory.CraftingInventoryWindow
+import ru.deadsoftware.cavedroid.game.ui.windows.inventory.CreativeInventoryWindow
+import ru.deadsoftware.cavedroid.game.ui.windows.inventory.SurvivalInventoryWindow
+import javax.inject.Inject
+
+@GameScope
+class GameWindowsManager @Inject constructor(
+    private val tooltipManager: TooltipManager,
+    private val mobsController: MobsController,
+    private val dropController: DropController,
+) {
+
+    var creativeScrollAmount = 0
+    var isDragging = false
+
+    var currentWindow: AbstractInventoryWindow? = null
+
+    @JvmName("getCurrentWindowType")
+    fun getCurrentWindow(): GameUiWindow {
+        return currentWindow?.type ?: GameUiWindow.NONE
+    }
+
+    fun openInventory() {
+        if (mobsController.player.gameMode == 1) {
+            currentWindow = CreativeInventoryWindow(GameUiWindow.CREATIVE_INVENTORY)
+        } else {
+            currentWindow = SurvivalInventoryWindow(GameUiWindow.SURVIVAL_INVENTORY)
+        }
+    }
+
+    fun openCrafting() {
+        currentWindow = CraftingInventoryWindow(GameUiWindow.CRAFTING_TABLE)
+    }
+
+    fun closeWindow() {
+        (currentWindow as? SurvivalInventoryWindow)?.let { window ->
+            window.craftingItems.forEach { item ->
+                item?.item?.let {
+                    dropController.addDrop(mobsController.player.x, mobsController.player.y, it, item.amount)
+                }
+            }
+        }
+
+        (currentWindow as? CraftingInventoryWindow)?.let { window ->
+            window.craftingItems.forEach { item ->
+                item?.item?.let {
+                    dropController.addDrop(mobsController.player.x, mobsController.player.y, it, item.amount)
+                }
+            }
+        }
+
+        currentWindow = null
+        tooltipManager.showMouseTooltip("")
+    }
+
+}
\ No newline at end of file
diff --git a/core/src/ru/deadsoftware/cavedroid/game/windows/inventory/AbstractInventoryWindow.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/AbstractInventoryWindow.kt
similarity index 79%
rename from core/src/ru/deadsoftware/cavedroid/game/windows/inventory/AbstractInventoryWindow.kt
rename to core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/AbstractInventoryWindow.kt
index 0660604..9d8e0f9 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/windows/inventory/AbstractInventoryWindow.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/AbstractInventoryWindow.kt
@@ -1,4 +1,4 @@
-package ru.deadsoftware.cavedroid.game.windows.inventory
+package ru.deadsoftware.cavedroid.game.ui.windows.inventory
 
 import ru.deadsoftware.cavedroid.game.GameUiWindow
 import ru.deadsoftware.cavedroid.game.model.item.InventoryItem
diff --git a/core/src/ru/deadsoftware/cavedroid/game/windows/inventory/CraftingInventoryWindow.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/CraftingInventoryWindow.kt
similarity index 86%
rename from core/src/ru/deadsoftware/cavedroid/game/windows/inventory/CraftingInventoryWindow.kt
rename to core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/CraftingInventoryWindow.kt
index 03808f1..13dbd83 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/windows/inventory/CraftingInventoryWindow.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/CraftingInventoryWindow.kt
@@ -1,4 +1,4 @@
-package ru.deadsoftware.cavedroid.game.windows.inventory
+package ru.deadsoftware.cavedroid.game.ui.windows.inventory
 
 import ru.deadsoftware.cavedroid.game.GameUiWindow
 import ru.deadsoftware.cavedroid.game.model.item.InventoryItem
diff --git a/core/src/ru/deadsoftware/cavedroid/game/windows/inventory/CreativeInventoryWindow.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/CreativeInventoryWindow.kt
similarity index 81%
rename from core/src/ru/deadsoftware/cavedroid/game/windows/inventory/CreativeInventoryWindow.kt
rename to core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/CreativeInventoryWindow.kt
index 5f72243..22a3d56 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/windows/inventory/CreativeInventoryWindow.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/CreativeInventoryWindow.kt
@@ -1,4 +1,4 @@
-package ru.deadsoftware.cavedroid.game.windows.inventory
+package ru.deadsoftware.cavedroid.game.ui.windows.inventory
 
 import ru.deadsoftware.cavedroid.game.GameUiWindow
 import ru.deadsoftware.cavedroid.game.model.item.InventoryItem
diff --git a/core/src/ru/deadsoftware/cavedroid/game/windows/inventory/SurvivalInventoryWindow.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/SurvivalInventoryWindow.kt
similarity index 86%
rename from core/src/ru/deadsoftware/cavedroid/game/windows/inventory/SurvivalInventoryWindow.kt
rename to core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/SurvivalInventoryWindow.kt
index 4eeba3c..685642c 100644
--- a/core/src/ru/deadsoftware/cavedroid/game/windows/inventory/SurvivalInventoryWindow.kt
+++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/SurvivalInventoryWindow.kt
@@ -1,4 +1,4 @@
-package ru.deadsoftware.cavedroid.game.windows.inventory
+package ru.deadsoftware.cavedroid.game.ui.windows.inventory
 
 import ru.deadsoftware.cavedroid.game.GameUiWindow
 import ru.deadsoftware.cavedroid.game.model.item.InventoryItem
diff --git a/core/src/ru/deadsoftware/cavedroid/game/windows/GameWindowsManager.kt b/core/src/ru/deadsoftware/cavedroid/game/windows/GameWindowsManager.kt
deleted file mode 100644
index b07f1fd..0000000
--- a/core/src/ru/deadsoftware/cavedroid/game/windows/GameWindowsManager.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-package ru.deadsoftware.cavedroid.game.windows
-
-import ru.deadsoftware.cavedroid.MainConfig
-import ru.deadsoftware.cavedroid.game.GameScope
-import ru.deadsoftware.cavedroid.game.GameUiWindow
-import ru.deadsoftware.cavedroid.game.mobs.MobsController
-import ru.deadsoftware.cavedroid.game.model.item.InventoryItem
-import ru.deadsoftware.cavedroid.game.windows.inventory.AbstractInventoryWindow
-import ru.deadsoftware.cavedroid.game.windows.inventory.CraftingInventoryWindow
-import ru.deadsoftware.cavedroid.game.windows.inventory.CreativeInventoryWindow
-import ru.deadsoftware.cavedroid.game.windows.inventory.SurvivalInventoryWindow
-import javax.inject.Inject
-
-@GameScope
-class GameWindowsManager @Inject constructor(
-    private val mainConfig: MainConfig,
-    private val mobsController: MobsController,
-) {
-
-    var creativeScrollAmount = 0
-    var isDragging = false
-
-    var currentWindow: AbstractInventoryWindow? = null
-
-    @JvmName("getCurrentWindowType")
-    fun getCurrentWindow(): GameUiWindow {
-        return currentWindow?.type ?: GameUiWindow.NONE
-    }
-
-    fun openInventory() {
-        if (mobsController.player.gameMode == 1) {
-            currentWindow = CreativeInventoryWindow(GameUiWindow.CREATIVE_INVENTORY)
-        } else {
-            currentWindow = SurvivalInventoryWindow(GameUiWindow.SURVIVAL_INVENTORY)
-        }
-    }
-
-    fun openCrafting() {
-        currentWindow = CraftingInventoryWindow(GameUiWindow.CRAFTING_TABLE)
-    }
-
-    fun closeWindow() {
-        currentWindow = null
-    }
-
-}
\ No newline at end of file
diff --git a/core/src/ru/deadsoftware/cavedroid/misc/Assets.java b/core/src/ru/deadsoftware/cavedroid/misc/Assets.java
index b7fd03e..029c59f 100644
--- a/core/src/ru/deadsoftware/cavedroid/misc/Assets.java
+++ b/core/src/ru/deadsoftware/cavedroid/misc/Assets.java
@@ -199,6 +199,7 @@ public class Assets {
         setPlayerHeadOrigin();
         minecraftFont = new BitmapFont(assetLoader.getAssetHandle("font.fnt"), true);
         minecraftFont.getData().setScale(.375f);
+        minecraftFont.setUseIntegerPositions(false);
     }
 
     /**