DEADSOFTWARE

454337eefb744f6f8a4803283299ddd28a2e694a
[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 + player.width / 2)
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)
92 if (worldX < player.x + player.width / 2) {
93 player.setDir(Mob.Direction.LEFT)
94 } else {
95 player.setDir(Mob.Direction.RIGHT)
96 }
97 }
99 private fun getCreativeTooltip(action: MouseInputAction): String? {
100 val creativeTexture = creativeInventoryTexture
101 val xOnGrid = (action.screenX - (action.cameraViewport.width / 2 - creativeTexture.regionWidth / 2 +
102 GameWindowsConfigs.Creative.itemsGridMarginLeft)) /
103 GameWindowsConfigs.Creative.itemsGridColWidth
104 val yOnGrid = (action.screenY - (action.cameraViewport.height / 2 - creativeTexture.regionHeight / 2 +
105 GameWindowsConfigs.Creative.itemsGridMarginTop)) /
106 GameWindowsConfigs.Creative.itemsGridRowHeight
108 if (xOnGrid < 0 || xOnGrid >= GameWindowsConfigs.Creative.itemsInRow ||
109 yOnGrid < 0 || yOnGrid >= GameWindowsConfigs.Creative.itemsInCol) {
110 return null
113 val itemIndex = (gameWindowsManager.creativeScrollAmount * GameWindowsConfigs.Creative.itemsInRow +
114 (xOnGrid.toInt() + yOnGrid.toInt() * GameWindowsConfigs.Creative.itemsInRow))
115 val item = gameItemsHolder.getItemFromCreativeInventory(itemIndex)
117 return item.params.name
120 override fun checkConditions(action: MouseInputAction): Boolean {
121 return action.actionKey is MouseInputActionKey.None
124 override fun handle(action: MouseInputAction) {
125 val pastCursorX = player.cursorX
126 val pastCursorY = player.cursorY
128 when {
129 player.controlMode == Player.ControlMode.WALK && mainConfig.isTouch -> handleWalkTouch()
130 !mainConfig.isTouch -> handleMouse(action)
133 player.checkCursorBounds(gameWorld)
135 if (player.controlMode == Player.ControlMode.WALK && mainConfig.isTouch) {
136 setPlayerDirectionToCursor()
139 if (player.cursorX != pastCursorX || player.cursorY != pastCursorY) {
140 player.blockDamage = 0f
143 if (gameWindowsManager.getCurrentWindow() == GameUiWindow.CREATIVE_INVENTORY) {
144 tooltipManager.showMouseTooltip(getCreativeTooltip(action).orEmpty())
148 companion object {
149 private const val SURVIVAL_CURSOR_RANGE = 4