From 801577fd9eaba0da06f80e32ad5bb5a702081af9 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Mon, 8 Jan 2024 22:20:51 +0700 Subject: [PATCH 01/14] Readd phantom attractor to machines list --- src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt index 8db343d04..0a7fdc5fe 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt @@ -128,6 +128,7 @@ object MItems { machines.addAll(CHEMICAL_GENERATOR.asSupplierArray()) machines.addAll(ENERGY_SERVO.asSupplierArray()) + machines.add(::PHANTOM_ATTRACTOR) machines.add(::PAINTER) machines.addAll(COBBLESTONE_GENERATOR.asSupplierArray().iterator()) machines.addAll(ESSENCE_STORAGE.asSupplierArray().iterator()) From e009ed33a32970a81c312091fc114c01217a4c6e Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Mon, 8 Jan 2024 23:01:49 +0700 Subject: [PATCH 02/14] Make progress bar in exopack inventory be clickable --- .../dbotthepony/mc/otm/client/screen/ExopackInventoryScreen.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExopackInventoryScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExopackInventoryScreen.kt index a51f8b21b..ee8b3b2bf 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExopackInventoryScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/ExopackInventoryScreen.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.client.screen +import mezz.jei.api.constants.RecipeTypes import net.minecraft.client.gui.screens.inventory.InventoryScreen import net.minecraft.world.item.ItemStack import net.minecraft.world.item.Items @@ -187,6 +188,8 @@ class ExopackInventoryScreen(menu: ExopackInventoryMenu) : MatteryScreen Date: Tue, 9 Jan 2024 00:47:37 +0700 Subject: [PATCH 03/14] update blockentity backlog phrasing --- .../dbotthepony/mc/otm/network/GenericNetworkChannel.kt | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/GenericNetworkChannel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/GenericNetworkChannel.kt index 931fad1fb..7cfedece9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/network/GenericNetworkChannel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/GenericNetworkChannel.kt @@ -17,6 +17,8 @@ import ru.dbotthepony.mc.otm.android.feature.ItemEntityDataPacket import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.onceClient +import ru.dbotthepony.mc.otm.core.collect.map +import ru.dbotthepony.mc.otm.core.collect.reduce import ru.dbotthepony.mc.otm.item.QuantumBatteryItem import ru.dbotthepony.mc.otm.matter.MatterManager import java.util.* @@ -69,12 +71,11 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v val blockEntity = level.getBlockEntity(position) if (blockEntity == null) { - LOGGER.warn("Putting BlockEntitySyncPacket received for $position into backlog because there is literally no block entity there! This is CERTAINLY a bug in one of optimizing mods you have or server has installed! This might cause memory leak.") - - backlog.computeIfAbsent(level) { Object2ObjectOpenHashMap() } + val list = backlog.computeIfAbsent(level) { Object2ObjectOpenHashMap() } .computeIfAbsent(position, Object2ObjectFunction { ArrayList() }) - .add(this) + list.add(this) + LOGGER.warn("Putting BlockEntitySyncPacket received for $position into backlog (size: ${list.iterator().map { it.validBytes }.reduce(0, Int::plus) } bytes) because there is literally no block entity there! This might cause memory leak.") return } else if (blockEntity !is MatteryBlockEntity) { LOGGER.warn("Dropping BlockEntitySyncPacket received for $position, because there is $blockEntity which is not MatteryBlockEntity!") From 8ea83dbd40d53080a14a85f34bb86c8c19c92ec5 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 00:52:48 +0700 Subject: [PATCH 04/14] More compact backlog storage --- .../mc/otm/network/GenericNetworkChannel.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/network/GenericNetworkChannel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/network/GenericNetworkChannel.kt index 7cfedece9..a685e0d0e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/network/GenericNetworkChannel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/network/GenericNetworkChannel.kt @@ -74,8 +74,8 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v val list = backlog.computeIfAbsent(level) { Object2ObjectOpenHashMap() } .computeIfAbsent(position, Object2ObjectFunction { ArrayList() }) - list.add(this) - LOGGER.warn("Putting BlockEntitySyncPacket received for $position into backlog (size: ${list.iterator().map { it.validBytes }.reduce(0, Int::plus) } bytes) because there is literally no block entity there! This might cause memory leak.") + list.add(buffer.copyOf(validBytes)) + LOGGER.warn("Putting BlockEntitySyncPacket received for $position into backlog (size: ${list.iterator().map { it.size }.reduce(0, Int::plus)} bytes) because there is literally no block entity there! This might cause memory leak.") return } else if (blockEntity !is MatteryBlockEntity) { LOGGER.warn("Dropping BlockEntitySyncPacket received for $position, because there is $blockEntity which is not MatteryBlockEntity!") @@ -90,7 +90,7 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v LOGGER.info("Unfolding ${packets.size} backlog packets for $position (${level.getBlockState(position)}/$blockEntity)") for (packet in packets) { - blockEntity.synchronizer.read(FastByteArrayInputStream(packet.buffer, 0, packet.validBytes)) + blockEntity.synchronizer.read(FastByteArrayInputStream(packet)) } } @@ -105,7 +105,7 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v } companion object { - private val backlog = WeakHashMap>>() + private val backlog = WeakHashMap>>() fun read(buff: FriendlyByteBuf): BlockEntitySyncPacket { val position = buff.readBlockPos() @@ -122,10 +122,10 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v try { if (packets != null) { - LOGGER.info("Unfolding ${packets.size} backlog packets for ${blockEntity.blockPos} (${blockEntity.level!!.getBlockState(blockEntity.blockPos)}/$blockEntity)") + LOGGER.info("Unfolding ${packets.size} backlog packets (size: ${packets.iterator().map { it.size }.reduce(0, Int::plus)} bytes) for ${blockEntity.blockPos} (${blockEntity.level!!.getBlockState(blockEntity.blockPos)}/$blockEntity)") for (packet in packets) { - blockEntity.synchronizer.read(FastByteArrayInputStream(packet.buffer, 0, packet.validBytes)) + blockEntity.synchronizer.read(FastByteArrayInputStream(packet)) } } } catch(err: Throwable) { From eac3bea94aeb406e731a8310388a87c07801e6ca Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 01:09:09 +0700 Subject: [PATCH 05/14] Relaxed player sets --- .../ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt index ccfea941e..28fa66950 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/MatteryBlockEntity.kt @@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectFunction import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap import it.unimi.dsi.fastutil.objects.ObjectArraySet import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap import net.minecraft.core.BlockPos import net.minecraft.core.Direction @@ -619,8 +620,8 @@ abstract class MatteryBlockEntity(p_155228_: BlockEntityType<*>, p_155229_: Bloc private class ChunkSubscribers(level: ServerLevel, val chunkPos: Long) { val level = WeakReference(level) val blockEntities = WeakHashSet(linked = true, initialCapacity = 0) - val players = ObjectLinkedOpenHashSet(0) - val veto = ObjectLinkedOpenHashSet(0) + val players = ObjectArraySet(0) + val veto = ObjectArraySet(0) val blockEntitiesWithObservers = WeakHashSet(linked = true, initialCapacity = 0) operator fun component1() = blockEntities From 0a1cb62479a946fb56bb09b3cd5b987b615e41b6 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 11:19:54 +0700 Subject: [PATCH 06/14] Add more missing machines to creative menu --- .../kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt | 1 + src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt | 3 +++ 2 files changed, 4 insertions(+) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt index 1924b60c3..3252dd0bc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt @@ -150,6 +150,7 @@ private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) { accept(MItems.TRITANIUM_ORE) accept(MItems.DEEPSLATE_TRITANIUM_ORE) accept(MItems.TRITANIUM_ORE_CLUMP) + accept(MItems.TRITANIUM_RAW_BLOCK) accept(MItems.TRITANIUM_DUST) accept(MItems.TRITANIUM_NUGGET) accept(MItems.TRITANIUM_INGOT) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt index 0a7fdc5fe..fe24d64a2 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MItems.kt @@ -143,6 +143,9 @@ object MItems { machines.addAll(MATTER_BOTTLER.asSupplierArray().iterator()) machines.add(::MATTER_ENTANGLER) machines.addAll(MATTER_RECYCLER.asSupplierArray().iterator()) + machines.addAll(MATTER_RECONSTRUCTOR.asSupplierArray().iterator()) + + machines.add(::GRAVITATION_STABILIZER) machines.add(::STORAGE_BUS) machines.add(::STORAGE_IMPORTER) From b0dc5baa71424f2a5c0e9d5d49960adc058e2929 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 11:53:30 +0700 Subject: [PATCH 07/14] Add fluid container interaction with infinite water source block --- .../block/decorative/InfiniteWaterSourceBlock.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/InfiniteWaterSourceBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/InfiniteWaterSourceBlock.kt index 294a0353a..d9a0b1524 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/InfiniteWaterSourceBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/InfiniteWaterSourceBlock.kt @@ -1,6 +1,9 @@ package ru.dbotthepony.mc.otm.block.decorative import net.minecraft.core.BlockPos +import net.minecraft.world.InteractionHand +import net.minecraft.world.InteractionResult +import net.minecraft.world.entity.player.Player import net.minecraft.world.level.Level import net.minecraft.world.level.block.EntityBlock import net.minecraft.world.level.block.entity.BlockEntity @@ -9,6 +12,8 @@ import net.minecraft.world.level.block.entity.BlockEntityType import net.minecraft.world.level.block.state.BlockState import net.minecraft.world.level.material.MapColor import net.minecraft.world.level.material.PushReaction +import net.minecraft.world.phys.BlockHitResult +import net.minecraftforge.fluids.FluidUtil import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.entity.decorative.InfiniteWaterSourceBlockEntity @@ -17,6 +22,15 @@ class InfiniteWaterSourceBlock : RotatableMatteryBlock(Properties.of().destroyTi return InfiniteWaterSourceBlockEntity(p_153215_, p_153216_) } + @Suppress("OVERRIDE_DEPRECATION") + override fun use(blockState: BlockState, level: Level, blockPos: BlockPos, ply: Player, hand: InteractionHand, blockHitResult: BlockHitResult): InteractionResult { + if (FluidUtil.interactWithFluidHandler(ply, hand, level, blockPos, blockHitResult.direction)) { + return InteractionResult.sidedSuccess(level.isClientSide) + } + + return super.use(blockState, level, blockPos, ply, hand, blockHitResult) + } + override fun getTicker(p_153212_: Level, p_153213_: BlockState, p_153214_: BlockEntityType): BlockEntityTicker? { if (p_153212_.isClientSide) return null From 7e5ea3be8d6a5be38773f83677024e49771e64c8 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 11:56:41 +0700 Subject: [PATCH 08/14] Add missing infinite water source to creative menu --- src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt index 3252dd0bc..3379b32f3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MCreativeTabs.kt @@ -189,6 +189,7 @@ private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) { fluids(MItems.FLUID_CAPSULE) fluids(MItems.FLUID_TANK) + accept(MItems.INFINITE_WATER_SOURCE) base(MItems.CARGO_CRATE_MINECARTS) From a5c1d7fbf87ad8c6841e13766ec3f7cff05da1f6 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 12:01:38 +0700 Subject: [PATCH 09/14] Use networked field directly as backing fluid field --- .../mc/otm/block/decorative/FluidTankBlock.kt | 2 +- .../entity/decorative/FluidTankBlockEntity.kt | 14 ++++++-------- .../capability/fluid/BlockMatteryFluidHandler.kt | 10 +++------- .../client/render/blockentity/FluidTankRenderer.kt | 2 +- 4 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/FluidTankBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/FluidTankBlock.kt index ea0b5a975..edeb9f709 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/FluidTankBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/FluidTankBlock.kt @@ -62,7 +62,7 @@ class FluidTankBlock : RotatableMatteryBlock(DEFAULT_MACHINE_PROPERTIES), Entity val tile = level?.getExistingBlockEntity(pos) ?: lightLevel if (tile is FluidTankBlockEntity) { - val fluid = tile.synchronizedFluid + val fluid = tile.fluid.fluid if (!fluid.isEmpty) { val newLevel = fluid.fluid.fluidType.getLightLevel(fluid) 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 c3e321746..b137b6ce1 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 @@ -27,12 +27,15 @@ import ru.dbotthepony.mc.otm.menu.decorative.FluidTankMenu 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, setter = { value, access, remote -> + val fluid = BlockMatteryFluidHandler(ItemsConfig::FLUID_TANK_CAPACITY, synchronizer.Field(FluidStack.EMPTY, FluidStackValueCodec, setter = { value, access, remote -> access.write(value) level?.lightEngine?.checkBlock(blockPos) - }) + + if (!remote) { + markDirtyFast() + } + })) val fillInput = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer) val drainInput = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer) @@ -73,11 +76,6 @@ class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : Mattery savetables.stateful(::output) } - private fun onChanged(new: FluidStack, old: FluidStack) { - synchronizedFluid = new.copy() - markDirtyFast() - } - private fun drainItem() { val item = drainInput[0] diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/BlockMatteryFluidHandler.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/BlockMatteryFluidHandler.kt index ac675dac6..b93252b1a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/BlockMatteryFluidHandler.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/fluid/BlockMatteryFluidHandler.kt @@ -7,18 +7,14 @@ import net.minecraftforge.common.util.INBTSerializable import net.minecraftforge.fluids.FluidStack import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.tagNotNull +import ru.dbotthepony.mc.otm.network.synchronizer.IMutableField import java.util.function.IntSupplier /** * Fluid handler for blocks */ -class BlockMatteryFluidHandler(val onChanged: (new: FluidStack, old: FluidStack) -> Unit, private val _capacity: IntSupplier) : AbstractMatteryFluidHandler(), INBTSerializable { - override var fluid: FluidStack = FluidStack.EMPTY - set(value) { - val old = field - field = value - onChanged(value, old) - } +open class BlockMatteryFluidHandler(private val _capacity: IntSupplier, field: IMutableField) : AbstractMatteryFluidHandler(), INBTSerializable { + override var fluid by field override val capacity: Int get() = _capacity.asInt diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/FluidTankRenderer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/FluidTankRenderer.kt index 4d9fd6fc4..7791ebc1e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/FluidTankRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/FluidTankRenderer.kt @@ -32,7 +32,7 @@ class FluidTankRenderer(private val context: BlockEntityRendererProvider.Context packedLight: Int, packedOverlay: Int ) { - renderFluidInTank(tile.fluid, tile.synchronizedFluid, poseStack, bufferSource, packedLight, packedOverlay) + renderFluidInTank(tile.fluid, tile.fluid.fluid, poseStack, bufferSource, packedLight, packedOverlay) } object FluidTankItemRenderer : BlockEntityWithoutLevelRenderer(minecraft.blockEntityRenderDispatcher, minecraft.entityModels) { From 0e60e84eb3872ce6d14713dcc068dd2db4d147ac Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 12:22:53 +0700 Subject: [PATCH 10/14] Mod name and JEI on fluid gauge panel --- .../client/screen/widget/FluidGaugePanel.kt | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/FluidGaugePanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/FluidGaugePanel.kt index 670246d22..854e521f7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/FluidGaugePanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/FluidGaugePanel.kt @@ -1,29 +1,40 @@ package ru.dbotthepony.mc.otm.client.screen.widget +import com.mojang.blaze3d.platform.InputConstants import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.vertex.DefaultVertexFormat import com.mojang.blaze3d.vertex.VertexFormat +import mezz.jei.api.forge.ForgeTypes +import mezz.jei.api.recipe.RecipeIngredientRole +import net.minecraft.ChatFormatting import net.minecraft.client.gui.screens.Screen import net.minecraft.client.renderer.GameRenderer import net.minecraft.network.chat.Component import net.minecraft.resources.ResourceLocation import net.minecraft.world.inventory.InventoryMenu import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions +import net.minecraftforge.fml.ModList import org.lwjgl.opengl.GL11 import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.client.CursorType import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.ShiftPressedCond import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.render.sprites.MatterySprite import ru.dbotthepony.mc.otm.client.render.tesselator import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel +import ru.dbotthepony.mc.otm.client.screen.panels.button.AbstractButtonPanel +import ru.dbotthepony.mc.otm.compat.jei.JEIPlugin +import ru.dbotthepony.mc.otm.compat.jei.isJeiLoaded import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.linearInterpolation +import ru.dbotthepony.mc.otm.core.registryName import ru.dbotthepony.mc.otm.core.util.formatFluidLevel import ru.dbotthepony.mc.otm.menu.widget.FluidGaugeWidget +import kotlin.jvm.optionals.getOrNull open class FluidGaugePanel( screen: S, @@ -31,16 +42,22 @@ open class FluidGaugePanel( val widget: FluidGaugeWidget, x: Float = 0f, y: Float = 0f -) : EditablePanel(screen, parent, x, y, width = GAUGE.width, height = GAUGE.height) { +) : AbstractButtonPanel(screen, parent, x, y, width = GAUGE.width, height = GAUGE.height) { init { scissor = true } protected open fun makeTooltip(): MutableList { - return mutableListOf( + val tooltip = mutableListOf( if (widget.fluid.isEmpty) TranslatableComponent("otm.gui.empty") else TextComponent(String.format("%s: %.2f%%", widget.fluid.displayName.string, widget.percentage * 100.0)), formatFluidLevel(if (widget.fluid.isEmpty) 0 else widget.fluid.amount, widget.maxCapacity, formatAsReadable = ShiftPressedCond) ) + + if (widget.fluid.isNotEmpty) { + tooltip.add(TextComponent(ModList.get().getModContainerById(widget.fluid.fluid.registryName!!.namespace).get().modInfo.displayName).withStyle(ChatFormatting.BLUE).withStyle(ChatFormatting.ITALIC)) + } + + return tooltip } override fun innerRenderTooltips(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean { @@ -52,6 +69,29 @@ open class FluidGaugePanel( return false } + private fun openFluidRecipes(button: Int) { + val ingredient = JEIPlugin.RUNTIME.ingredientManager.createTypedIngredient(ForgeTypes.FLUID_STACK, widget.fluid).getOrNull() ?: return + + if (button == InputConstants.MOUSE_BUTTON_RIGHT) { + JEIPlugin.RUNTIME.recipesGui.show(JEIPlugin.RUNTIME.jeiHelpers.focusFactory.createFocus(RecipeIngredientRole.INPUT, ingredient)) + } else { + JEIPlugin.RUNTIME.recipesGui.show(JEIPlugin.RUNTIME.jeiHelpers.focusFactory.createFocus(RecipeIngredientRole.OUTPUT, ingredient)) + } + } + + override val cursorType: CursorType + get() = if (isJeiLoaded && widget.fluid.isNotEmpty) CursorType.HAND else CursorType.ARROW + + override fun test(value: Int): Boolean { + return (value == InputConstants.MOUSE_BUTTON_RIGHT || value == InputConstants.MOUSE_BUTTON_LEFT) && isJeiLoaded && widget.fluid.isNotEmpty + } + + override fun onClick(mouseButton: Int) { + if (isJeiLoaded && widget.fluid.isNotEmpty) { + openFluidRecipes(mouseButton) + } + } + override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { if (widget.percentage > 0.01f && widget.fluid.isNotEmpty) { val data = IClientFluidTypeExtensions.of(widget.fluid.fluid) From 0b464c3a0b8990fa03f58113e469b86997e48039 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 12:24:39 +0700 Subject: [PATCH 11/14] Don't display "show recipes" on progress gauge because mouse cursor already tells that --- .../mc/otm/client/screen/widget/ProgressGaugePanel.kt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/ProgressGaugePanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/ProgressGaugePanel.kt index 8a9267fe6..bd295bbf7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/ProgressGaugePanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/ProgressGaugePanel.kt @@ -54,11 +54,6 @@ open class ProgressGaugePanel( ) } - if (recipeTypeSupplier != null) { - tooltip.add(TextComponent("")) - tooltip.add(TranslatableComponent("jei.tooltip.show.recipes").withStyle(ChatFormatting.GRAY)) - } - return tooltip } From b95a1885e852a1cfca04496ca7ccabc0c29ec5bd Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 13:15:09 +0700 Subject: [PATCH 12/14] Less rigid jei support --- .../otm/client/screen/panels/EditablePanel.kt | 51 ++++++++++++------- .../screen/panels/slot/AbstractSlotPanel.kt | 10 ++-- .../mc/otm/compat/jei/JEIPlugin.kt | 26 +++------- .../compat/jei/Panel2ClickableIngredient.kt | 31 +++++++++++ 4 files changed, 79 insertions(+), 39 deletions(-) create mode 100644 src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/Panel2ClickableIngredient.kt diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt index f0064faec..0ae78b18e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/EditablePanel.kt @@ -14,7 +14,6 @@ import net.minecraft.client.gui.screens.Screen import net.minecraft.client.renderer.Rect2i import net.minecraft.network.chat.Component import net.minecraft.world.inventory.Slot -import net.minecraft.world.item.ItemStack import org.apache.logging.log4j.LogManager import ru.dbotthepony.mc.otm.SystemTime import ru.dbotthepony.mc.otm.client.CursorType @@ -29,6 +28,7 @@ import ru.dbotthepony.mc.otm.client.screen.panels.input.QueryUserPanel import ru.dbotthepony.mc.otm.core.collect.concatIterators import ru.dbotthepony.mc.otm.core.collect.flatMap import java.util.* +import java.util.function.Predicate import kotlin.collections.ArrayList import kotlin.math.roundToInt @@ -56,10 +56,6 @@ interface ISlotPanel { val slot: S } -interface IItemStackPanel { - val itemStack: ItemStack -} - data class Rect2f(val x: Float, val y: Float, val width: Float, val height: Float) { fun toIntRect(): Rect2i { return Rect2i(x.roundToInt(), y.roundToInt(), width.roundToInt(), height.roundToInt()) @@ -1016,9 +1012,30 @@ open class EditablePanel @JvmOverloads constructor( return false to null } - fun findItemStack(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean = false): Pair?, ItemStack> { + data class PanelOfTypeResult(val panel: T?, val interrupt: Boolean) { + constructor(panel: T) : this(panel, true) + + companion object { + private val notFound0 = PanelOfTypeResult(null, false) + private val notFound1 = PanelOfTypeResult(null, true) + + fun notFoundInterrupt(): PanelOfTypeResult { + return notFound1 as PanelOfTypeResult + } + + fun notFoundContinue(): PanelOfTypeResult { + return notFound0 as PanelOfTypeResult + } + } + } + + inline fun panelOfTypeUnderCursor(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean = false): T? { + return panelOfTypeUnderCursor(mouseX, mouseY, ignoreMouseInputLock) { it is T }.panel + } + + fun panelOfTypeUnderCursor(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean, tester: Predicate>): PanelOfTypeResult { if (!isVisible()) { - return null to ItemStack.EMPTY + return PanelOfTypeResult.notFoundContinue() } if (!acceptMouseInput && !ignoreMouseInputLock) { @@ -1026,20 +1043,20 @@ open class EditablePanel @JvmOverloads constructor( mouseX <= absoluteX + width && mouseY >= absoluteY && mouseY <= absoluteY + height) { - return this to ItemStack.EMPTY + return PanelOfTypeResult.notFoundInterrupt() } else { - return null to ItemStack.EMPTY + return PanelOfTypeResult.notFoundContinue() } } - if (grabMouseInput && this is IItemStackPanel) { - return this to this.itemStack + if (grabMouseInput && tester.test(this)) { + return PanelOfTypeResult(this as T) } for (child in visibleChildrenInternal) { - val status = child.findItemStack(mouseX, mouseY, ignoreMouseInputLock) + val status = child.panelOfTypeUnderCursor(mouseX, mouseY, ignoreMouseInputLock, tester) - if (status.first != null) { + if (status.interrupt) { return status } } @@ -1050,14 +1067,14 @@ open class EditablePanel @JvmOverloads constructor( mouseY >= absoluteY && mouseY <= absoluteY + height ) { - if (this is IItemStackPanel) { - return this to this.itemStack + if (tester.test(this)) { + return PanelOfTypeResult(this as T) } - return this to ItemStack.EMPTY + return PanelOfTypeResult.notFoundInterrupt() } - return null to ItemStack.EMPTY + return PanelOfTypeResult.notFoundContinue() } fun renderTooltips(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt index 1ce1d3d89..dec8c84ee 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt @@ -6,24 +6,26 @@ import net.minecraft.client.renderer.GameRenderer import net.minecraft.network.chat.Component import net.minecraft.world.item.ItemStack import net.minecraftforge.client.extensions.common.IClientItemExtensions +import ru.dbotthepony.mc.otm.client.render.IGUIRenderable import ru.dbotthepony.mc.otm.client.render.MGUIGraphics -import ru.dbotthepony.mc.otm.client.render.* +import ru.dbotthepony.mc.otm.client.render.WidgetLocation import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel -import ru.dbotthepony.mc.otm.client.screen.panels.IItemStackPanel import ru.dbotthepony.mc.otm.core.math.RGBAColor -abstract class AbstractSlotPanel> @JvmOverloads constructor( +abstract class AbstractSlotPanel>( screen: S, parent: EditablePanel<*>?, x: Float = 0f, y: Float = 0f, width: Float = SIZE, height: Float = SIZE, -) : EditablePanel(screen, parent, x, y, width, height), IItemStackPanel { +) : EditablePanel(screen, parent, x, y, width, height) { open var slotBackground: IGUIRenderable? = null open var slotBackgroundEmpty: IGUIRenderable? = null + abstract val itemStack: ItemStack + protected open fun renderSlotBackground(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { SLOT_BACKGROUND.render(graphics, width = width, height = height) slotBackground?.render(graphics, 0f, 0f, width, height) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/JEIPlugin.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/JEIPlugin.kt index d58aef0cb..2d9df4c3f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/JEIPlugin.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/JEIPlugin.kt @@ -4,6 +4,7 @@ import mezz.jei.api.IModPlugin import mezz.jei.api.JeiPlugin import mezz.jei.api.constants.RecipeTypes import mezz.jei.api.constants.VanillaTypes +import mezz.jei.api.forge.ForgeTypes import mezz.jei.api.gui.handlers.IGuiContainerHandler import mezz.jei.api.helpers.IJeiHelpers import mezz.jei.api.ingredients.ITypedIngredient @@ -17,14 +18,17 @@ import mezz.jei.api.runtime.IJeiRuntime import net.minecraft.client.renderer.Rect2i import net.minecraft.resources.ResourceLocation import net.minecraft.world.item.ItemStack +import net.minecraftforge.fluids.FluidStack import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.screen.MatteryScreen +import ru.dbotthepony.mc.otm.client.screen.panels.slot.AbstractSlotPanel +import ru.dbotthepony.mc.otm.client.screen.widget.FluidGaugePanel import ru.dbotthepony.mc.otm.core.collect.filter import ru.dbotthepony.mc.otm.core.collect.filterIsInstance -import ru.dbotthepony.mc.otm.core.collect.filterNotNull import ru.dbotthepony.mc.otm.core.collect.map import ru.dbotthepony.mc.otm.core.collect.toList +import ru.dbotthepony.mc.otm.core.filterNotNull import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu import ru.dbotthepony.mc.otm.menu.matter.MatterEntanglerMenu import ru.dbotthepony.mc.otm.menu.tech.PlatePressMenu @@ -133,23 +137,9 @@ class JEIPlugin : IModPlugin { mouseX: Double, mouseY: Double ): Optional> { - return containerScreen.panelsView - .stream() - .map { it.findItemStack(mouseX.toFloat(), mouseY.toFloat(), ignoreMouseInputLock = true) } - .filter { it.first != null } - .findAny() - .flatMap { a -> helpers.ingredientManager.createTypedIngredient(VanillaTypes.ITEM_STACK, a.second).map { a.first to it } } - .map { - object : IClickableIngredient { - override fun getTypedIngredient(): ITypedIngredient { - return it.second - } - - override fun getArea(): Rect2i { - return it.first!!.calculateAbsoluteRectangle().toIntRect() - } - } - } + return Panel2ClickableIngredient.find(mouseX, mouseY, VanillaTypes.ITEM_STACK, containerScreen.panelsView, AbstractSlotPanel<*>::itemStack).or { + Panel2ClickableIngredient.find(mouseX, mouseY, ForgeTypes.FLUID_STACK, containerScreen.panelsView) { it: FluidGaugePanel<*> -> it.widget.fluid } + } } }) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/Panel2ClickableIngredient.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/Panel2ClickableIngredient.kt new file mode 100644 index 000000000..f61e9e81d --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/Panel2ClickableIngredient.kt @@ -0,0 +1,31 @@ +package ru.dbotthepony.mc.otm.compat.jei + +import mezz.jei.api.ingredients.IIngredientType +import mezz.jei.api.ingredients.ITypedIngredient +import mezz.jei.api.runtime.IClickableIngredient +import net.minecraft.client.renderer.Rect2i +import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel +import ru.dbotthepony.mc.otm.core.filterNotNull +import java.util.* + +class Panel2ClickableIngredient

, T>(val panel: P, val ingredient: ITypedIngredient) : IClickableIngredient { + override fun getTypedIngredient(): ITypedIngredient { + return ingredient + } + + override fun getArea(): Rect2i { + return panel.calculateAbsoluteRectangle().toIntRect() + } + + companion object { + inline fun , T : Any> find(mouseX: Double, mouseY: Double, type: IIngredientType, source: Collection>, noinline provider: (P) -> T): Optional> { + return source + .stream() + .map { it.panelOfTypeUnderCursor

(mouseX.toFloat(), mouseY.toFloat(), ignoreMouseInputLock = true) } + .filterNotNull() + .findAny() + .flatMap { a -> JEIPlugin.helpers.ingredientManager.createTypedIngredient(type, provider(a)).map { a to it } } + .map { Panel2ClickableIngredient(it.first!!, it.second) } + } + } +} From 1c9ea6f8bd7652148f24c1b36aad2877ed072d8c Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 13:15:41 +0700 Subject: [PATCH 13/14] Revert fluid gauge panel clicking for jei recipes --- .../client/screen/widget/FluidGaugePanel.kt | 35 ++----------------- 1 file changed, 2 insertions(+), 33 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/FluidGaugePanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/FluidGaugePanel.kt index 854e521f7..cccd7e3ac 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/FluidGaugePanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/widget/FluidGaugePanel.kt @@ -1,11 +1,8 @@ package ru.dbotthepony.mc.otm.client.screen.widget -import com.mojang.blaze3d.platform.InputConstants import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.vertex.DefaultVertexFormat import com.mojang.blaze3d.vertex.VertexFormat -import mezz.jei.api.forge.ForgeTypes -import mezz.jei.api.recipe.RecipeIngredientRole import net.minecraft.ChatFormatting import net.minecraft.client.gui.screens.Screen import net.minecraft.client.renderer.GameRenderer @@ -16,16 +13,12 @@ import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions import net.minecraftforge.fml.ModList import org.lwjgl.opengl.GL11 import ru.dbotthepony.mc.otm.OverdriveThatMatters -import ru.dbotthepony.mc.otm.client.CursorType -import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.ShiftPressedCond import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.client.render.MGUIGraphics import ru.dbotthepony.mc.otm.client.render.sprites.MatterySprite import ru.dbotthepony.mc.otm.client.render.tesselator import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel -import ru.dbotthepony.mc.otm.client.screen.panels.button.AbstractButtonPanel -import ru.dbotthepony.mc.otm.compat.jei.JEIPlugin -import ru.dbotthepony.mc.otm.compat.jei.isJeiLoaded import ru.dbotthepony.mc.otm.core.TextComponent import ru.dbotthepony.mc.otm.core.TranslatableComponent import ru.dbotthepony.mc.otm.core.isNotEmpty @@ -34,7 +27,6 @@ import ru.dbotthepony.mc.otm.core.math.linearInterpolation import ru.dbotthepony.mc.otm.core.registryName import ru.dbotthepony.mc.otm.core.util.formatFluidLevel import ru.dbotthepony.mc.otm.menu.widget.FluidGaugeWidget -import kotlin.jvm.optionals.getOrNull open class FluidGaugePanel( screen: S, @@ -42,7 +34,7 @@ open class FluidGaugePanel( val widget: FluidGaugeWidget, x: Float = 0f, y: Float = 0f -) : AbstractButtonPanel(screen, parent, x, y, width = GAUGE.width, height = GAUGE.height) { +) : EditablePanel(screen, parent, x, y, width = GAUGE.width, height = GAUGE.height) { init { scissor = true } @@ -69,29 +61,6 @@ open class FluidGaugePanel( return false } - private fun openFluidRecipes(button: Int) { - val ingredient = JEIPlugin.RUNTIME.ingredientManager.createTypedIngredient(ForgeTypes.FLUID_STACK, widget.fluid).getOrNull() ?: return - - if (button == InputConstants.MOUSE_BUTTON_RIGHT) { - JEIPlugin.RUNTIME.recipesGui.show(JEIPlugin.RUNTIME.jeiHelpers.focusFactory.createFocus(RecipeIngredientRole.INPUT, ingredient)) - } else { - JEIPlugin.RUNTIME.recipesGui.show(JEIPlugin.RUNTIME.jeiHelpers.focusFactory.createFocus(RecipeIngredientRole.OUTPUT, ingredient)) - } - } - - override val cursorType: CursorType - get() = if (isJeiLoaded && widget.fluid.isNotEmpty) CursorType.HAND else CursorType.ARROW - - override fun test(value: Int): Boolean { - return (value == InputConstants.MOUSE_BUTTON_RIGHT || value == InputConstants.MOUSE_BUTTON_LEFT) && isJeiLoaded && widget.fluid.isNotEmpty - } - - override fun onClick(mouseButton: Int) { - if (isJeiLoaded && widget.fluid.isNotEmpty) { - openFluidRecipes(mouseButton) - } - } - override fun innerRender(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { if (widget.percentage > 0.01f && widget.fluid.isNotEmpty) { val data = IClientFluidTypeExtensions.of(widget.fluid.fluid) From ddaa0dafe57f1682786f5c40c9070170b6234552 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Tue, 9 Jan 2024 13:41:43 +0700 Subject: [PATCH 14/14] 1984 --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 50a8b01e7..1628e4915 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,6 @@ Minecraft mod with science fiction style, about matter, and energy, combined. ### Mods with special compatibility code * [JEI](https://www.curseforge.com/minecraft/mc-mods/jei) -* [Mekanism](https://www.curseforge.com/minecraft/mc-mods/Mekanism) * [Curios](https://www.curseforge.com/minecraft/mc-mods/curios) * [Cosmetic Armor Reworked](https://www.curseforge.com/minecraft/mc-mods/cosmetic-armor-reworked)