DEADSOFTWARE

a8f5d1ec2b0a1bc1830eda01dfe626a26da75235
[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.ApplicationContextRepository
9 import ru.fredboy.cavedroid.domain.configuration.repository.GameContextRepository
10 import ru.fredboy.cavedroid.domain.items.model.block.Block
11 import ru.fredboy.cavedroid.domain.items.usecase.GetItemByIndexUseCase
12 import ru.fredboy.cavedroid.entity.mob.model.Direction
13 import ru.fredboy.cavedroid.entity.mob.model.Player
14 import ru.fredboy.cavedroid.game.controller.mob.MobController
15 import ru.fredboy.cavedroid.game.window.GameWindowType
16 import ru.fredboy.cavedroid.game.window.GameWindowsConfigs
17 import ru.fredboy.cavedroid.game.window.GameWindowsManager
18 import ru.fredboy.cavedroid.game.window.TooltipManager
19 import ru.fredboy.cavedroid.game.world.GameWorld
20 import ru.fredboy.cavedroid.ux.controls.input.IMouseInputHandler
21 import ru.fredboy.cavedroid.ux.controls.input.action.MouseInputAction
22 import ru.fredboy.cavedroid.ux.controls.input.action.keys.MouseInputActionKey
23 import ru.fredboy.cavedroid.ux.controls.input.annotation.BindMouseInputHandler
24 import javax.inject.Inject
25
26 @GameScope
27 @BindMouseInputHandler
28 class CursorMouseInputHandler @Inject constructor(
29 private val applicationContextRepository: ApplicationContextRepository,
30 private val mobController: MobController,
31 private val gameWorld: GameWorld,
32 private val gameWindowsManager: GameWindowsManager,
33 private val tooltipManager: TooltipManager,
34 private val textureRegions: GetTextureRegionByNameUseCase,
35 private val getItemByIndexUseCase: GetItemByIndexUseCase,
36 ) : IMouseInputHandler {
37
38 private val player get() = mobController.player
39
40 private val creativeInventoryTexture get() = requireNotNull(textureRegions["creative"])
41
42 private val Block.isAutoselectable
43 get() = !isNone() && params.hasCollision
44
45 private fun GameWorld.isCurrentBlockAutoselectable() =
46 getForeMap(player.cursorX, player.cursorY).isAutoselectable
47
48 private fun setPlayerDirectionToCursor() {
49 if (player.controlMode != Player.ControlMode.CURSOR) {
50 return
51 }
52
53 if (player.cursorX.px + 8 < player.x + player.width / 2) {
54 player.direction = Direction.LEFT
55 } else {
56 player.direction = Direction.RIGHT
57 }
58 }
59
60 private fun handleWalkTouch() {
61 player.cursorX = player.mapX + player.direction.basis
62 player.cursorY = player.upperMapY
63 player.headRotation = 0f
64
65 for (i in 1..2) {
66 if (gameWorld.isCurrentBlockAutoselectable()) {
67 break
68 }
69 player.cursorY++
70 }
71
72 if (!gameWorld.isCurrentBlockAutoselectable()) {
73 player.cursorX -= player.direction.basis
74 }
75 }
76
77 private fun getPlayerHeadRotation(mouseWorldX: Float, mouseWorldY: Float): Float {
78 val h = mouseWorldX - (player.x + player.width / 2)
79 val v = mouseWorldY - player.y
80
81 return MathUtils.atan(v / h) * MathUtils.radDeg
82 }
83
84 private fun handleMouse(action: MouseInputAction) {
85 val worldX = action.screenX + action.cameraViewport.x
86 val worldY = action.screenY + action.cameraViewport.y
87
88 // when worldX < 0, need to subtract 1 to avoid negative zero
89 // val fixCycledWorld = if (worldX < 0) 1 else 0
90
91 player.cursorX = worldX.bl - 0
92 player.cursorY = worldY.bl
93
94 player.headRotation = getPlayerHeadRotation(worldX, worldY)
95
96 if (worldX < player.x + player.width / 2) {
97 player.direction = Direction.LEFT
98 } else {
99 player.direction = Direction.RIGHT
100 }
101 }
102
103 private fun getCreativeTooltip(action: MouseInputAction): String? {
104 val creativeTexture = creativeInventoryTexture
105 val xOnGrid = (action.screenX - (action.cameraViewport.width / 2 - creativeTexture.regionWidth / 2 +
106 GameWindowsConfigs.Creative.itemsGridMarginLeft)) /
107 GameWindowsConfigs.Creative.itemsGridColWidth
108 val yOnGrid = (action.screenY - (action.cameraViewport.height / 2 - creativeTexture.regionHeight / 2 +
109 GameWindowsConfigs.Creative.itemsGridMarginTop)) /
110 GameWindowsConfigs.Creative.itemsGridRowHeight
111
112 if (xOnGrid < 0 || xOnGrid >= GameWindowsConfigs.Creative.itemsInRow ||
113 yOnGrid < 0 || yOnGrid >= GameWindowsConfigs.Creative.itemsInCol) {
114 return null
115 }
116
117 val itemIndex = (gameWindowsManager.creativeScrollAmount * GameWindowsConfigs.Creative.itemsInRow +
118 (xOnGrid.toInt() + yOnGrid.toInt() * GameWindowsConfigs.Creative.itemsInRow))
119 val item = getItemByIndexUseCase[itemIndex]
120
121 return item.params.name
122 }
123
124 override fun checkConditions(action: MouseInputAction): Boolean {
125 return action.actionKey is MouseInputActionKey.None
126 }
127
128 override fun handle(action: MouseInputAction) {
129 val pastCursorX = player.cursorX
130 val pastCursorY = player.cursorY
131
132 when {
133 player.controlMode == Player.ControlMode.WALK && applicationContextRepository.isTouch() -> handleWalkTouch()
134 !applicationContextRepository.isTouch() -> handleMouse(action)
135 }
136
137 mobController.checkPlayerCursorBounds()
138
139 if (player.controlMode == Player.ControlMode.WALK && applicationContextRepository.isTouch()) {
140 setPlayerDirectionToCursor()
141 }
142
143 if (player.cursorX != pastCursorX || player.cursorY != pastCursorY) {
144 player.blockDamage = 0f
145 }
146
147 if (gameWindowsManager.currentWindowType == GameWindowType.CREATIVE_INVENTORY) {
148 tooltipManager.showMouseTooltip(getCreativeTooltip(action).orEmpty())
149 }
150 }
151
152 }