Clean up container iterators and move container extensions

This commit is contained in:
DBotThePony 2022-09-02 00:00:07 +07:00
parent ea701e70c9
commit e6b8b9b409
Signed by: DBot
GPG Key ID: DCC23B5715498507
39 changed files with 252 additions and 234 deletions

View File

@ -9,7 +9,7 @@ import net.minecraft.core.Direction
import net.minecraft.resources.ResourceLocation
import net.minecraftforge.client.model.generators.ModelBuilder
import net.minecraftforge.common.data.ExistingFileHelper
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
data class TextureSize(val width: Float, val height: Float) {
constructor(arr: JsonArray) : this(arr[0].asFloat, arr[1].asFloat)

View File

@ -7,7 +7,7 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.crafting.RecipeSerializer
import ru.dbotthepony.mc.otm.recipe.PlatePressRecipe
import ru.dbotthepony.mc.otm.recipe.PlatePressRecipeFactory
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
class PlatePressFinishedRecipe(private val recipe: PlatePressRecipe) : FinishedRecipe {
override fun serializeRecipeData(it: JsonObject) {

View File

@ -5,7 +5,7 @@ import net.minecraftforge.common.util.INBTSerializable
import net.minecraftforge.event.entity.living.LivingHurtEvent
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.core.readNbt
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.core.writeNbt
import java.io.InputStream
import java.io.OutputStream

View File

@ -8,7 +8,7 @@ import net.minecraftforge.common.util.INBTSerializable
import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.client.render.SkinElement
import ru.dbotthepony.mc.otm.core.readNbt
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.core.writeNbt
import java.io.InputStream
import java.io.OutputStream

View File

@ -8,7 +8,7 @@ import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.client.render.SkinElement
import ru.dbotthepony.mc.otm.container.iterator
import ru.dbotthepony.mc.otm.container.nonEmptyIterator
import ru.dbotthepony.mc.otm.registry.MRegistry
import kotlin.collections.ArrayList
@ -260,7 +260,7 @@ class AndroidResearchBuilder(
for (item in items) {
var required = item.count
val iterator = capability.ply.inventory.iterator()
val iterator = capability.ply.inventory.nonEmptyIterator()
for (invItem in iterator) {
if (ItemStack.isSameItemSameTags(invItem, item)) {

View File

@ -9,7 +9,7 @@ import ru.dbotthepony.mc.otm.capability.extractEnergyInnerExact
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
import ru.dbotthepony.mc.otm.registry.StatNames
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import kotlin.math.roundToInt
class NanobotsArmor(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.NANOBOTS_ARMOR, android) {

View File

@ -8,7 +8,7 @@ import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.registry.AndroidFeatures
import ru.dbotthepony.mc.otm.registry.StatNames
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import kotlin.math.roundToInt
class NanobotsRegeneration(android: MatteryPlayerCapability) : AndroidFeature(AndroidFeatures.NANOBOTS_REGENERATION, android) {

View File

@ -17,7 +17,7 @@ import ru.dbotthepony.mc.otm.block.CargoCrateBlock
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.menu.CargoCrateMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
class CargoCrateBlockEntity(
p_155229_: BlockPos,

View File

@ -24,7 +24,7 @@ import net.minecraft.world.level.Level
import net.minecraftforge.common.capabilities.Capability
import ru.dbotthepony.mc.otm.addPreWorldTickerOnce
import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : BlockEntity(p_155228_, p_155229_, p_155230_), MenuProvider {
var customDisplayName: Component? = null

View File

@ -13,7 +13,7 @@ import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.core.ifPresentK
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
abstract class MatteryPoweredBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: BlockPos, p_155230_: BlockState) : MatteryBlockEntity(p_155228_, p_155229_, p_155230_) {
abstract val energy: BlockEnergyStorageImpl

View File

@ -8,7 +8,6 @@ import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.block.Block
import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.core.map
import ru.dbotthepony.mc.otm.core.set
private fun isReason(status: Any?, reason: Any) = status == null || status == reason

View File

@ -21,13 +21,17 @@ import net.minecraft.server.level.ServerLevel
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.Block
import net.minecraftforge.common.capabilities.Capability
import net.minecraftforge.common.capabilities.ForgeCapabilities
import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.capability.matter.*
import ru.dbotthepony.mc.otm.container.forEachCapability
import ru.dbotthepony.mc.otm.container.iterator
import ru.dbotthepony.mc.otm.graph.Graph6Node
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.core.set
import java.util.ArrayList
@ -130,9 +134,9 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
if (valid) {
if (cap === MatteryCapability.PATTERN) return resolverPatterns.cast()
if (cap === MatteryCapability.MATTER_NODE) return resolverNode.cast()
if (cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY) return resolverItem.get().cast()
if (cap == MatteryCapability.PATTERN) return resolverPatterns.cast()
if (cap == MatteryCapability.MATTER_NODE) return resolverNode.cast()
if (cap == ForgeCapabilities.ITEM_HANDLER) return resolverItem.get().cast()
}
return super.getCapability(cap, side)
@ -147,14 +151,14 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
override val storedPatterns: Collection<PatternState> get() {
val list = ArrayList<PatternState>()
patterns.consumeCapability(MatteryCapability.PATTERN) { capability: IPatternStorage -> list.addAll(capability.storedPatterns) }
patterns.forEachCapability(MatteryCapability.PATTERN) { capability: IPatternStorage -> list.addAll(capability.storedPatterns) }
return list
}
override val capacity: Int get() {
var stored = 0L
for (pattern in patterns.capabilityIterator(MatteryCapability.PATTERN))
for ((_, pattern) in patterns.iterator(MatteryCapability.PATTERN))
stored += pattern.capacity.toLong()
return if (stored > Int.MAX_VALUE) Int.MAX_VALUE else stored.toInt()
@ -163,7 +167,7 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
override val stored: Int get() {
var stored = 0L
for (pattern in patterns.capabilityIterator(MatteryCapability.PATTERN))
for ((_, pattern) in patterns.iterator(MatteryCapability.PATTERN))
stored += pattern.stored.toLong()
return if (stored > Int.MAX_VALUE) Int.MAX_VALUE else stored.toInt()
@ -175,7 +179,7 @@ class PatternStorageBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
}
override fun insertPattern(pattern: PatternState, only_update: Boolean, simulate: Boolean): PatternInsertStatus {
for (storage in patterns.capabilityIterator(MatteryCapability.PATTERN)) {
for ((_, storage) in patterns.iterator(MatteryCapability.PATTERN)) {
val status = storage.insertPattern(pattern, only_update, simulate)
if (!status.isFailed) {

View File

@ -20,7 +20,7 @@ import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.menu.PlatePressMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.registry.MRecipes
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
class PlatePressBlockEntity(
p_155229_: BlockPos,

View File

@ -31,7 +31,7 @@ import ru.dbotthepony.mc.otm.matter.getMatterValue
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.registry.MItems
import ru.dbotthepony.mc.otm.registry.MRegistry
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import kotlin.math.roundToInt
import kotlin.math.sqrt

View File

@ -23,7 +23,6 @@ import ru.dbotthepony.mc.otm.block.BlockExplosionDebugger
import ru.dbotthepony.mc.otm.core.*
import ru.dbotthepony.mc.otm.core.Vector
import ru.dbotthepony.mc.otm.registry.MRegistry
import ru.dbotthepony.mc.otm.core.set
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap

View File

@ -33,7 +33,7 @@ import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.menu.MatterBottlerMenu
import ru.dbotthepony.mc.otm.core.orNull
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
class MatterBottlerBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
MatteryPoweredBlockEntity(MBlockEntities.MATTER_BOTTLER, p_155229_, p_155230_), IMatterGraphNode {

View File

@ -28,7 +28,7 @@ import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph
import ru.dbotthepony.mc.otm.menu.MatterCapacitorBankMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import javax.annotation.ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault

View File

@ -26,7 +26,7 @@ import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.container.MatteryContainerFilter
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.getImpreciseFraction
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.graph.Graph6Node
import ru.dbotthepony.mc.otm.graph.matter.IMatterGraphNode
import ru.dbotthepony.mc.otm.graph.matter.MatterNetworkGraph

View File

@ -31,7 +31,7 @@ import ru.dbotthepony.mc.otm.item.MatterDustItem
import ru.dbotthepony.mc.otm.core.map
import ru.dbotthepony.mc.otm.menu.MatterRecyclerMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
class MatterRecyclerBlockEntity(blockPos: BlockPos, blockState: BlockState)
: MatteryWorkerBlockEntity<MatteryWorkerBlockEntity.Job>(MBlockEntities.MATTER_RECYCLER, blockPos, blockState, ::Job), IMatterGraphNode {

View File

@ -31,7 +31,7 @@ import ru.dbotthepony.mc.otm.matter.baselineComplexityReplicateTicks
import ru.dbotthepony.mc.otm.matter.getMatterValue
import ru.dbotthepony.mc.otm.menu.MatterReplicatorMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
class MatterReplicatorBlockEntity(p_155229_: BlockPos, p_155230_: BlockState) :
MatteryWorkerBlockEntity<MatterReplicatorBlockEntity.ReplicatorJob>(MBlockEntities.MATTER_REPLICATOR, p_155229_, p_155230_, ::ReplicatorJob), IMatterGraphNode {

View File

@ -22,7 +22,7 @@ import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.menu.DriveRackMenu
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.storage.*

View File

@ -20,7 +20,7 @@ import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.menu.DriveViewerMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import javax.annotation.ParametersAreNonnullByDefault
@MethodsReturnNonnullByDefault

View File

@ -32,14 +32,14 @@ import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.container.MatteryContainer
import ru.dbotthepony.mc.otm.core.get
import ru.dbotthepony.mc.otm.container.get
import ru.dbotthepony.mc.otm.graph.storage.BasicStorageGraphNode
import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.menu.ItemMonitorMenu
import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.storage.*
import java.math.BigInteger
import java.util.*

View File

@ -24,7 +24,7 @@ import ru.dbotthepony.mc.otm.graph.storage.StorageNetworkGraph
import ru.dbotthepony.mc.otm.menu.StoragePowerSupplierMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities
import ru.dbotthepony.mc.otm.registry.MNames
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
class StoragePowerSupplierBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryPoweredBlockEntity(MBlockEntities.STORAGE_POWER_SUPPLIER, blockPos, blockState) {
override val defaultDisplayName: Component

View File

@ -15,7 +15,7 @@ import net.minecraftforge.common.util.LazyOptional
import ru.dbotthepony.mc.otm.compat.mekanism.MatteryToMekanismEnergyWrapper
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.core.tagNotNull
private enum class EnergyFlow {

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.capability
import net.minecraft.core.Direction
import net.minecraft.world.entity.LivingEntity
import net.minecraft.world.entity.player.Player
import net.minecraftforge.common.capabilities.ForgeCapabilities
import net.minecraftforge.common.capabilities.ICapabilityProvider
import net.minecraftforge.common.util.LazyOptional

View File

@ -11,7 +11,7 @@ import ru.dbotthepony.mc.otm.core.BigInteger
import ru.dbotthepony.mc.otm.core.isPositive
import ru.dbotthepony.mc.otm.core.serializeNBT
import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.storage.*
import java.math.BigInteger
import java.util.ArrayList

View File

@ -9,7 +9,7 @@ import net.minecraftforge.registries.ForgeRegistries
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.core.BigInteger
import ru.dbotthepony.mc.otm.core.serializeNBT
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import ru.dbotthepony.mc.otm.storage.IStorageTuple
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
import ru.dbotthepony.mc.otm.storage.StorageStackType

View File

@ -4,7 +4,7 @@ import net.minecraft.nbt.CompoundTag
import net.minecraftforge.common.util.INBTSerializable
import net.minecraftforge.common.util.LazyOptional
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
open class MatterHandlerImpl @JvmOverloads constructor(
protected val listener: Runnable?,

View File

@ -0,0 +1,69 @@
package ru.dbotthepony.mc.otm.container
import net.minecraft.world.Container
import net.minecraft.world.item.ItemStack
operator fun Container.set(index: Int, value: ItemStack) = setItem(index, value)
operator fun Container.get(index: Int): ItemStack = getItem(index)
fun Container.addItem(stack: ItemStack, range: IntRange, simulate: Boolean = false): ItemStack {
if (this is MatteryContainer) {
return this.addItem(stack, range, simulate)
}
if (range.last >= containerSize || range.first < 0)
throw IllegalArgumentException("Invalid range: $range")
if (stack.isEmpty)
return stack
val copy = stack.copy()
// двигаем в одинаковые слоты
for (slot in range) {
if (ItemStack.isSameItemSameTags(this[slot], copy)) {
val slotStack = this[slot]
val slotLimit = maxStackSize.coerceAtMost(slotStack.maxStackSize)
if (slotStack.count < slotLimit) {
val newCount = (slotStack.count + copy.count).coerceAtMost(slotLimit)
val diff = newCount - slotStack.count
if (!simulate) {
slotStack.count = newCount
setChanged()
}
copy.shrink(diff)
if (copy.isEmpty) {
return copy
}
}
}
}
// двигаем в пустые слоты
for (slot in range) {
if (this[slot].isEmpty) {
val diff = copy.count.coerceAtMost(maxStackSize.coerceAtMost(copy.maxStackSize))
if (!simulate) {
val copyToPut = copy.copy()
copyToPut.count = diff
this[slot] = copyToPut
setChanged()
}
copy.shrink(diff)
if (copy.isEmpty) {
return copy
}
}
}
return copy
}
fun Container.addItem(stack: ItemStack, simulate: Boolean): ItemStack = addItem(stack, 0 until containerSize, simulate)

View File

@ -14,7 +14,7 @@ import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.network.MatteryPacket
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
import java.util.Arrays
import java.util.LinkedList
import java.util.function.Supplier

View File

@ -3,95 +3,163 @@ package ru.dbotthepony.mc.otm.container
import net.minecraft.world.Container
import net.minecraft.world.item.ItemStack
import net.minecraftforge.common.capabilities.Capability
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.core.ifPresentK
import java.util.function.Consumer
class ContainerIteratorItemStack(private val container: Container) : MutableIterator<ItemStack>, Iterable<ItemStack> {
private var scanIndex = 0
private var nextStack: ItemStack? = null
private var nextIndex = 0
class ContainerIterator(private val container: Container) : MutableIterator<ItemStack> {
private var index = 0
override fun hasNext(): Boolean {
if (scanIndex >= container.containerSize && nextStack == null)
return false
while (nextStack == null && scanIndex < container.containerSize) {
val get = container.getItem(scanIndex)
if (!get.isEmpty) {
nextStack = get
nextIndex = scanIndex
}
scanIndex++
}
return nextStack != null
return index < container.containerSize
}
override fun next(): ItemStack {
if (!hasNext()) {
throw NoSuchElementException()
if (index >= container.containerSize) {
throw IllegalStateException("Already finished iterating")
}
val nextStack = nextStack!!
this.nextStack = null
return nextStack
return container[index++]
}
override fun remove() {
container[nextIndex] = ItemStack.EMPTY
}
override fun iterator(): Iterator<ItemStack> {
return this
}
fun consume(consumer: Consumer<ItemStack?>) {
for (t in this) {
consumer.accept(t)
if (index == 0) {
throw IllegalStateException("Never called next()")
}
container[index - 1] = ItemStack.EMPTY
}
}
fun Container.iterator() = ContainerIteratorItemStack(this)
fun Container.iterator() = ContainerIterator(this)
class ContainerIteratorCapability<T>(private val container: Container, private val cap: Capability<T>) : Iterator<T>, Iterable<T> {
private var index = 0
private var nextStack: T? = null
class NonEmptyContainerIterator(container: Container) : MutableIterator<ItemStack> {
private val parent = ContainerIterator(container)
private var itemStack: ItemStack? = null
private var searched = false
private fun search() {
searched = true
if (itemStack != null) {
return
}
for (stack in parent) {
if (!stack.isEmpty) {
itemStack = stack
return
}
}
}
override fun hasNext(): Boolean {
if (index >= container.containerSize && nextStack == null)
return false
if (!searched) {
search()
}
while (nextStack == null && index < container.containerSize) {
val get = container.getItem(index)
return itemStack != null
}
if (!get.isEmpty) {
get.getCapability(cap).ifPresent { t: T -> nextStack = t }
override fun next(): ItemStack {
if (!searched) {
search()
}
val itemStack = itemStack ?: throw IllegalStateException("No next element")
this.itemStack = null
this.searched = false
return itemStack
}
override fun remove() {
parent.remove()
}
}
fun Container.nonEmptyIterator() = NonEmptyContainerIterator(this)
class ContainerIteratorCapability<T>(container: Container, private val cap: Capability<T>) : MutableIterator<Pair<ItemStack, T>> {
private val parent = NonEmptyContainerIterator(container)
private var itemStack: ItemStack? = null
private var capability: T? = null
private var searched = false
private fun search() {
searched = true
if (itemStack != null) {
return
}
for (item in parent) {
item.getCapability(cap).ifPresentK {
itemStack = item
capability = it
return
}
}
}
index++
override fun hasNext(): Boolean {
if (!searched) {
search()
}
return nextStack != null
return itemStack != null
}
override fun next(): T {
val nextStack = nextStack!!
this.nextStack = null
return nextStack
}
override fun iterator(): Iterator<T> {
return this
}
fun consume(consumer: Consumer<T>) {
for (t in this) {
consumer.accept(t)
override fun next(): Pair<ItemStack, T> {
if (!searched) {
search()
}
val itemStack = itemStack ?: throw IllegalStateException("No next element")
val capability = capability ?: throw IllegalStateException("No next element")
this.itemStack = null
this.capability = null
this.searched = false
return itemStack to capability
}
override fun remove() {
parent.remove()
}
}
fun <T> Container.iterator(cap: Capability<T>) = ContainerIteratorCapability(this, cap)
inline fun <T> Container.forEach(cap: Capability<T>, consumer: (Pair<ItemStack, T>) -> Unit) {
for (value in iterator(cap)) {
consumer(value)
}
}
inline fun <T> Container.forEach(cap: Capability<T>, consumer: (ItemStack, T) -> Unit) {
for ((a, b) in iterator(cap)) {
consumer(a, b)
}
}
inline fun <T> Container.forEachItem(cap: Capability<T>, consumer: (ItemStack) -> Unit) {
for (pair in iterator(cap)) {
consumer(pair.first)
}
}
inline fun <T> Container.forEachCapability(cap: Capability<T>, consumer: (T) -> Unit) {
for (pair in iterator(cap)) {
consumer(pair.second)
}
}
inline fun Container.forEach(lambda: (ItemStack) -> Unit) {
for (value in iterator()) {
lambda(value)
}
}
inline fun Container.forEachNonEmpty(lambda: (ItemStack) -> Unit) {
for (value in nonEmptyIterator()) {
lambda(value)
}
}

View File

@ -8,12 +8,8 @@ import net.minecraft.world.Container
import kotlin.jvm.JvmOverloads
import net.minecraft.world.entity.player.Player
import net.minecraft.world.level.block.entity.BlockEntity
import net.minecraftforge.common.capabilities.Capability
import ru.dbotthepony.mc.otm.core.get
import ru.dbotthepony.mc.otm.core.ifHas
import ru.dbotthepony.mc.otm.core.set
import java.util.*
import java.util.function.Consumer
@Suppress("UNUSED")
open class MatteryContainer(val watcher: Runnable, private val size: Int) : Container, Iterable<ItemStack> {
@ -71,7 +67,6 @@ open class MatteryContainer(val watcher: Runnable, private val size: Int) : Cont
return
}
// нам не интересен размер
for (i in 0 until tag.size.coerceAtMost(size)) {
slots[i] = ItemStack.of(tag[i] as CompoundTag)
}
@ -80,46 +75,16 @@ open class MatteryContainer(val watcher: Runnable, private val size: Int) : Cont
}
fun deserializeNBT(tag: Tag?) {
if (tag is CompoundTag) {
deserializeNBT(tag)
} else if (tag is ListTag) {
deserializeNBT(tag)
} else {
Arrays.fill(slots, ItemStack.EMPTY)
setChanged()
}
}
fun stacks(): ContainerIteratorItemStack {
return ContainerIteratorItemStack(this)
}
fun forEachNonEmpty(consumer: (ItemStack) -> Unit) {
for (item in slots) {
if (!item.isEmpty) {
consumer(item)
when (tag) {
is CompoundTag -> deserializeNBT(tag)
is ListTag -> deserializeNBT(tag)
else -> {
Arrays.fill(slots, ItemStack.EMPTY)
setChanged()
}
}
}
fun forEachNonEmpty(consumer: (ItemStack, Int) -> Unit) {
for (i in 0 until size) {
val item = slots[i]
if (!item.isEmpty) {
consumer(item, i)
}
}
}
fun <T> capabilityIterator(cap: Capability<T>): ContainerIteratorCapability<T> {
return ContainerIteratorCapability(this, cap)
}
fun <T> consumeCapability(cap: Capability<T>, consumer: Consumer<T>) {
capabilityIterator(cap).consume(consumer)
}
open fun setChanged(slot: Int, new: ItemStack, old: ItemStack) {
if (ignoreChangeNotifications == 0) watcher.run()
}
@ -345,90 +310,6 @@ open class MatteryContainer(val watcher: Runnable, private val size: Int) : Cont
}
final override fun iterator(): MutableIterator<ItemStack> {
return object : MutableIterator<ItemStack> {
private var index = 0
override fun hasNext(): Boolean {
return index < size
}
override fun next(): ItemStack {
if (index >= size) {
throw IllegalStateException("Already finished iterating")
}
return slots[index++]
}
override fun remove() {
if (index == 0) {
throw IllegalStateException("Never called next()")
}
set(index - 1, ItemStack.EMPTY)
}
}
return ContainerIterator(this)
}
}
fun Container.addItem(stack: ItemStack, range: IntRange, simulate: Boolean = false): ItemStack {
if (this is MatteryContainer) {
return this.addItem(stack, range, simulate)
}
if (range.last >= containerSize || range.first < 0)
throw IllegalArgumentException("Invalid range: $range")
if (stack.isEmpty)
return stack
val copy = stack.copy()
// двигаем в одинаковые слоты
for (slot in range) {
if (ItemStack.isSameItemSameTags(this[slot], copy)) {
val slotStack = this[slot]
val slotLimit = maxStackSize.coerceAtMost(slotStack.maxStackSize)
if (slotStack.count < slotLimit) {
val newCount = (slotStack.count + copy.count).coerceAtMost(slotLimit)
val diff = newCount - slotStack.count
if (!simulate) {
slotStack.count = newCount
setChanged()
}
copy.shrink(diff)
if (copy.isEmpty) {
return copy
}
}
}
}
// двигаем в пустые слоты
for (slot in range) {
if (this[slot].isEmpty) {
val diff = copy.count.coerceAtMost(maxStackSize.coerceAtMost(copy.maxStackSize))
if (!simulate) {
val copyToPut = copy.copy()
copyToPut.count = diff
this[slot] = copyToPut
setChanged()
}
copy.shrink(diff)
if (copy.isEmpty) {
return copy
}
}
}
return copy
}
fun Container.addItem(stack: ItemStack, simulate: Boolean): ItemStack = addItem(stack, 0 until containerSize, simulate)

View File

@ -10,7 +10,6 @@ import net.minecraft.nbt.ByteArrayTag
import net.minecraft.nbt.CompoundTag
import net.minecraft.nbt.Tag
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.world.Container
import net.minecraft.world.entity.Entity
import net.minecraft.world.item.ItemStack
import net.minecraft.world.phys.Vec3
@ -220,9 +219,6 @@ fun FriendlyByteBuf.writeBigInteger(value: BigInteger) {
fun FriendlyByteBuf.readBigInteger(byteLimit: Int = 128) = BigInteger(readByteArray(byteLimit))
operator fun Container.set(index: Int, value: ItemStack) = setItem(index, value)
operator fun Container.get(index: Int): ItemStack = getItem(index)
operator fun IItemHandler.get(index: Int): ItemStack = getStackInSlot(index)
operator fun JsonObject.set(s: String, value: JsonElement) = add(s, value)

View File

@ -11,7 +11,7 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.matter.IMatterItem
import ru.dbotthepony.mc.otm.matter.MatterTuple
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
class MatterDustItem : Item(Properties().tab(OverdriveThatMatters.INSTANCE.CREATIVE_TAB).stacksTo(64)), IMatterItem {
private fun matter(stack: ItemStack): ImpreciseFraction {

View File

@ -10,7 +10,8 @@ import net.minecraft.world.item.ItemStack
import net.minecraftforge.network.PacketDistributor
import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorBlockEntity
import ru.dbotthepony.mc.otm.block.entity.storage.ItemMonitorPlayerSettings
import ru.dbotthepony.mc.otm.core.get
import ru.dbotthepony.mc.otm.container.get
import ru.dbotthepony.mc.otm.container.nonEmptyIterator
import ru.dbotthepony.mc.otm.menu.data.INetworkedItemViewProvider
import ru.dbotthepony.mc.otm.menu.data.NetworkedItemView
import ru.dbotthepony.mc.otm.network.MenuNetworkChannel
@ -197,7 +198,7 @@ class ItemMonitorMenu @JvmOverloads constructor(
var maxStack = 64
if (settings.craftingAmount == ItemMonitorPlayerSettings.Amount.FULL) {
for (gridItem in tile.craftingGrid.stacks()) {
for (gridItem in tile.craftingGrid.nonEmptyIterator()) {
if (!gridItem.isStackable) {
hasUnstackables = true
break
@ -206,7 +207,7 @@ class ItemMonitorMenu @JvmOverloads constructor(
} else {
maxStack = 0
for (gridItem in tile.craftingGrid.stacks()) {
for (gridItem in tile.craftingGrid.nonEmptyIterator()) {
maxStack = maxStack.coerceAtLeast(gridItem.maxStackSize)
}
}

View File

@ -8,7 +8,7 @@ import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items
import net.minecraftforge.registries.ForgeRegistries
import ru.dbotthepony.mc.otm.core.registryName
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
fun stackFromJson(obj: JsonElement, field: String = "<unknown>"): ItemStack {
if (obj is JsonPrimitive) {

View File

@ -15,7 +15,7 @@ import net.minecraft.world.level.Level
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.block.entity.PlatePressBlockEntity
import ru.dbotthepony.mc.otm.core.get
import ru.dbotthepony.mc.otm.container.get
import ru.dbotthepony.mc.otm.registry.MRecipes
import ru.dbotthepony.mc.otm.core.registryName

View File

@ -8,7 +8,7 @@ import net.minecraft.nbt.ListTag
import net.minecraft.nbt.Tag
import net.minecraft.world.level.saveddata.SavedData
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.core.set
import ru.dbotthepony.mc.otm.container.set
class SavedMapDelegate<V>(val parent: SavedCountingMap<SavedMapDelegate<V>>?, val index: Int, value: V) {
constructor(value: V) : this(null, -1, value)