From 01c7a29fe80282c9e4613bafb2937583a84eb0ee Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Mon, 22 Apr 2024 00:14:59 +0700 Subject: [PATCH] More genuine container contents shuffling --- .../dbotthepony/kstarbound/item/IContainer.kt | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/ru/dbotthepony/kstarbound/item/IContainer.kt b/src/main/kotlin/ru/dbotthepony/kstarbound/item/IContainer.kt index 32d63a88..a73dd3aa 100644 --- a/src/main/kotlin/ru/dbotthepony/kstarbound/item/IContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/kstarbound/item/IContainer.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.kstarbound.item import com.google.gson.JsonArray import com.google.gson.JsonElement +import it.unimi.dsi.fastutil.ints.IntArrayList import ru.dbotthepony.kstarbound.Starbound import ru.dbotthepony.kstarbound.defs.item.ItemDescriptor import java.util.random.RandomGenerator @@ -50,7 +51,7 @@ interface IContainer { return count } - fun shuffle(random: RandomGenerator) { + fun shuffle(random: RandomGenerator, split: Boolean = true, splitChance: Float = 0.8f) { for (i in 0 until size) { val rand = random.nextInt(size) val a = this[i] @@ -59,6 +60,53 @@ interface IContainer { this[rand] = a this[i] = b } + + if (split) { + val emptySlots = IntArrayList() + val splittableSlots = IntArrayList() + + for (i in 0 until size) { + if (this[i].isEmpty) { + emptySlots.add(i) + } else if (this[i].size > 1L) { + splittableSlots.add(i) + } + } + + if (splittableSlots.isNotEmpty() && emptySlots.isNotEmpty()) { + for (tslot in splittableSlots) { + if (emptySlots.isEmpty) + break + + if (random.nextFloat() <= splitChance) { + var currentChance = splitChance + val workingSlots = IntArrayList() + workingSlots.add(tslot) + + while (workingSlots.isNotEmpty() && emptySlots.isNotEmpty()) { + val slot = workingSlots.removeInt(0) + val item = this[slot] + val splitAmount = random.nextLong(1L, item.size) + val copy = item.copy(splitAmount) + item.size -= splitAmount + + val targetSlot = emptySlots.removeInt(random.nextInt(emptySlots.size)) + this[targetSlot] = copy + + currentChance *= 0.75f + + if (item.size > 1L && random.nextFloat() <= currentChance) { + workingSlots.add(slot) + } + + if (splitAmount > 1L && random.nextFloat() <= currentChance) { + workingSlots.add(targetSlot) + } + } + } + } + } + } } // puts item into container, returns remaining not put items