1 package ru.fredboy.cavedroid.ux.controls.input.handler.mouse
3 import com.badlogic.gdx.math.MathUtils
4 import ru.fredboy.cavedroid.common.di.GameScope
5 import ru.fredboy.cavedroid.domain.assets.usecase.GetTextureRegionByNameUseCase
6 import ru.fredboy.cavedroid.common.utils.bl
7 import ru.fredboy.cavedroid.common.utils.px
8 import ru.fredboy.cavedroid.domain.configuration.repository.GameConfigurationRepository
9 import ru.fredboy.cavedroid.domain.items.model.block.Block
10 import ru.fredboy.cavedroid.domain.items.usecase.GetItemByIndexUseCase
11 import ru.fredboy.cavedroid.entity.mob.model.Direction
12 import ru.fredboy.cavedroid.entity.mob.model.Player
13 import ru.fredboy.cavedroid.game.controller.mob.MobController
14 import ru.fredboy.cavedroid.game.window.GameWindowType
15 import ru.fredboy.cavedroid.game.window.GameWindowsConfigs
16 import ru.fredboy.cavedroid.game.window.GameWindowsManager
17 import ru.fredboy.cavedroid.game.window.TooltipManager
18 import ru.fredboy.cavedroid.game.world.GameWorld
19 import ru.fredboy.cavedroid.ux.controls.input.IMouseInputHandler
20 import ru.fredboy.cavedroid.ux.controls.input.action.MouseInputAction
21 import ru.fredboy.cavedroid.ux.controls.input.action.keys.MouseInputActionKey
22 import ru.fredboy.cavedroid.ux.controls.input.annotation.BindMouseInputHandler
23 import javax.inject.Inject
26 @BindMouseInputHandler
27 class CursorMouseInputHandler @Inject constructor(
28 private val gameConfigurationRepository: GameConfigurationRepository,
29 private val mobController: MobController,
30 private val gameWorld: GameWorld,
31 private val gameWindowsManager: GameWindowsManager,
32 private val tooltipManager: TooltipManager,
33 private val textureRegions: GetTextureRegionByNameUseCase,
34 private val getItemByIndexUseCase: GetItemByIndexUseCase,
35 ) : IMouseInputHandler {
37 private val player get() = mobController.player
39 private val creativeInventoryTexture get() = requireNotNull(textureRegions["creative"])
41 private val Block.isAutoselectable
42 get() = !isNone() && params.hasCollision
44 private fun GameWorld.isCurrentBlockAutoselectable() =
45 getForeMap(player.cursorX, player.cursorY).isAutoselectable
47 private fun setPlayerDirectionToCursor() {
48 if (player.controlMode != Player.ControlMode.CURSOR) {
52 if (player.cursorX.px + 8 < player.x + player.width / 2) {
53 player.direction = Direction.LEFT
55 player.direction = Direction.RIGHT
59 private fun handleWalkTouch() {
60 player.cursorX = player.mapX + player.direction.basis
61 player.cursorY = player.upperMapY
62 player.headRotation = 0f
65 if (gameWorld.isCurrentBlockAutoselectable()) {
71 if (!gameWorld.isCurrentBlockAutoselectable()) {
72 player.cursorX -= player.direction.basis
76 private fun getPlayerHeadRotation(mouseWorldX: Float, mouseWorldY: Float): Float {
77 val h = mouseWorldX - (player.x + player.width / 2)
78 val v = mouseWorldY - player.y
80 return MathUtils.atan(v / h) * MathUtils.radDeg
83 private fun handleMouse(action: MouseInputAction) {
84 val worldX = action.screenX + action.cameraViewport.x
85 val worldY = action.screenY + action.cameraViewport.y
87 // when worldX < 0, need to subtract 1 to avoid negative zero
88 // val fixCycledWorld = if (worldX < 0) 1 else 0
90 player.cursorX = worldX.bl - 0
91 player.cursorY = worldY.bl
93 player.headRotation = getPlayerHeadRotation(worldX, worldY)
95 if (worldX < player.x + player.width / 2) {
96 player.direction = Direction.LEFT
98 player.direction = Direction.RIGHT
102 private fun getCreativeTooltip(action: MouseInputAction): String? {
103 val creativeTexture = creativeInventoryTexture
104 val xOnGrid = (action.screenX - (action.cameraViewport.width / 2 - creativeTexture.regionWidth / 2 +
105 GameWindowsConfigs.Creative.itemsGridMarginLeft)) /
106 GameWindowsConfigs.Creative.itemsGridColWidth
107 val yOnGrid = (action.screenY - (action.cameraViewport.height / 2 - creativeTexture.regionHeight / 2 +
108 GameWindowsConfigs.Creative.itemsGridMarginTop)) /
109 GameWindowsConfigs.Creative.itemsGridRowHeight
111 if (xOnGrid < 0 || xOnGrid >= GameWindowsConfigs.Creative.itemsInRow ||
112 yOnGrid < 0 || yOnGrid >= GameWindowsConfigs.Creative.itemsInCol) {
116 val itemIndex = (gameWindowsManager.creativeScrollAmount * GameWindowsConfigs.Creative.itemsInRow +
117 (xOnGrid.toInt() + yOnGrid.toInt() * GameWindowsConfigs.Creative.itemsInRow))
118 val item = getItemByIndexUseCase[itemIndex]
120 return item.params.name
123 override fun checkConditions(action: MouseInputAction): Boolean {
124 return action.actionKey is MouseInputActionKey.None
127 override fun handle(action: MouseInputAction) {
128 val pastCursorX = player.cursorX
129 val pastCursorY = player.cursorY
132 player.controlMode == Player.ControlMode.WALK && gameConfigurationRepository.isTouch() -> handleWalkTouch()
133 !gameConfigurationRepository.isTouch() -> handleMouse(action)
136 mobController.checkPlayerCursorBounds()
138 if (player.controlMode == Player.ControlMode.WALK && gameConfigurationRepository.isTouch()) {
139 setPlayerDirectionToCursor()
142 if (player.cursorX != pastCursorX || player.cursorY != pastCursorY) {
143 player.blockDamage = 0f
146 if (gameWindowsManager.currentWindowType == GameWindowType.CREATIVE_INVENTORY) {
147 tooltipManager.showMouseTooltip(getCreativeTooltip(action).orEmpty())