Compare commits

...

7 Commits

9 changed files with 64 additions and 39 deletions

View File

@ -92,7 +92,7 @@ class MatterEntanglerBlockEntity(blockPos: BlockPos, blockState: BlockState) : M
}
private inner class InputSlot(container: SlottedContainer, slot: Int) : FilteredContainerSlot(container, slot) {
val insertCache = SimpleCache<ItemStackKey, Boolean>(1024L, Duration.ofMinutes(1))
val insertCache = SimpleCache<ItemStackKey, Boolean>(Duration.ofMinutes(1))
override fun canAutomationPlaceItem(itemStack: ItemStack): Boolean {
if (!super.canAutomationPlaceItem(itemStack))

View File

@ -202,7 +202,7 @@ sealed class AbstractPoweredFurnaceBlockEntity<P : AbstractCookingRecipe, S : Ma
companion object {
// shared by all furnace instances, so cache should be large enough
private val acceptableItems = SimpleCache<ItemStackKey, Boolean>(16384L, Duration.ofMinutes(1))
private val acceptableItems = SimpleCache<ItemStackKey, Boolean>(Duration.ofMinutes(1))
}
}

View File

@ -127,6 +127,6 @@ class PlatePressBlockEntity(
}
companion object {
private val cache = SimpleCache<ItemStackKey, Boolean>(16384L, Duration.ofMinutes(1L))
private val cache = SimpleCache<ItemStackKey, Boolean>(Duration.ofMinutes(1L))
}
}

View File

@ -1,24 +1,25 @@
package ru.dbotthepony.mc.otm.container.slotted
import net.minecraft.world.item.ItemStack
import ru.dbotthepony.mc.otm.container.IContainerSlot
fun interface AutomationPlaceItem<in S : ContainerSlot> {
fun interface AutomationPlaceItem<in S : IContainerSlot> {
fun canAutomationPlaceItem(self: S, itemStack: ItemStack): Boolean
}
fun interface AutomationTakeItem<in S : ContainerSlot> {
fun interface AutomationTakeItem<in S : IContainerSlot> {
fun canAutomationTakeItem(self: S, desired: Int): Boolean
}
fun interface AutomationModifyPlaceCount<in S : ContainerSlot> {
fun interface AutomationModifyPlaceCount<in S : IContainerSlot> {
fun modifyAutomationPlaceCount(self: S, itemStack: ItemStack): Int
}
fun interface AutomationModifyExtractionCount<in S : ContainerSlot> {
fun interface AutomationModifyExtractionCount<in S : IContainerSlot> {
fun modifyAutomationExtractionCount(self: S, desired: Int): Int
}
interface AutomationFilter<in S : ContainerSlot> : AutomationPlaceItem<S>, AutomationTakeItem<S>, AutomationModifyPlaceCount<S>, AutomationModifyExtractionCount<S> {
interface AutomationFilter<in S : IContainerSlot> : AutomationPlaceItem<S>, AutomationTakeItem<S>, AutomationModifyPlaceCount<S>, AutomationModifyExtractionCount<S> {
override fun modifyAutomationPlaceCount(self: S, itemStack: ItemStack): Int {
return itemStack.count
}

View File

@ -4,118 +4,119 @@ import net.minecraft.world.item.ItemStack
import net.neoforged.neoforge.capabilities.Capabilities
import ru.dbotthepony.mc.otm.capability.MatteryCapability
import ru.dbotthepony.mc.otm.capability.fluid.stream
import ru.dbotthepony.mc.otm.container.IContainerSlot
import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.math.Decimal
enum class AutomationFilters : AutomationFilter<ContainerSlot> {
enum class AutomationFilters : AutomationFilter<IContainerSlot> {
ONLY_OUT {
override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean {
return true
override fun canAutomationPlaceItem(self: IContainerSlot, itemStack: ItemStack): Boolean {
return false
}
override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean {
return false
override fun canAutomationTakeItem(self: IContainerSlot, desired: Int): Boolean {
return true
}
},
ONLY_IN {
override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean {
return false
override fun canAutomationPlaceItem(self: IContainerSlot, itemStack: ItemStack): Boolean {
return true
}
override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean {
return true
override fun canAutomationTakeItem(self: IContainerSlot, desired: Int): Boolean {
return false
}
},
ALLOW {
override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean {
override fun canAutomationPlaceItem(self: IContainerSlot, itemStack: ItemStack): Boolean {
return true
}
override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean {
override fun canAutomationTakeItem(self: IContainerSlot, desired: Int): Boolean {
return true
}
},
DENY {
override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean {
override fun canAutomationPlaceItem(self: IContainerSlot, itemStack: ItemStack): Boolean {
return false
}
override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean {
override fun canAutomationTakeItem(self: IContainerSlot, desired: Int): Boolean {
return false
}
},
FLUID_CONTAINERS {
override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean {
override fun canAutomationPlaceItem(self: IContainerSlot, itemStack: ItemStack): Boolean {
return itemStack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.tanks > 0 } ?: false
}
override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean {
override fun canAutomationTakeItem(self: IContainerSlot, desired: Int): Boolean {
return true
}
},
DRAINABLE_FLUID_CONTAINERS {
override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean {
override fun canAutomationPlaceItem(self: IContainerSlot, itemStack: ItemStack): Boolean {
return itemStack.getCapability(Capabilities.FluidHandler.ITEM)?.let { it.stream().anyMatch { it.isNotEmpty } } ?: false
}
override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean {
override fun canAutomationTakeItem(self: IContainerSlot, desired: Int): Boolean {
return !canAutomationPlaceItem(self, self.item)
}
},
DISCHARGABLE {
override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean {
override fun canAutomationPlaceItem(self: IContainerSlot, itemStack: ItemStack): Boolean {
return itemStack.getCapability(Capabilities.EnergyStorage.ITEM)?.let { it.canExtract() && it.extractEnergy(Int.MAX_VALUE, true) > 0 } ?: false
}
override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean {
override fun canAutomationTakeItem(self: IContainerSlot, desired: Int): Boolean {
return self.item.getCapability(Capabilities.EnergyStorage.ITEM)?.let { !it.canExtract() || it.extractEnergy(Int.MAX_VALUE, true) <= 0 } ?: true
}
},
CHARGEABLE {
override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean {
override fun canAutomationPlaceItem(self: IContainerSlot, itemStack: ItemStack): Boolean {
return itemStack.getCapability(Capabilities.EnergyStorage.ITEM)?.let { it.canReceive() && it.receiveEnergy(Int.MAX_VALUE, true) > 0 } ?: false
}
override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean {
override fun canAutomationTakeItem(self: IContainerSlot, desired: Int): Boolean {
return self.item.getCapability(Capabilities.EnergyStorage.ITEM)?.let { !it.canReceive() || it.receiveEnergy(Int.MAX_VALUE, true) <= 0 } ?: true
}
},
CHEMICAL_FUEL {
override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean {
override fun canAutomationPlaceItem(self: IContainerSlot, itemStack: ItemStack): Boolean {
return itemStack.getBurnTime(null) > 0
}
override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean {
override fun canAutomationTakeItem(self: IContainerSlot, desired: Int): Boolean {
return self.item.getBurnTime(null) <= 0
}
},
IS_PATTERN {
override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean {
override fun canAutomationPlaceItem(self: IContainerSlot, itemStack: ItemStack): Boolean {
return itemStack.getCapability(MatteryCapability.PATTERN_ITEM) != null
}
override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean {
override fun canAutomationTakeItem(self: IContainerSlot, desired: Int): Boolean {
return true
}
},
MATTER_PROVIDERS {
override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean {
override fun canAutomationPlaceItem(self: IContainerSlot, itemStack: ItemStack): Boolean {
return itemStack.getCapability(MatteryCapability.MATTER_ITEM)
?.let { it.matterFlow.output && it.extractMatterChecked(Decimal.POSITIVE_INFINITY, true) > Decimal.ZERO }
?: false
}
override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean {
override fun canAutomationTakeItem(self: IContainerSlot, desired: Int): Boolean {
return self.item.getCapability(MatteryCapability.MATTER_ITEM)
?.let { !it.matterFlow.output || it.extractMatterChecked(Decimal.POSITIVE_INFINITY, true) <= Decimal.ZERO }
?: true
@ -123,13 +124,13 @@ enum class AutomationFilters : AutomationFilter<ContainerSlot> {
},
MATTER_CONSUMERS {
override fun canAutomationPlaceItem(self: ContainerSlot, itemStack: ItemStack): Boolean {
override fun canAutomationPlaceItem(self: IContainerSlot, itemStack: ItemStack): Boolean {
return itemStack.getCapability(MatteryCapability.MATTER_ITEM)
?.let { it.matterFlow.input && it.receiveMatterChecked(Decimal.POSITIVE_INFINITY, true) > Decimal.ZERO }
?: false
}
override fun canAutomationTakeItem(self: ContainerSlot, desired: Int): Boolean {
override fun canAutomationTakeItem(self: IContainerSlot, desired: Int): Boolean {
return self.item.getCapability(MatteryCapability.MATTER_ITEM)
?.let { !it.matterFlow.input || it.receiveMatterChecked(Decimal.POSITIVE_INFINITY, true) <= Decimal.ZERO }
?: true

View File

@ -133,6 +133,13 @@ open class ContainerSlot(
override val maxStackSize: Int
get() = this@Simple.maxStackSize
override fun maxStackSize(item: ItemStack): Int {
if (maxStackSize == Int.MAX_VALUE)
return Int.MAX_VALUE
return super.maxStackSize(item)
}
override fun notifyChanged(old: ItemStack) {
super.notifyChanged(old)
listener(item, old)
@ -160,6 +167,7 @@ open class ContainerSlot(
}
}
companion object {
private val LOGGER = LogManager.getLogger()
}

View File

@ -44,7 +44,7 @@ open class FilteredContainerSlot(
filter = ItemFilter.EMPTY
if ("filter" in nbt) {
ItemFilter.CODEC.decode(provider.createSerializationContext(NbtOps.INSTANCE), nbt)
ItemFilter.CODEC.decode(provider.createSerializationContext(NbtOps.INSTANCE), nbt["filter"])
.ifError { LOGGER.error("Unable to deserialize item filter: ${it.message()}") }
.resultOrPartial().map { it.first }.ifPresent { filter = it }
}
@ -68,6 +68,13 @@ open class FilteredContainerSlot(
override val maxStackSize: Int
get() = this@Simple.maxStackSize
override fun maxStackSize(item: ItemStack): Int {
if (maxStackSize == Int.MAX_VALUE)
return Int.MAX_VALUE
return super.maxStackSize(item)
}
override fun notifyChanged(old: ItemStack) {
super.notifyChanged(old)
listener(item, old)

View File

@ -610,3 +610,7 @@ fun <K : Any, V> SimpleCache(size: Long, freshness: Duration): Cache<K, V> {
.expireAfterWrite(freshness)
.build()
}
fun <K : Any, V> SimpleCache(freshness: Duration): Cache<K, V> {
return SimpleCache(16384L, freshness)
}

View File

@ -89,8 +89,12 @@ open class MatterEntanglerRecipe(
return ingredients.ingredients()
}
private val _isIncomplete by lazy(LazyThreadSafetyMode.PUBLICATION) {
result.isEmpty || ingredients.isIncomplete
}
override fun isIncomplete(): Boolean {
return result.isEmpty || ingredients.isIncomplete
return _isIncomplete
}
override fun isSpecial(): Boolean {