DEADSOFTWARE

e05765d32264d8864619ced1743d881c24241917
[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 fun update(delta: Float) {
67 val iterator = containerMap.iterator()
68 while (iterator.hasNext()) {
69 val (coordinates, container) = iterator.next()
70
71 if (!containerWorldAdapter.checkContainerAtCoordinates(coordinates, container.type)) {
72 Gdx.app.log(TAG, "Removing orphaned ${container::class.simpleName} at $coordinates")
73 iterator.remove()
74 } else {
75 container.update(getItemByKeyUseCase)
76 }
77 }
78 }
79
80 fun dispose() {
81 containerMap.clear()
82 containerWorldAdapter.removeOnBlockPlacedListener(this)
83 containerWorldAdapter.removeOnBlockDestroyedListener(this)
84 }
85
86 override fun onBlockDestroyed(block: Block, x: Int, y: Int, layer: Layer, withDrop: Boolean) {
87 destroyContainer(x, y, layer.z)
88 }
89
90 override fun onBlockPlaced(block: Block, x: Int, y: Int, layer: Layer) {
91 if (block is Block.Container) {
92 val container = containerFactory.createContainer(block)
93 addContainer(x, y, layer.z, container)
94 }
95 }
96
97 companion object {
98 private const val TAG = "ContainerControllerImpl"
99 }
100 }