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) { 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 { override fun canAutomationPlaceItem(itemStack: ItemStack): Boolean {
if (!super.canAutomationPlaceItem(itemStack)) if (!super.canAutomationPlaceItem(itemStack))

View File

@ -202,7 +202,7 @@ sealed class AbstractPoweredFurnaceBlockEntity<P : AbstractCookingRecipe, S : Ma
companion object { companion object {
// shared by all furnace instances, so cache should be large enough // 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 { 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 package ru.dbotthepony.mc.otm.container.slotted
import net.minecraft.world.item.ItemStack 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 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 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 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 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 { override fun modifyAutomationPlaceCount(self: S, itemStack: ItemStack): Int {
return itemStack.count return itemStack.count
} }

View File

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

View File

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

View File

@ -44,7 +44,7 @@ open class FilteredContainerSlot(
filter = ItemFilter.EMPTY filter = ItemFilter.EMPTY
if ("filter" in nbt) { 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()}") } .ifError { LOGGER.error("Unable to deserialize item filter: ${it.message()}") }
.resultOrPartial().map { it.first }.ifPresent { filter = it } .resultOrPartial().map { it.first }.ifPresent { filter = it }
} }
@ -68,6 +68,13 @@ open class FilteredContainerSlot(
override val maxStackSize: Int override val maxStackSize: Int
get() = this@Simple.maxStackSize 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) { override fun notifyChanged(old: ItemStack) {
super.notifyChanged(old) super.notifyChanged(old)
listener(item, old) listener(item, old)

View File

@ -610,3 +610,7 @@ fun <K : Any, V> SimpleCache(size: Long, freshness: Duration): Cache<K, V> {
.expireAfterWrite(freshness) .expireAfterWrite(freshness)
.build() .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() return ingredients.ingredients()
} }
private val _isIncomplete by lazy(LazyThreadSafetyMode.PUBLICATION) {
result.isEmpty || ingredients.isIncomplete
}
override fun isIncomplete(): Boolean { override fun isIncomplete(): Boolean {
return result.isEmpty || ingredients.isIncomplete return _isIncomplete
} }
override fun isSpecial(): Boolean { override fun isSpecial(): Boolean {