DEADSOFTWARE

17d6dd0632c560c24854301944d0d762043a5312
[cavedroid.git] /
1 package ru.fredboy.cavedroid.game.controller.container
2
3 import com.badlogic.gdx.Gdx
4 import ru.fredboy.cavedroid.common.di.GameScope
5 import ru.fredboy.cavedroid.common.utils.px
6 import ru.fredboy.cavedroid.domain.items.model.block.Block
7 import ru.fredboy.cavedroid.domain.items.usecase.GetItemByKeyUseCase
8 import ru.fredboy.cavedroid.domain.world.listener.OnBlockDestroyedListener
9 import ru.fredboy.cavedroid.domain.world.listener.OnBlockPlacedListener
10 import ru.fredboy.cavedroid.domain.world.model.Layer
11 import ru.fredboy.cavedroid.entity.container.abstraction.ContainerFactory
12 import ru.fredboy.cavedroid.entity.container.abstraction.ContainerWorldAdapter
13 import ru.fredboy.cavedroid.entity.container.model.Container
14 import ru.fredboy.cavedroid.entity.container.model.ContainerCoordinates
15 import ru.fredboy.cavedroid.entity.drop.abstraction.DropAdapter
16 import javax.inject.Inject
17
18 @GameScope
19 class ContainerController @Inject constructor(
20 private val getItemByKeyUseCase: GetItemByKeyUseCase,
21 private val containerWorldAdapter: ContainerWorldAdapter,
22 private val containerFactory: ContainerFactory,
23 private val dropAdapter: DropAdapter,
24 ): OnBlockPlacedListener, OnBlockDestroyedListener {
25
26 val containerMap = mutableMapOf<ContainerCoordinates, Container>()
27
28 val size get() = containerMap.size
29
30 init {
31 containerWorldAdapter.addOnBlockPlacedListener(this)
32 containerWorldAdapter.addOnBlockDestroyedListener(this)
33 }
34
35 private fun getContainerKey(x: Int, y: Int, z: Int): ContainerCoordinates {
36 return ContainerCoordinates(x, y, z)
37 }
38
39 fun getContainer(x: Int, y: Int, z: Int): Container? {
40 return containerMap[getContainerKey(x, y, z)]
41 }
42
43 fun addContainer(x: Int, y: Int, z: Int, container: Container) {
44 val key = getContainerKey(x, y, z)
45 if (containerMap.containsKey(key)) {
46 resetContainer(x, y, z)
47 }
48
49 containerMap[key] = container
50 }
51
52 private fun retrieveContainer(x: Int, y: Int, z: Int): Container? {
53 return containerMap.remove(getContainerKey(x, y, z))
54 }
55
56 fun resetContainer(x: Int, y: Int, z: Int) {
57 retrieveContainer(x, y, z)
58 }
59
60 fun destroyContainer(x: Int, y: Int, z: Int) {
61 retrieveContainer(x, y, z)?.let { container ->
62 dropAdapter.dropInventory(x.px, y.px, container.inventory)
63 }
64 }
65
66 @Suppress("unused")
67 fun update(delta: Float) {
68 val iterator = containerMap.iterator()
69 while (iterator.hasNext()) {
70 val (coordinates, container) = iterator.next()
71
72 if (!containerWorldAdapter.checkContainerAtCoordinates(coordinates, container.type)) {
73 Gdx.app.log(TAG, "Removing orphaned ${container::class.simpleName} at $coordinates")
74 iterator.remove()
75 } else {
76 container.update(getItemByKeyUseCase)
77 }
78 }
79 }
80
81 fun dispose() {
82 containerMap.clear()
83 containerWorldAdapter.removeOnBlockPlacedListener(this)
84 containerWorldAdapter.removeOnBlockDestroyedListener(this)
85 }
86
87 override fun onBlockDestroyed(block: Block, x: Int, y: Int, layer: Layer, withDrop: Boolean) {
88 destroyContainer(x, y, layer.z)
89 }
90
91 override fun onBlockPlaced(block: Block, x: Int, y: Int, layer: Layer) {
92 if (block is Block.Container) {
93 val container = containerFactory.createContainer(block)
94 addContainer(x, y, layer.z, container)
95 }
96 }
97
98 companion object {
99 private const val TAG = "ContainerControllerImpl"
100 }
101 }