diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/FluidTankBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/FluidTankBlockEntity.kt index 39d62c563..5b6bd1f3f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/FluidTankBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/decorative/FluidTankBlockEntity.kt @@ -29,7 +29,7 @@ import ru.dbotthepony.mc.otm.registry.MBlockEntities class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.FLUID_TANK, blockPos, blockState) { val fluid = BlockMatteryFluidHandler(::onChanged, ItemsConfig::FLUID_TANK_CAPACITY) - var synchronizedFluid by synchronizer.Field(FluidStack.EMPTY!!, FluidStackValueCodec) + var synchronizedFluid by synchronizer.Field(FluidStack.EMPTY, FluidStackValueCodec) private set val fillInput = MatteryContainer(::setChangedLight, 1).also(::addDroppableContainer) @@ -42,25 +42,15 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery fillInput.handler(object : HandlerFilter { override fun canInsert(slot: Int, stack: ItemStack): Boolean { if (fluid.isEmpty) { - stack.getCapability(ForgeCapabilities.FLUID_HANDLER).ifPresentK { - if (it.tanks > 0) return true - } - stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresentK { - if (it.tanks > 0) return true + return it.tanks > 0 } return false } - stack.getCapability(ForgeCapabilities.FLUID_HANDLER).ifPresentK { - if (it.fill(fluid[0], IFluidHandler.FluidAction.SIMULATE) > 0) - return true - } - stack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).ifPresentK { - if (it.fill(fluid[0], IFluidHandler.FluidAction.SIMULATE) > 0) - return true + return it.fill(fluid[0], IFluidHandler.FluidAction.SIMULATE) > 0 } return false @@ -91,8 +81,7 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery val item = drainInput[0] if (item.isNotEmpty) { - val target = if (item.count == 1) item else item.copyWithCount(1) - val cap = target.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: target.getCapability(ForgeCapabilities.FLUID_HANDLER).orNull() + val cap = (if (item.count == 1) item else item.copyWithCount(1)).getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() if (cap == null) { if (output.consumeItem(item, simulate = false)) { @@ -107,9 +96,9 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery val moved0 = moveFluid(source = cap, destination = fluid) if (moved0.isNotEmpty) { - drainInput.setChanged(0) + drainInput[0] = cap.container - if (output.consumeItem(item, simulate = false)) { + if (output.consumeItem(drainInput[0], simulate = false)) { drainInput.setChanged(0) } } @@ -117,21 +106,20 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery val moved0 = moveFluid(source = cap, destination = fluid, actuallyFill = false) if (moved0.isNotEmpty) { - if (output.consumeItem(target, simulate = true)) { - val target1 = item.copyWithCount(1) - val cap1 = target1.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: target1.getCapability(ForgeCapabilities.FLUID_HANDLER).orNull() ?: throw ConcurrentModificationException() + if (output.consumeItem(cap.container, simulate = true)) { + val cap1 = item.copyWithCount(1).getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: throw ConcurrentModificationException() val moved1 = moveFluid(source = cap1, destination = fluid) if (moved1 != moved0 || moved1.amount != moved0.amount) { - LOGGER.error("Error moving fluids in Fluid tank at $blockPos: moved $moved0 during simulation from $target, moved $moved1 from $target1 during execution. This is likely a bug in OTM or other mod!") + LOGGER.error("Error moving fluids in Fluid tank at $blockPos: moved $moved0 during simulation from ${cap.container}, moved $moved1 from ${cap1.container} during execution. This is likely a bug in OTM or other mod!") } else { item.count-- drainInput.setChanged(0) - if (!output.consumeItem(target1, simulate = false)) { - LOGGER.error("Unable to insert $target1 into output slot of Fluid tank at $blockPos, popping item in world instead to avoid item loss! This is likely a bug in OTM or other mod!") - (level as? ServerLevel)?.addFreshEntity(ItemEntity(level!!, blockPos.x.toDouble(), blockPos.y.toDouble(), blockPos.z.toDouble(), target1)) + if (!output.consumeItem(cap1.container, simulate = false)) { + LOGGER.error("Unable to insert ${cap1.container} into output slot of Fluid tank at $blockPos, popping item in world instead to avoid item loss! This is likely a bug in OTM or other mod!") + (level as? ServerLevel)?.addFreshEntity(ItemEntity(level!!, blockPos.x.toDouble(), blockPos.y.toDouble(), blockPos.z.toDouble(), cap1.container)) } } } @@ -145,8 +133,7 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery val item = fillInput[0] if (item.isNotEmpty) { - val target = if (item.count == 1) item else item.copyWithCount(1) - val cap = target.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: target.getCapability(ForgeCapabilities.FLUID_HANDLER).orNull() + val cap = (if (item.count == 1) item else item.copyWithCount(1)).getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() if (cap == null) { if (output.consumeItem(item, simulate = false)) { @@ -161,9 +148,9 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery val moved0 = moveFluid(source = fluid, destination = cap) if (moved0.isNotEmpty) { - fillInput.setChanged(0) + fillInput[0] = cap.container - if (output.consumeItem(item, simulate = false)) { + if (output.consumeItem(fillInput[0], simulate = false)) { fillInput.setChanged(0) } } @@ -171,21 +158,20 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery val moved0 = moveFluid(source = fluid, destination = cap, actuallyDrain = false) if (moved0.isNotEmpty) { - if (output.consumeItem(target, simulate = true)) { - val target1 = item.copyWithCount(1) - val cap1 = target1.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: target1.getCapability(ForgeCapabilities.FLUID_HANDLER).orNull() ?: throw ConcurrentModificationException() + if (output.consumeItem(cap.container, simulate = true)) { + val cap1 = item.copyWithCount(1).getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM).orNull() ?: throw ConcurrentModificationException() val moved1 = moveFluid(source = fluid, destination = cap1) if (moved1 != moved0 || moved1.amount != moved0.amount) { - LOGGER.error("Error moving fluids in Fluid tank at $blockPos: moved $moved0 during simulation from $target, moved $moved1 from $target1 during execution. This is likely a bug in OTM or other mod!") + LOGGER.error("Error moving fluids in Fluid tank at $blockPos: moved $moved0 during simulation from ${cap.container}, moved $moved1 from ${cap1.container} during execution. This is likely a bug in OTM or other mod!") } else { item.count-- fillInput.setChanged(0) - if (!output.consumeItem(target1, simulate = false)) { - LOGGER.error("Unable to insert $target1 into output slot of Fluid tank at $blockPos, popping item in world instead to avoid item loss! This is likely a bug in OTM or other mod!") - (level as? ServerLevel)?.addFreshEntity(ItemEntity(level!!, blockPos.x.toDouble(), blockPos.y.toDouble(), blockPos.z.toDouble(), target1)) + if (!output.consumeItem(cap1.container, simulate = false)) { + LOGGER.error("Unable to insert ${cap1.container} into output slot of Fluid tank at $blockPos, popping item in world instead to avoid item loss! This is likely a bug in OTM or other mod!") + (level as? ServerLevel)?.addFreshEntity(ItemEntity(level!!, blockPos.x.toDouble(), blockPos.y.toDouble(), blockPos.z.toDouble(), cap1.container)) } } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/AbstractMatteryFluidHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/AbstractMatteryFluidHandler.kt index 5cb8ac463..4b55a6bf7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/AbstractMatteryFluidHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/AbstractMatteryFluidHandler.kt @@ -42,7 +42,7 @@ abstract class AbstractMatteryFluidHandler : IFluidHandler { return isFluidValid(stack) } - final override fun fill(resource: FluidStack, action: IFluidHandler.FluidAction): Int { + override fun fill(resource: FluidStack, action: IFluidHandler.FluidAction): Int { if (resource.isEmpty || !isFluidValid(resource) || !direction.input) { return 0 } @@ -63,7 +63,7 @@ abstract class AbstractMatteryFluidHandler : IFluidHandler { } } - final override fun drain(resource: FluidStack, action: IFluidHandler.FluidAction): FluidStack { + override fun drain(resource: FluidStack, action: IFluidHandler.FluidAction): FluidStack { if (resource.isEmpty || !direction.output) { return FluidStack.EMPTY } @@ -77,7 +77,7 @@ abstract class AbstractMatteryFluidHandler : IFluidHandler { } } - final override fun drain(maxDrain: Int, action: IFluidHandler.FluidAction): FluidStack { + override fun drain(maxDrain: Int, action: IFluidHandler.FluidAction): FluidStack { require(maxDrain >= 0) { "Invalid amount to drain: $maxDrain" } if (maxDrain == 0 || !direction.output) return FluidStack.EMPTY diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/ItemMatteryFluidHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/ItemMatteryFluidHandler.kt index 6cddb0c21..21c087662 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/ItemMatteryFluidHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/ItemMatteryFluidHandler.kt @@ -9,6 +9,7 @@ import net.minecraftforge.common.capabilities.ForgeCapabilities import net.minecraftforge.common.capabilities.ICapabilityProvider import net.minecraftforge.common.util.LazyOptional import net.minecraftforge.fluids.FluidStack +import net.minecraftforge.fluids.capability.IFluidHandler import net.minecraftforge.fluids.capability.IFluidHandlerItem import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.tagNotNull @@ -38,4 +39,25 @@ open class ItemMatteryFluidHandler(val itemStack: ItemStack, private val _capaci return LazyOptional.empty() } + + override fun fill(resource: FluidStack, action: IFluidHandler.FluidAction): Int { + if (itemStack.count != 1) + return 0 + + return super.fill(resource, action) + } + + override fun drain(resource: FluidStack, action: IFluidHandler.FluidAction): FluidStack { + if (itemStack.count != 1) + return FluidStack.EMPTY + + return super.drain(resource, action) + } + + override fun drain(maxDrain: Int, action: IFluidHandler.FluidAction): FluidStack { + if (itemStack.count != 1) + return FluidStack.EMPTY + + return super.drain(maxDrain, action) + } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt index 6b44eee1f..757662ebd 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/MatteryContainer.kt @@ -331,6 +331,9 @@ open class MatteryContainer(protected val watcher: Runnable, private val size: I * @return Whenever [stack] was modified */ fun consumeItem(stack: ItemStack, simulate: Boolean, onlyIntoExisting: Boolean = false, popTime: Int? = null): Boolean { + if (stack.isEmpty) + return false + val result = addItem(stack, 0 until size, simulate, onlyIntoExisting = onlyIntoExisting, popTime = popTime) if (result.count != stack.count) { @@ -411,7 +414,7 @@ open class MatteryContainer(protected val watcher: Runnable, private val size: I val old = slots[slot] slots[slot] = stack - trackedSlots[slot] = stack.copy() + trackedSlots[slot] = if (stack.isEmpty) ItemStack.EMPTY else stack.copy() setChanged(slot, stack, old) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/FluidTankMenu.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/FluidTankMenu.kt index 2b746de00..e7e1b4693 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/FluidTankMenu.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/menu/decorative/FluidTankMenu.kt @@ -25,31 +25,26 @@ class FluidTankMenu(containerId: Int, inventory: Inventory, tile: FluidTankBlock val drainInput = object : MatterySlot(tile?.drainInput ?: SimpleContainer(1), 0) { override fun mayPlace(itemStack: ItemStack): Boolean { - return super.mayPlace(itemStack) && itemStack.getCapability(ForgeCapabilities.FLUID_HANDLER) + return super.mayPlace(itemStack) && + itemStack + .getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM) .map { it.isNotEmpty } - .orElse(itemStack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM) - .map { it.isNotEmpty } - .orElse(false)) + .orElse(false) } } val fillInput = object : MatterySlot(tile?.fillInput ?: SimpleContainer(1), 0) { override fun mayPlace(itemStack: ItemStack): Boolean { - return super.mayPlace(itemStack) && itemStack.getCapability(ForgeCapabilities.FLUID_HANDLER) + return super.mayPlace(itemStack) && + (if (itemStack.count <= 1) itemStack else itemStack.copyWithCount(1)) + .getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM) .map { if (fluid.fluid.isEmpty) it.tanks > 0 else it.fill(fluid.fluid, IFluidHandler.FluidAction.SIMULATE) > 0 } - .orElse(itemStack.getCapability(ForgeCapabilities.FLUID_HANDLER_ITEM) - .map { - if (fluid.fluid.isEmpty) - it.tanks > 0 - else - it.fill(fluid.fluid, IFluidHandler.FluidAction.SIMULATE) > 0 - } - .orElse(false)) + .orElse(false) } }