DEADSOFTWARE

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