Storage importer now can receive items directly, fix item filter saving

This commit is contained in:
DBotThePony 2022-05-14 23:24:22 +07:00
parent 69fdba7ea2
commit 4dee77edbe
Signed by: DBot
GPG Key ID: DCC23B5715498507
3 changed files with 97 additions and 15 deletions

View File

@ -66,6 +66,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
val filter = ItemFilter(MAX_FILTERS) { _, _, _ ->
component?.scan()
setChangedLight()
}
override fun setLevel(p_155231_: Level) {
@ -122,7 +123,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
override fun load(nbt: CompoundTag) {
super.load(nbt)
nbt.ifHas("filter", ListTag::class.java, filter::deserializeNBT)
nbt.ifHas("filter", CompoundTag::class.java, filter::deserializeNBT)
}
fun checkSurroundings() {

View File

@ -10,6 +10,7 @@ import net.minecraft.server.level.ServerLevel
import net.minecraft.world.entity.player.Inventory
import net.minecraft.world.entity.player.Player
import net.minecraft.world.inventory.AbstractContainerMenu
import net.minecraft.world.item.ItemStack
import net.minecraft.world.level.Level
import net.minecraft.world.level.block.entity.BlockEntityType
import net.minecraft.world.level.block.state.BlockState
@ -100,12 +101,14 @@ abstract class AbstractStorageImportExport<T>(
}
}
class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : AbstractStorageImportExport<IItemHandler>(MBlockEntities.STORAGE_IMPORTER, blockPos, blockState) {
class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState)
: AbstractStorageImportExport<IItemHandler>(MBlockEntities.STORAGE_IMPORTER, blockPos, blockState),
IItemHandler {
override val defaultDisplayName: Component
get() = MACHINE_NAME
val filter = ItemFilter(MAX_FILTERS) { _, _, _ ->
setChangedLight()
}
override fun createMenu(containerID: Int, inventory: Inventory, ply: Player): AbstractContainerMenu {
@ -129,7 +132,69 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : A
override fun load(nbt: CompoundTag) {
super.load(nbt)
nbt.ifHas("filter", ListTag::class.java, filter::deserializeNBT)
nbt.ifHas("filter", CompoundTag::class.java, filter::deserializeNBT)
}
private var valid = true
private var resolverItemHandler = LazyOptional.of<IItemHandler> { this }
override fun invalidateCaps() {
super.invalidateCaps()
resolverItemHandler.invalidate()
valid = false
}
override fun reviveCaps() {
super.reviveCaps()
resolverItemHandler = LazyOptional.of { this }
valid = true
}
override fun <T> getCapability(cap: Capability<T>, side: Direction?): LazyOptional<T> {
if (valid && cap === CapabilityItemHandler.ITEM_HANDLER_CAPABILITY && side == blockState.getValue(RotatableMatteryBlock.FACING_FULL)) {
return resolverItemHandler.cast()
}
return super.getCapability(cap, side)
}
override fun getSlots(): Int {
return 1
}
override fun getStackInSlot(slot: Int): ItemStack {
return ItemStack.EMPTY
}
override fun insertItem(slot: Int, stack: ItemStack, simulate: Boolean): ItemStack {
if (!filter.match(stack))
return stack
val view = cell.storageGraph?.getVirtualComponent(ITEM_STORAGE) ?: return stack
val maxMove = energy.extractStepInner(ITEM_STORAGE.energyPerOperation, stack.count, true)
if (maxMove == 0)
return stack
val leftover = view.insertStack(ItemStackWrapper(stack).also { it.count = maxMove.toImpreciseFraction() }, simulate)
if (simulate)
return leftover.stack
energy.extractStepInner(ITEM_STORAGE.energyPerOperation, maxMove - leftover.count.toInt(), false)
return leftover.stack
}
override fun extractItem(slot: Int, amount: Int, simulate: Boolean): ItemStack {
return ItemStack.EMPTY
}
override fun getSlotLimit(slot: Int): Int {
return Int.MAX_VALUE
}
override fun isItemValid(slot: Int, stack: ItemStack): Boolean {
return filter.match(stack)
}
fun tick() {
@ -140,7 +205,7 @@ class StorageImporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : A
if (nextTick <= 0 && target.isPresent && enoughEnergy) {
val graph = cell.storageGraph ?: return
val items = graph.getVirtualComponent(OverdriveThatMatters.INSTANCE.ITEM_STORAGE())
val items = graph.getVirtualComponent(ITEM_STORAGE)
val resolved = target.orThrow()
@ -217,6 +282,8 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
}
lastSlot = 0
setChangedLight()
}.also { it.isWhitelist = true }
private var lastSlot = 0
@ -241,7 +308,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
override fun load(nbt: CompoundTag) {
super.load(nbt)
nbt.ifHas("filter", ListTag::class.java, filter::deserializeNBT)
nbt.ifHas("filter", CompoundTag::class.java, filter::deserializeNBT)
}
fun tick() {
@ -263,6 +330,10 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
var hit = false
for (stack in exportStacks) {
if (!resolved.isItemValid(lastSlot, stack.second.item)) {
continue
}
val exportAmountA = items.extractStack(stack.first, stack.second.count.toInt().coerceAtMost(MAX_MOVE_PER_OPERATION).toImpreciseFraction(), true).count.toInt()
if (exportAmountA == 0) {

View File

@ -9,7 +9,9 @@ import net.minecraftforge.common.util.INBTSerializable
import net.minecraftforge.network.NetworkEvent
import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.ifHas
import ru.dbotthepony.mc.otm.menu.MatteryMenu
import ru.dbotthepony.mc.otm.set
import java.util.LinkedList
import java.util.function.Supplier
@ -78,7 +80,7 @@ data class ItemFilterNetworkSlot(val slotID: Int, val networkID: Int, val filter
class ItemFilter(
val size: Int,
private val modified: (slot: Int?, oldValue: ItemStack?, newValue: ItemStack?) -> Unit
) : INBTSerializable<ListTag> {
) : INBTSerializable<CompoundTag> {
private val filter = Array<ItemStack>(size) { ItemStack.EMPTY }
private val linkedFilter = LinkedList<ItemStack>()
@ -139,25 +141,33 @@ class ItemFilter(
return true
}
override fun serializeNBT(): ListTag {
return ListTag().also {
override fun serializeNBT(): CompoundTag {
return CompoundTag().also {
it["items"] = ListTag().also {
for (value in filter) {
it.add(value.serializeNBT())
}
}
it["is_whitelist"] = isWhitelist
}
}
override fun deserializeNBT(nbt: ListTag?) {
override fun deserializeNBT(nbt: CompoundTag?) {
for (i in filter.indices)
filter[i] = ItemStack.EMPTY
if (nbt == null)
return
for ((i, value) in nbt.withIndex()) {
nbt.ifHas("items", ListTag::class.java) {
for ((i, value) in it.withIndex()) {
if (value is CompoundTag) {
filter[i] = ItemStack.of(value)
}
}
}
isWhitelist = nbt.getBoolean("is_whitelist")
}
}