DEADSOFTWARE

a6915efa0df0f70dda0ecfde3d7cf2e287fa14f0
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / objects / furnace / Furnace.kt
1 package ru.deadsoftware.cavedroid.game.objects.furnace
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
10 import java.io.Serializable
12 class Furnace : Serializable {
14 val items = MutableList<InventoryItem?>(3) { null }
16 var fuel: InventoryItem?
17 get() = items[FUEL_INDEX]
18 set(value) {
19 items[FUEL_INDEX] = value
20 }
22 var input: InventoryItem?
23 get() = items[INPUT_INDEX]
24 set(value) {
25 items[INPUT_INDEX] = value
26 }
28 var result: InventoryItem?
29 get() = items[RESULT_INDEX]
30 set(value) {
31 items[RESULT_INDEX] = value
32 }
34 val isActive: Boolean get() = currentFuel != null
36 @Transient
37 var currentFuel: Item? = null
38 set(value) {
39 currentFuelKey = value?.params?.key
40 field = value
41 }
43 var currentFuelKey: String? = null
45 private var startBurnTimeMs = 0L
46 private var smeltStarTimeMs = 0L
48 var burnProgress = 0f
49 private set(value) {
50 field = MathUtils.clamp(value, 0f, 1f)
51 }
52 var smeltProgress = 0f
53 private set(value) {
54 field = MathUtils.clamp(value, 0f, 1f)
55 }
57 fun init(gameItemsHolder: GameItemsHolder) {
58 currentFuel = currentFuelKey?.let { gameItemsHolder.getItem(it) }
59 items.forEach { it?.init(gameItemsHolder) }
60 }
62 fun canSmelt(): Boolean {
63 return (result.isNoneOrNull() || (result?.item?.params?.key == input?.item?.params?.smeltProductKey) )&&
64 !input.isNoneOrNull() && input?.item?.params?.smeltProductKey != null &&
65 (!fuel.isNoneOrNull() || burnProgress > 0f)
66 }
68 private fun startBurning() {
69 requireNotNull(fuel?.item?.params?.burningTimeMs) { "Cant start burning without fuel" }
70 currentFuel = fuel!!.item
71 fuel!!.subtract()
72 if (fuel!!.amount <= 0) {
73 fuel = null
74 }
75 startBurnTimeMs = TimeUtils.millis()
76 burnProgress = 0f
77 }
79 fun update(gameItemsHolder: GameItemsHolder) {
80 if (currentFuel?.isNone() == true) {
81 currentFuel = null
82 }
84 currentFuel?.let { curFuel ->
85 val burningTimeMs = curFuel.params.burningTimeMs ?: run {
86 Gdx.app.error(TAG, "Burning item has no burning time. Item : ${curFuel.params.key}")
87 return
88 }
90 if (TimeUtils.timeSinceMillis(startBurnTimeMs).toDouble() / burningTimeMs >= 0.01) {
91 burnProgress += 0.01f
92 startBurnTimeMs = TimeUtils.millis()
93 }
95 }
97 if (currentFuel != null && burnProgress >= 1f) {
98 if (canSmelt()) {
99 startBurning()
100 } else {
101 currentFuel = null
102 burnProgress = 0f
103 smeltProgress = 0f
107 if (!canSmelt()) {
108 return
110 if (currentFuel == null && !fuel.isNoneOrNull()) {
111 startBurning()
112 smeltStarTimeMs = startBurnTimeMs
113 smeltProgress = 0f
116 if ((TimeUtils.timeSinceMillis(smeltStarTimeMs).toDouble() / SMELTING_TIME_MS) >= 0.01) {
117 smeltProgress += 0.01f
118 smeltStarTimeMs = TimeUtils.millis()
121 if (isActive && smeltProgress >= 1f) {
122 val res = gameItemsHolder.getItem(input!!.item.params.smeltProductKey!!)
123 if (result.isNoneOrNull()) {
124 result = res.toInventoryItem()
125 } else {
126 result!!.add()
128 input!!.subtract()
129 if (input!!.amount <= 0) {
130 input = null
132 smeltStarTimeMs = TimeUtils.millis()
133 smeltProgress = 0f
137 companion object {
138 private const val TAG = "Furnace"
140 const val FUEL_INDEX = 0
141 const val INPUT_INDEX = 1
142 const val RESULT_INDEX = 2
144 const val SMELTING_TIME_MS = 10000L