DEADSOFTWARE

Bug fixes
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / input / handler / mouse / CursorMouseInputHandler.kt
1 package ru.deadsoftware.cavedroid.game.input.handler.mouse
3 import com.badlogic.gdx.math.MathUtils
4 import ru.deadsoftware.cavedroid.MainConfig
5 import ru.deadsoftware.cavedroid.game.GameItemsHolder
6 import ru.deadsoftware.cavedroid.game.GameScope
7 import ru.deadsoftware.cavedroid.game.GameUiWindow
8 import ru.deadsoftware.cavedroid.game.input.IGameInputHandler
9 import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction
10 import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey
11 import ru.deadsoftware.cavedroid.game.mobs.Mob
12 import ru.deadsoftware.cavedroid.game.mobs.MobsController
13 import ru.deadsoftware.cavedroid.game.mobs.player.Player
14 import ru.deadsoftware.cavedroid.game.model.block.Block
15 import ru.deadsoftware.cavedroid.game.ui.TooltipManager
16 import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs
17 import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager
18 import ru.deadsoftware.cavedroid.game.world.GameWorld
19 import ru.deadsoftware.cavedroid.misc.Assets
20 import ru.deadsoftware.cavedroid.misc.utils.bl
21 import ru.deadsoftware.cavedroid.misc.utils.px
22 import javax.inject.Inject
24 @GameScope
25 class CursorMouseInputHandler @Inject constructor(
26 private val mainConfig: MainConfig,
27 private val mobsController: MobsController,
28 private val gameWorld: GameWorld,
29 private val gameWindowsManager: GameWindowsManager,
30 private val gameItemsHolder: GameItemsHolder,
31 private val tooltipManager: TooltipManager,
32 ) : IGameInputHandler<MouseInputAction> {
34 private val player get() = mobsController.player
36 private val creativeInventoryTexture get() = requireNotNull(Assets.textureRegions["creative"])
38 private val Block.isAutoselectable
39 get() = !isNone() && params.hasCollision
41 private fun GameWorld.isCurrentBlockAutoselectable() =
42 getForeMap(player.cursorX, player.cursorY).isAutoselectable
44 private fun setPlayerDirectionToCursor() {
45 if (player.controlMode != Player.ControlMode.CURSOR) {
46 return
47 }
49 if (player.cursorX.px + 8 < player.x + player.width / 2) {
50 player.setDir(Mob.Direction.LEFT)
51 } else {
52 player.setDir(Mob.Direction.RIGHT)
53 }
54 }
56 private fun handleWalkTouch() {
57 player.cursorX = player.mapX + player.direction.basis
58 player.cursorY = player.upperMapY
59 player.headRotation = 0f
61 for (i in 1..2) {
62 if (gameWorld.isCurrentBlockAutoselectable()) {
63 break
64 }
65 player.cursorY++
66 }
68 if (!gameWorld.isCurrentBlockAutoselectable()) {
69 player.cursorX -= player.direction.basis
70 }
71 }
73 private fun getPlayerHeadRotation(mouseWorldX: Float, mouseWorldY: Float): Float {
74 val h = mouseWorldX - player.x
75 val v = mouseWorldY - player.y
77 return MathUtils.atan(v / h) * MathUtils.radDeg
78 }
80 private fun handleMouse(action: MouseInputAction) {
81 val worldX = action.screenX + action.cameraViewport.x
82 val worldY = action.screenY + action.cameraViewport.y
84 // when worldX < 0, need to subtract 1 to avoid negative zero
85 // val fixCycledWorld = if (worldX < 0) 1 else 0
87 player.cursorX = worldX.bl - 0
88 player.cursorY = worldY.bl
90 player.headRotation = getPlayerHeadRotation(worldX, worldY)
91 }
93 private fun getCreativeTooltip(action: MouseInputAction): String? {
94 val creativeTexture = creativeInventoryTexture
95 val xOnGrid = (action.screenX - (action.cameraViewport.width / 2 - creativeTexture.regionWidth / 2 +
96 GameWindowsConfigs.Creative.itemsGridMarginLeft)) /
97 GameWindowsConfigs.Creative.itemsGridColWidth
98 val yOnGrid = (action.screenY - (action.cameraViewport.height / 2 - creativeTexture.regionHeight / 2 +
99 GameWindowsConfigs.Creative.itemsGridMarginTop)) /
100 GameWindowsConfigs.Creative.itemsGridRowHeight
102 if (xOnGrid < 0 || xOnGrid >= GameWindowsConfigs.Creative.itemsInRow ||
103 yOnGrid < 0 || yOnGrid >= GameWindowsConfigs.Creative.itemsInCol) {
104 return null
107 val itemIndex = (gameWindowsManager.creativeScrollAmount * GameWindowsConfigs.Creative.itemsInRow +
108 (xOnGrid.toInt() + yOnGrid.toInt() * GameWindowsConfigs.Creative.itemsInRow))
109 val item = gameItemsHolder.getItemFromCreativeInventory(itemIndex)
111 return item.params.name
114 override fun checkConditions(action: MouseInputAction): Boolean {
115 return action.actionKey is MouseInputActionKey.None
118 override fun handle(action: MouseInputAction) {
119 val pastCursorX = player.cursorX
120 val pastCursorY = player.cursorY
122 when {
123 player.controlMode == Player.ControlMode.WALK && mainConfig.isTouch -> handleWalkTouch()
124 !mainConfig.isTouch -> handleMouse(action)
127 player.checkCursorBounds(gameWorld)
128 setPlayerDirectionToCursor()
130 if (player.cursorX != pastCursorX || player.cursorY != pastCursorY) {
131 player.blockDamage = 0f
134 if (gameWindowsManager.getCurrentWindow() == GameUiWindow.CREATIVE_INVENTORY) {
135 tooltipManager.showMouseTooltip(getCreativeTooltip(action).orEmpty())
139 companion object {
140 private const val SURVIVAL_CURSOR_RANGE = 4