DEADSOFTWARE

Update version script
[cavedroid.git] / core / src / main / kotlin / 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.dto.SaveDataDto
8 import ru.deadsoftware.cavedroid.game.model.item.InventoryItem
9 import ru.deadsoftware.cavedroid.game.model.item.InventoryItem.Companion.isNoneOrNull
10 import ru.deadsoftware.cavedroid.game.model.item.Item
11 import ru.deadsoftware.cavedroid.misc.Saveable
13 class Furnace @JvmOverloads constructor(
14 gameItemsHolder: GameItemsHolder,
15 initialItems: List<InventoryItem>? = null
16 ) : Container(SIZE, gameItemsHolder, initialItems), Saveable {
18 var fuel: InventoryItem
19 get() = items[FUEL_INDEX]
20 set(value) {
21 items[FUEL_INDEX] = value
22 }
24 var input: InventoryItem
25 get() = items[INPUT_INDEX]
26 set(value) {
27 items[INPUT_INDEX] = value
28 }
30 var result: InventoryItem
31 get() = items[RESULT_INDEX]
32 set(value) {
33 items[RESULT_INDEX] = value
34 }
36 val isActive: Boolean get() = currentFuel != null
38 var currentFuel: Item? = null
39 set(value) {
40 currentFuelKey = value?.params?.key
41 field = value
42 }
44 var currentFuelKey: String? = null
46 private var startBurnTimeMs = 0L
47 private var smeltStarTimeMs = 0L
49 var burnProgress = 0f
50 private set(value) {
51 field = MathUtils.clamp(value, 0f, 1f)
52 }
53 var smeltProgress = 0f
54 private set(value) {
55 field = MathUtils.clamp(value, 0f, 1f)
56 }
58 fun init(gameItemsHolder: GameItemsHolder) {
59 currentFuel = currentFuelKey?.let { gameItemsHolder.getItem(it) }
60 items.forEach { it.init(gameItemsHolder) }
61 }
63 fun canSmelt(): Boolean {
64 return (result.isNoneOrNull() || (result.item.params.key == input.item.params.smeltProductKey)) &&
65 !input.isNoneOrNull() && input.item.params.smeltProductKey != null &&
66 (!fuel.isNoneOrNull() || burnProgress > 0f)
67 }
69 private fun startBurning(gameItemsHolder: GameItemsHolder) {
70 requireNotNull(fuel.item.params.burningTimeMs) { "Cant start burning without fuel" }
71 currentFuel = fuel.item
72 fuel.subtract()
73 if (fuel.amount <= 0) {
74 fuel = gameItemsHolder.fallbackItem.toInventoryItem()
75 }
76 startBurnTimeMs = TimeUtils.millis()
77 burnProgress = 0f
78 }
80 override fun update(gameItemsHolder: GameItemsHolder) {
81 if (currentFuel?.isNone() == true) {
82 currentFuel = null
83 }
85 currentFuel?.let { curFuel ->
86 val burningTimeMs = curFuel.params.burningTimeMs ?: run {
87 Gdx.app.error(TAG, "Burning item has no burning time. Item : ${curFuel.params.key}")
88 return
89 }
91 if (TimeUtils.timeSinceMillis(startBurnTimeMs).toDouble() / burningTimeMs >= 0.01) {
92 burnProgress += 0.01f
93 startBurnTimeMs = TimeUtils.millis()
94 }
96 }
98 if (currentFuel?.isNone() == false && burnProgress >= 1f) {
99 if (canSmelt()) {
100 startBurning(gameItemsHolder)
101 } else {
102 currentFuel = null
103 burnProgress = 0f
104 smeltProgress = 0f
108 if (!canSmelt()) {
109 return
111 if (currentFuel == null && !fuel.isNoneOrNull()) {
112 startBurning(gameItemsHolder)
113 smeltStarTimeMs = startBurnTimeMs
114 smeltProgress = 0f
117 if ((TimeUtils.timeSinceMillis(smeltStarTimeMs).toDouble() / SMELTING_TIME_MS) >= 0.01) {
118 smeltProgress += 0.01f
119 smeltStarTimeMs = TimeUtils.millis()
122 if (isActive && smeltProgress >= 1f) {
123 val productKey = requireNotNull(input.item.params.smeltProductKey)
124 val res = gameItemsHolder.getItem(productKey)
125 if (result.isNoneOrNull()) {
126 result = res.toInventoryItem()
127 } else {
128 result.add()
130 input.subtract()
131 if (input.amount <= 0) {
132 input = gameItemsHolder.fallbackItem.toInventoryItem()
134 smeltStarTimeMs = TimeUtils.millis()
135 smeltProgress = 0f
139 override fun getSaveData(): SaveDataDto.FurnaceSaveData {
140 return SaveDataDto.FurnaceSaveData(
141 version = SAVE_DATA_VERSION,
142 size = size,
143 currentFuelItemKey = currentFuelKey,
144 items = items.map(InventoryItem::getSaveData),
145 startBurnTimeMs = startBurnTimeMs,
146 startSmeltTimeMs = smeltStarTimeMs,
147 burnProgress = burnProgress,
148 smeltProgress = smeltProgress,
152 companion object {
153 private const val SAVE_DATA_VERSION = 1
154 private const val SIZE = 3
155 private const val TAG = "Furnace"
157 const val FUEL_INDEX = 0
158 const val INPUT_INDEX = 1
159 const val RESULT_INDEX = 2
161 const val SMELTING_TIME_MS = 10000L
163 fun fromSaveData(saveData: SaveDataDto.FurnaceSaveData, gameItemsHolder: GameItemsHolder): Furnace {
164 saveData.verifyVersion(SAVE_DATA_VERSION)
166 return Furnace(
167 gameItemsHolder = gameItemsHolder,
168 initialItems = saveData.items.map { item ->
169 InventoryItem.fromSaveData(item, gameItemsHolder)
171 ).apply {
172 currentFuelKey = saveData.currentFuelItemKey
173 startBurnTimeMs = saveData.startSmeltTimeMs
174 smeltStarTimeMs = saveData.startSmeltTimeMs
175 burnProgress = saveData.burnProgress
176 smeltProgress = saveData.smeltProgress