189 lines
3.6 KiB
Kotlin
189 lines
3.6 KiB
Kotlin
package ru.dbotthepony.kstarbound.item
|
|
|
|
import com.google.gson.JsonArray
|
|
import com.google.gson.JsonElement
|
|
import ru.dbotthepony.kstarbound.Starbound
|
|
import ru.dbotthepony.kstarbound.defs.item.ItemDescriptor
|
|
import java.util.random.RandomGenerator
|
|
|
|
interface IContainer {
|
|
var size: Int
|
|
operator fun get(index: Int): ItemStack
|
|
operator fun set(index: Int, value: ItemStack)
|
|
|
|
fun ageItems(by: Double): Boolean {
|
|
var any = false
|
|
|
|
for (i in 0 until size) {
|
|
val (newItem, hasAdvanced) = this[i].advanceAge(by)
|
|
any = hasAdvanced || any
|
|
|
|
if (newItem != null) {
|
|
this[i] = newItem
|
|
}
|
|
}
|
|
|
|
return any
|
|
}
|
|
|
|
fun hasCountOfItem(item: ItemDescriptor, exactMatch: Boolean = false): Long {
|
|
var count = 0L
|
|
|
|
for (i in 0 until size) {
|
|
if (this[i].matches(item, exactMatch)) {
|
|
count += this[i].size
|
|
}
|
|
}
|
|
|
|
return count
|
|
}
|
|
|
|
fun hasCountOfItem(item: ItemStack, exactMatch: Boolean = false): Long {
|
|
var count = 0L
|
|
|
|
for (i in 0 until size) {
|
|
if (this[i].matches(item, exactMatch)) {
|
|
count += this[i].size
|
|
}
|
|
}
|
|
|
|
return count
|
|
}
|
|
|
|
fun shuffle(random: RandomGenerator) {
|
|
for (i in 0 until size) {
|
|
val rand = random.nextInt(size)
|
|
val a = this[i]
|
|
val b = this[rand]
|
|
|
|
this[rand] = a
|
|
this[i] = b
|
|
}
|
|
}
|
|
|
|
// puts item into container, returns remaining not put items
|
|
fun add(item: ItemStack, simulate: Boolean = false): ItemStack {
|
|
val copy = item.copy()
|
|
|
|
// first, try to put into not empty slots first
|
|
for (i in 0 until size) {
|
|
val itemThere = this[i]
|
|
|
|
if (itemThere.isStackable(copy)) {
|
|
val newCount = (itemThere.size + copy.size).coerceAtMost(itemThere.maxStackSize)
|
|
val diff = newCount - itemThere.size
|
|
|
|
copy.size -= diff
|
|
|
|
if (!simulate)
|
|
itemThere.size += diff
|
|
|
|
if (copy.isEmpty)
|
|
return ItemStack.EMPTY
|
|
}
|
|
}
|
|
|
|
// then try to move into empty slots
|
|
for (i in 0 until size) {
|
|
val itemThere = this[i]
|
|
|
|
if (itemThere.isEmpty) {
|
|
if (copy.size > copy.maxStackSize) {
|
|
if (!simulate)
|
|
this[i] = copy.copy(copy.maxStackSize)
|
|
|
|
copy.size -= copy.maxStackSize
|
|
} else {
|
|
if (!simulate)
|
|
this[i] = copy
|
|
|
|
return ItemStack.EMPTY
|
|
}
|
|
}
|
|
}
|
|
|
|
return copy
|
|
}
|
|
|
|
fun clear()
|
|
|
|
fun toJson(store: Boolean = false): JsonArray {
|
|
val result = JsonArray(size)
|
|
|
|
if (store) {
|
|
Starbound.storeJson {
|
|
for (i in 0 until size) {
|
|
result.add(this[i].toJson())
|
|
}
|
|
}
|
|
} else {
|
|
for (i in 0 until size) {
|
|
result.add(this[i].toJson())
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
fun fromJson(json: JsonElement, resize: Boolean = false): List<ItemStack> {
|
|
clear()
|
|
|
|
val read = ArrayList<ItemStack>()
|
|
val array = json.asJsonArray
|
|
var nonEmpty = 0
|
|
|
|
for (i in 0 until array.size()) {
|
|
val item = ItemDescriptor(array[i])
|
|
|
|
if (item.isNotEmpty)
|
|
nonEmpty++
|
|
|
|
read.add(item.build())
|
|
}
|
|
|
|
if (read.size > size) {
|
|
// we have a problem
|
|
|
|
if (resize) {
|
|
// no problem
|
|
size = read.size
|
|
|
|
for ((i, item) in read.withIndex()) {
|
|
this[i] = item
|
|
}
|
|
|
|
return emptyList()
|
|
} else {
|
|
// first, put items to their place if they are within container size
|
|
|
|
for (i in 0 until size) {
|
|
this[i] = read[i]
|
|
}
|
|
|
|
// second, try to move remaining item into empty or stackable slots
|
|
val lost = ArrayList<ItemStack>()
|
|
|
|
for (i in size until read.size) {
|
|
val remaining = add(read[i])
|
|
|
|
if (remaining.isNotEmpty) {
|
|
lost.add(remaining)
|
|
}
|
|
}
|
|
|
|
// if we weren't capable of putting excess items into container, then what a shame.
|
|
return lost
|
|
}
|
|
} else {
|
|
if (read.size < size && resize)
|
|
size = read.size
|
|
|
|
for ((i, item) in read.withIndex()) {
|
|
this[i] = item
|
|
}
|
|
|
|
return emptyList()
|
|
}
|
|
}
|
|
}
|