DEADSOFTWARE

CaveGame in kotlin
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / objects / container / Furnace.kt
1 package ru.deadsoftware.cavedroid.game.objects.container
3 import com.badlogic.gdx.Gdx
4 import com.badlogic.gdx.math.MathUtils
5 import com.badlogic.gdx.utils.TimeUtils
6 import ru.deadsoftware.cavedroid.game.GameItemsHolder
7 import ru.deadsoftware.cavedroid.game.model.item.InventoryItem
8 import ru.deadsoftware.cavedroid.game.model.item.InventoryItem.Companion.isNoneOrNull
9 import ru.deadsoftware.cavedroid.game.model.item.Item
11 class Furnace(gameItemsHolder: GameItemsHolder) : Container(SIZE, gameItemsHolder) {
13 var fuel: InventoryItem
14 get() = items[FUEL_INDEX]
15 set(value) {
16 items[FUEL_INDEX] = value
17 }
19 var input: InventoryItem
20 get() = items[INPUT_INDEX]
21 set(value) {
22 items[INPUT_INDEX] = value
23 }
25 var result: InventoryItem
26 get() = items[RESULT_INDEX]
27 set(value) {
28 items[RESULT_INDEX] = value
29 }
31 val isActive: Boolean get() = currentFuel != null
33 @Transient
34 var currentFuel: Item? = null
35 set(value) {
36 currentFuelKey = value?.params?.key
37 field = value
38 }
40 var currentFuelKey: String? = null
42 private var startBurnTimeMs = 0L
43 private var smeltStarTimeMs = 0L
45 var burnProgress = 0f
46 private set(value) {
47 field = MathUtils.clamp(value, 0f, 1f)
48 }
49 var smeltProgress = 0f
50 private set(value) {
51 field = MathUtils.clamp(value, 0f, 1f)
52 }
54 fun init(gameItemsHolder: GameItemsHolder) {
55 currentFuel = currentFuelKey?.let { gameItemsHolder.getItem(it) }
56 items.forEach { it.init(gameItemsHolder) }
57 }
59 fun canSmelt(): Boolean {
60 return (result.isNoneOrNull() || (result.item.params.key == input.item.params.smeltProductKey) )&&
61 !input.isNoneOrNull() && input.item.params.smeltProductKey != null &&
62 (!fuel.isNoneOrNull() || burnProgress > 0f)
63 }
65 private fun startBurning(gameItemsHolder: GameItemsHolder) {
66 requireNotNull(fuel.item.params.burningTimeMs) { "Cant start burning without fuel" }
67 currentFuel = fuel.item
68 fuel.subtract()
69 if (fuel.amount <= 0) {
70 fuel = gameItemsHolder.fallbackItem.toInventoryItem()
71 }
72 startBurnTimeMs = TimeUtils.millis()
73 burnProgress = 0f
74 }
76 override fun update(gameItemsHolder: GameItemsHolder) {
77 if (currentFuel?.isNone() == true) {
78 currentFuel = null
79 }
81 currentFuel?.let { curFuel ->
82 val burningTimeMs = curFuel.params.burningTimeMs ?: run {
83 Gdx.app.error(TAG, "Burning item has no burning time. Item : ${curFuel.params.key}")
84 return
85 }
87 if (TimeUtils.timeSinceMillis(startBurnTimeMs).toDouble() / burningTimeMs >= 0.01) {
88 burnProgress += 0.01f
89 startBurnTimeMs = TimeUtils.millis()
90 }
92 }
94 if (currentFuel?.isNone() == false && burnProgress >= 1f) {
95 if (canSmelt()) {
96 startBurning(gameItemsHolder)
97 } else {
98 currentFuel = null
99 burnProgress = 0f
100 smeltProgress = 0f
104 if (!canSmelt()) {
105 return
107 if (currentFuel == null && !fuel.isNoneOrNull()) {
108 startBurning(gameItemsHolder)
109 smeltStarTimeMs = startBurnTimeMs
110 smeltProgress = 0f
113 if ((TimeUtils.timeSinceMillis(smeltStarTimeMs).toDouble() / SMELTING_TIME_MS) >= 0.01) {
114 smeltProgress += 0.01f
115 smeltStarTimeMs = TimeUtils.millis()
118 if (isActive && smeltProgress >= 1f) {
119 val productKey = requireNotNull(input.item.params.smeltProductKey)
120 val res = gameItemsHolder.getItem(productKey)
121 if (result.isNoneOrNull()) {
122 result = res.toInventoryItem()
123 } else {
124 result.add()
126 input.subtract()
127 if (input.amount <= 0) {
128 input = gameItemsHolder.fallbackItem.toInventoryItem()
130 smeltStarTimeMs = TimeUtils.millis()
131 smeltProgress = 0f
135 companion object {
136 private const val SIZE = 3
137 private const val TAG = "Furnace"
139 const val FUEL_INDEX = 0
140 const val INPUT_INDEX = 1
141 const val RESULT_INDEX = 2
143 const val SMELTING_TIME_MS = 10000L