DEADSOFTWARE

a42ebcec55578c76c3d2302486e1c4fa273b1787
[cavedroid.git] /
1 package ru.fredboy.cavedroid.ux.controls.input.handler.mouse
2
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
24
25 @GameScope
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 {
36
37 private val player get() = mobController.player
38
39 private val creativeInventoryTexture get() = requireNotNull(textureRegions["creative"])
40
41 private val Block.isAutoselectable
42 get() = !isNone() && params.hasCollision
43
44 private fun GameWorld.isCurrentBlockAutoselectable() =
45 getForeMap(player.cursorX, player.cursorY).isAutoselectable
46
47 private fun setPlayerDirectionToCursor() {
48 if (player.controlMode != Player.ControlMode.CURSOR) {
49 return
50 }
51
52 if (player.cursorX.px + 8 < player.x + player.width / 2) {
53 player.direction = Direction.LEFT
54 } else {
55 player.direction = Direction.RIGHT
56 }
57 }
58
59 private fun handleWalkTouch() {
60 player.cursorX = player.mapX + player.direction.basis
61 player.cursorY = player.upperMapY
62 player.headRotation = 0f
63
64 for (i in 1..2) {
65 if (gameWorld.isCurrentBlockAutoselectable()) {
66 break
67 }
68 player.cursorY++
69 }
70
71 if (!gameWorld.isCurrentBlockAutoselectable()) {
72 player.cursorX -= player.direction.basis
73 }
74 }
75
76 private fun getPlayerHeadRotation(mouseWorldX: Float, mouseWorldY: Float): Float {
77 val h = mouseWorldX - (player.x + player.width / 2)
78 val v = mouseWorldY - player.y
79
80 return MathUtils.atan(v / h) * MathUtils.radDeg
81 }
82
83 private fun handleMouse(action: MouseInputAction) {
84 val worldX = action.screenX + action.cameraViewport.x
85 val worldY = action.screenY + action.cameraViewport.y
86
87 // when worldX < 0, need to subtract 1 to avoid negative zero
88 // val fixCycledWorld = if (worldX < 0) 1 else 0
89
90 player.cursorX = worldX.bl - 0
91 player.cursorY = worldY.bl
92
93 player.headRotation = getPlayerHeadRotation(worldX, worldY)
94
95 if (worldX < player.x + player.width / 2) {
96 player.direction = Direction.LEFT
97 } else {
98 player.direction = Direction.RIGHT
99 }
100 }
101
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
110
111 if (xOnGrid < 0 || xOnGrid >= GameWindowsConfigs.Creative.itemsInRow ||
112 yOnGrid < 0 || yOnGrid >= GameWindowsConfigs.Creative.itemsInCol) {
113 return null
114 }
115
116 val itemIndex = (gameWindowsManager.creativeScrollAmount * GameWindowsConfigs.Creative.itemsInRow +
117 (xOnGrid.toInt() + yOnGrid.toInt() * GameWindowsConfigs.Creative.itemsInRow))
118 val item = getItemByIndexUseCase[itemIndex]
119
120 return item.params.name
121 }
122
123 override fun checkConditions(action: MouseInputAction): Boolean {
124 return action.actionKey is MouseInputActionKey.None
125 }
126
127 override fun handle(action: MouseInputAction) {
128 val pastCursorX = player.cursorX
129 val pastCursorY = player.cursorY
130
131 when {
132 player.controlMode == Player.ControlMode.WALK && gameConfigurationRepository.isTouch() -> handleWalkTouch()
133 !gameConfigurationRepository.isTouch() -> handleMouse(action)
134 }
135
136 mobController.checkPlayerCursorBounds()
137
138 if (player.controlMode == Player.ControlMode.WALK && gameConfigurationRepository.isTouch()) {
139 setPlayerDirectionToCursor()
140 }
141
142 if (player.cursorX != pastCursorX || player.cursorY != pastCursorY) {
143 player.blockDamage = 0f
144 }
145
146 if (gameWindowsManager.currentWindowType == GameWindowType.CREATIVE_INVENTORY) {
147 tooltipManager.showMouseTooltip(getCreativeTooltip(action).orEmpty())
148 }
149 }
150
151 }