DEADSOFTWARE

Update README
[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.GameScope
6 import ru.deadsoftware.cavedroid.game.input.IGameInputHandler
7 import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction
8 import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey
9 import ru.deadsoftware.cavedroid.game.mobs.Mob
10 import ru.deadsoftware.cavedroid.game.mobs.MobsController
11 import ru.deadsoftware.cavedroid.game.mobs.Player
12 import ru.deadsoftware.cavedroid.game.model.block.Block
13 import ru.deadsoftware.cavedroid.game.world.GameWorld
14 import ru.deadsoftware.cavedroid.misc.utils.bl
15 import ru.deadsoftware.cavedroid.misc.utils.px
16 import javax.inject.Inject
18 @GameScope
19 class CursorMouseInputHandler @Inject constructor(
20 private val mainConfig: MainConfig,
21 private val mobsController: MobsController,
22 private val gameWorld: GameWorld,
23 ) : IGameInputHandler<MouseInputAction> {
25 private val player get() = mobsController.player
27 private val Block.isAutoselectable
28 get() = !isNone() && params.hasCollision
30 private fun GameWorld.isCurrentBlockAutoselectable() =
31 getForeMap(player.cursorX, player.cursorY).isAutoselectable
33 private fun checkCursorBounds() {
34 if (player.gameMode == 0) {
35 val minCursorX = player.mapX - SURVIVAL_CURSOR_RANGE
36 val maxCursorX = player.mapX + SURVIVAL_CURSOR_RANGE
37 val minCursorY = player.middleMapY - SURVIVAL_CURSOR_RANGE
38 val maxCursorY = player.middleMapY + SURVIVAL_CURSOR_RANGE
40 player.cursorX = MathUtils.clamp(player.cursorX, minCursorX, maxCursorX)
41 player.cursorY = MathUtils.clamp(player.cursorY, minCursorY, maxCursorY)
42 }
44 player.cursorY = MathUtils.clamp(player.cursorY, 0, gameWorld.height - 1)
45 }
47 private fun setPlayerDirectionToCursor() {
48 if (player.controlMode != Player.ControlMode.CURSOR) {
49 return
50 }
52 if (player.cursorX.px + 8 < player.x + player.width / 2) {
53 player.setDir(Mob.Direction.LEFT)
54 } else {
55 player.setDir(Mob.Direction.RIGHT)
56 }
57 }
59 private fun handleWalkTouch() {
60 player.cursorX = player.mapX + player.direction.basis
61 player.cursorY = player.upperMapY
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
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)
93 }
95 override fun checkConditions(action: MouseInputAction): Boolean {
96 return action.actionKey is MouseInputActionKey.None
97 }
99 override fun handle(action: MouseInputAction) {
100 val pastCursorX = player.cursorX
101 val pastCursorY = player.cursorY
103 when {
104 player.controlMode == Player.ControlMode.WALK && mainConfig.isTouch -> handleWalkTouch()
105 !mainConfig.isTouch -> handleMouse(action)
108 checkCursorBounds()
109 setPlayerDirectionToCursor()
111 if (player.cursorX != pastCursorX || player.cursorY != pastCursorY) {
112 player.blockDamage = 0f
116 companion object {
117 private const val SURVIVAL_CURSOR_RANGE = 4