DEADSOFTWARE

New saving fromat and rewrite in kotlin
[cavedroid.git] / core / src / ru / deadsoftware / cavedroid / game / mobs / player / Inventory.kt
1 package ru.deadsoftware.cavedroid.game.mobs.player
3 import ru.deadsoftware.cavedroid.game.GameItemsHolder
4 import ru.deadsoftware.cavedroid.game.model.dto.SaveDataDto
5 import ru.deadsoftware.cavedroid.game.model.item.InventoryItem
6 import ru.deadsoftware.cavedroid.game.model.item.Item
7 import ru.deadsoftware.cavedroid.game.objects.drop.Drop
8 import ru.deadsoftware.cavedroid.game.ui.TooltipManager
9 import ru.deadsoftware.cavedroid.misc.Saveable
10 import java.io.Serializable
12 class Inventory @JvmOverloads constructor(
13 val size: Int,
14 val hotbarSize: Int,
15 gameItemsHolder: GameItemsHolder,
16 tooltipManager: TooltipManager,
17 initialItems: List<InventoryItem>? = null
18 ) : Serializable, Saveable {
20 @Suppress("UNNECESSARY_LATEINIT")
21 @Transient
22 private lateinit var tooltipManager: TooltipManager
24 @Suppress("UNNECESSARY_LATEINIT")
25 @Transient
26 private lateinit var fallbackItem: InventoryItem
28 private val _items: Array<InventoryItem>
30 init {
31 fallbackItem = gameItemsHolder.fallbackItem.toInventoryItem()
32 this.tooltipManager = tooltipManager
34 if (size < 0 || hotbarSize < 0 || hotbarSize > size) {
35 throw IllegalArgumentException("Invalid inventory sizes: hotbarSize=$hotbarSize; size=$size")
36 }
38 _items = Array(size) { index -> initialItems?.getOrNull(index) ?: InventoryItem(gameItemsHolder.fallbackItem) }
39 }
41 val items get() = _items.asList() as MutableList<InventoryItem>
43 val hotbarItems get() = items.subList(0, hotbarSize)
45 private var _activeSlot = 0
47 var activeSlot
48 get() = _activeSlot
49 set(value) {
50 if (value in 0 ..< hotbarSize) {
51 _activeSlot = value
52 showCurrentItemTooltip()
53 }
54 }
56 fun showCurrentItemTooltip() {
57 tooltipManager.showHotbarTooltip(activeItem.item.params.name)
58 }
60 val activeItem get() = _items[activeSlot]
62 fun initItems(gameItemsHolder: GameItemsHolder, tooltipManager: TooltipManager) {
63 this.tooltipManager = tooltipManager
64 fallbackItem = gameItemsHolder.fallbackItem.toInventoryItem()
65 _items.forEach { item ->
66 item.init(gameItemsHolder)
67 }
68 }
70 private fun getItemPickSlot(drop: Drop): Int {
71 val item = drop.item
73 for (i in _items.indices) {
74 val inventoryItem = _items[i]
76 if (item == inventoryItem.item && inventoryItem.canBeAdded()) {
77 return i
78 }
79 }
81 for (i in _items.indices) {
82 val inventoryItem = _items[i]
84 if (inventoryItem.item.isNone()) {
85 return i
86 }
87 }
89 return -1
90 }
92 fun canPickItem(drop: Drop): Boolean {
93 return getItemPickSlot(drop) >= 0
94 }
96 fun pickDrop(drop: Drop) {
97 val slot = getItemPickSlot(drop).takeIf { it >= 0 } ?: return
98 val inventoryItem = _items[slot]
100 if (inventoryItem.item == drop.item) {
101 if (inventoryItem.canBeAdded(drop.amount)) {
102 inventoryItem.add(drop.amount)
103 drop.pickedUp = true
104 } else {
105 val addCount = inventoryItem.item.params.maxStack - inventoryItem.amount
106 inventoryItem.add(addCount)
107 drop.subtract(addCount)
108 pickDrop(drop)
110 } else {
111 _items[slot] = drop.item.toInventoryItem(drop.amount)
112 if (slot == activeSlot) {
113 showCurrentItemTooltip()
115 drop.pickedUp = true
119 fun addItem(item: Item) {
120 _items.copyInto(
121 destination = _items,
122 destinationOffset = 1,
123 startIndex = 0,
124 endIndex = size - 1
127 _items[0] = item.toInventoryItem(item.params.maxStack)
128 showCurrentItemTooltip()
131 @JvmOverloads
132 fun decreaseItemAmount(slot: Int, count: Int = 1) {
133 val item = _items[slot]
134 item.subtract(count)
135 if (item.amount <= 0) {
136 _items[slot] = fallbackItem
140 @JvmOverloads
141 fun decreaseCurrentItemAmount(count: Int = 1) {
142 decreaseItemAmount(activeSlot, count)
145 fun clear() {
146 for (i in _items.indices) {
147 _items[i] = fallbackItem
151 override fun getSaveData(): SaveDataDto.InventorySaveData {
152 return SaveDataDto.InventorySaveData(
153 version = SAVE_DATA_VERSION,
154 size = size,
155 hotbarSize = hotbarSize,
156 activeSlot = _activeSlot,
157 items = items.map(InventoryItem::getSaveData)
161 companion object {
162 private const val SAVE_DATA_VERSION = 1
164 fun fromSaveData(
165 saveData: SaveDataDto.InventorySaveData,
166 gameItemsHolder: GameItemsHolder,
167 tooltipManager: TooltipManager,
168 ): Inventory {
169 saveData.verifyVersion(SAVE_DATA_VERSION)
171 return Inventory(
172 size = saveData.size,
173 hotbarSize = saveData.hotbarSize,
174 gameItemsHolder = gameItemsHolder,
175 tooltipManager = tooltipManager,
176 initialItems = saveData.items.map { item -> InventoryItem.fromSaveData(item, gameItemsHolder) }
177 ).apply {
178 _activeSlot = saveData.activeSlot