This commit is contained in:
DBotThePony 2024-01-09 13:44:41 +07:00
commit 5645d5f56f
Signed by: DBot
GPG Key ID: DCC23B5715498507
17 changed files with 136 additions and 74 deletions

View File

@ -17,7 +17,6 @@ Minecraft mod with science fiction style, about matter, and energy, combined.
### Mods with special compatibility code ### Mods with special compatibility code
* [JEI](https://www.curseforge.com/minecraft/mc-mods/jei) * [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) * [Curios](https://www.curseforge.com/minecraft/mc-mods/curios)
* [Cosmetic Armor Reworked](https://www.curseforge.com/minecraft/mc-mods/cosmetic-armor-reworked) * [Cosmetic Armor Reworked](https://www.curseforge.com/minecraft/mc-mods/cosmetic-armor-reworked)

View File

@ -62,7 +62,7 @@ class FluidTankBlock : RotatableMatteryBlock(DEFAULT_MACHINE_PROPERTIES), Entity
val tile = level?.getExistingBlockEntity(pos) ?: lightLevel val tile = level?.getExistingBlockEntity(pos) ?: lightLevel
if (tile is FluidTankBlockEntity) { if (tile is FluidTankBlockEntity) {
val fluid = tile.synchronizedFluid val fluid = tile.fluid.fluid
if (!fluid.isEmpty) { if (!fluid.isEmpty) {
val newLevel = fluid.fluid.fluidType.getLightLevel(fluid) val newLevel = fluid.fluid.fluidType.getLightLevel(fluid)

View File

@ -1,6 +1,9 @@
package ru.dbotthepony.mc.otm.block.decorative package ru.dbotthepony.mc.otm.block.decorative
import net.minecraft.core.BlockPos 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.Level
import net.minecraft.world.level.block.EntityBlock import net.minecraft.world.level.block.EntityBlock
import net.minecraft.world.level.block.entity.BlockEntity import net.minecraft.world.level.block.entity.BlockEntity
@ -10,6 +13,8 @@ import net.minecraft.world.level.block.state.BlockState
import net.minecraft.world.level.material.Material import net.minecraft.world.level.material.Material
import net.minecraft.world.level.material.MaterialColor import net.minecraft.world.level.material.MaterialColor
import net.minecraft.world.level.material.PushReaction 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.RotatableMatteryBlock
import ru.dbotthepony.mc.otm.block.entity.decorative.InfiniteWaterSourceBlockEntity import ru.dbotthepony.mc.otm.block.entity.decorative.InfiniteWaterSourceBlockEntity
@ -18,6 +23,15 @@ class InfiniteWaterSourceBlock : RotatableMatteryBlock(Properties.of(Material.ME
return InfiniteWaterSourceBlockEntity(p_153215_, p_153216_) 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 getPistonPushReaction(p_60584_: BlockState): PushReaction { override fun getPistonPushReaction(p_60584_: BlockState): PushReaction {
return PushReaction.NORMAL return PushReaction.NORMAL
} }

View File

@ -6,6 +6,7 @@ import it.unimi.dsi.fastutil.longs.Long2ObjectFunction
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
import it.unimi.dsi.fastutil.objects.ObjectArraySet import it.unimi.dsi.fastutil.objects.ObjectArraySet
import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet import it.unimi.dsi.fastutil.objects.ObjectLinkedOpenHashSet
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.core.Direction 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) { private class ChunkSubscribers(level: ServerLevel, val chunkPos: Long) {
val level = WeakReference(level) val level = WeakReference(level)
val blockEntities = WeakHashSet<MatteryBlockEntity>(linked = true, initialCapacity = 0) val blockEntities = WeakHashSet<MatteryBlockEntity>(linked = true, initialCapacity = 0)
val players = ObjectLinkedOpenHashSet<ServerPlayer>(0) val players = ObjectArraySet<ServerPlayer>(0)
val veto = ObjectLinkedOpenHashSet<ServerPlayer>(0) val veto = ObjectArraySet<ServerPlayer>(0)
val blockEntitiesWithObservers = WeakHashSet<MatteryBlockEntity>(linked = true, initialCapacity = 0) val blockEntitiesWithObservers = WeakHashSet<MatteryBlockEntity>(linked = true, initialCapacity = 0)
operator fun component1() = blockEntities operator fun component1() = blockEntities

View File

@ -27,12 +27,15 @@ import ru.dbotthepony.mc.otm.menu.decorative.FluidTankMenu
import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlockEntities
class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.FLUID_TANK, blockPos, blockState) { class FluidTankBlockEntity(blockPos: BlockPos, blockState: BlockState) : MatteryDeviceBlockEntity(MBlockEntities.FLUID_TANK, blockPos, blockState) {
val fluid = BlockMatteryFluidHandler(::onChanged, ItemsConfig::FLUID_TANK_CAPACITY) val fluid = BlockMatteryFluidHandler(ItemsConfig::FLUID_TANK_CAPACITY, synchronizer.Field(FluidStack.EMPTY, FluidStackValueCodec, setter = { value, access, remote ->
var synchronizedFluid by synchronizer.Field(FluidStack.EMPTY, FluidStackValueCodec, setter = { value, access, remote ->
access.write(value) access.write(value)
level?.lightEngine?.checkBlock(blockPos) level?.lightEngine?.checkBlock(blockPos)
})
if (!remote) {
markDirtyFast()
}
}))
val fillInput = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer) val fillInput = MatteryContainer(::markDirtyFast, 1).also(::addDroppableContainer)
val drainInput = 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) savetables.stateful(::output)
} }
private fun onChanged(new: FluidStack, old: FluidStack) {
synchronizedFluid = new.copy()
markDirtyFast()
}
private fun drainItem() { private fun drainItem() {
val item = drainInput[0] val item = drainInput[0]

View File

@ -7,18 +7,14 @@ import net.minecraftforge.common.util.INBTSerializable
import net.minecraftforge.fluids.FluidStack import net.minecraftforge.fluids.FluidStack
import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.nbt.set
import ru.dbotthepony.mc.otm.core.tagNotNull import ru.dbotthepony.mc.otm.core.tagNotNull
import ru.dbotthepony.mc.otm.network.synchronizer.IMutableField
import java.util.function.IntSupplier import java.util.function.IntSupplier
/** /**
* Fluid handler for blocks * Fluid handler for blocks
*/ */
class BlockMatteryFluidHandler(val onChanged: (new: FluidStack, old: FluidStack) -> Unit, private val _capacity: IntSupplier) : AbstractMatteryFluidHandler(), INBTSerializable<CompoundTag?> { open class BlockMatteryFluidHandler(private val _capacity: IntSupplier, field: IMutableField<FluidStack>) : AbstractMatteryFluidHandler(), INBTSerializable<CompoundTag?> {
override var fluid: FluidStack = FluidStack.EMPTY override var fluid by field
set(value) {
val old = field
field = value
onChanged(value, old)
}
override val capacity: Int override val capacity: Int
get() = _capacity.asInt get() = _capacity.asInt

View File

@ -33,7 +33,7 @@ class FluidTankRenderer(private val context: BlockEntityRendererProvider.Context
packedLight: Int, packedLight: Int,
packedOverlay: 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) { object FluidTankItemRenderer : BlockEntityWithoutLevelRenderer(minecraft.blockEntityRenderDispatcher, minecraft.entityModels) {

View File

@ -1,5 +1,6 @@
package ru.dbotthepony.mc.otm.client.screen package ru.dbotthepony.mc.otm.client.screen
import mezz.jei.api.constants.RecipeTypes
import net.minecraft.client.gui.screens.inventory.InventoryScreen import net.minecraft.client.gui.screens.inventory.InventoryScreen
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraft.world.item.Items import net.minecraft.world.item.Items
@ -187,6 +188,8 @@ class ExopackInventoryScreen(menu: ExopackInventoryMenu) : MatteryScreen<Exopack
it.dock = Dock.LEFT it.dock = Dock.LEFT
it.dockLeft = 9f it.dockLeft = 9f
it.dockResize = DockResizeMode.NONE it.dockResize = DockResizeMode.NONE
it.setRecipeType { listOf(RecipeTypes.SMELTING) }
} }
SlotPanel(this, row, menu.furnaceOutputs[i]).also { SlotPanel(this, row, menu.furnaceOutputs[i]).also {

View File

@ -11,7 +11,6 @@ import net.minecraft.client.gui.screens.Screen
import net.minecraft.client.renderer.Rect2i import net.minecraft.client.renderer.Rect2i
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.world.inventory.Slot import net.minecraft.world.inventory.Slot
import net.minecraft.world.item.ItemStack
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.mc.otm.SystemTime import ru.dbotthepony.mc.otm.SystemTime
import ru.dbotthepony.mc.otm.client.CursorType import ru.dbotthepony.mc.otm.client.CursorType
@ -26,6 +25,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.concatIterators
import ru.dbotthepony.mc.otm.core.collect.flatMap import ru.dbotthepony.mc.otm.core.collect.flatMap
import java.util.* import java.util.*
import java.util.function.Predicate
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -53,10 +53,6 @@ interface ISlotPanel<out S : Slot> {
val slot: S val slot: S
} }
interface IItemStackPanel {
val itemStack: ItemStack
}
data class Rect2f(val x: Float, val y: Float, val width: Float, val height: Float) { data class Rect2f(val x: Float, val y: Float, val width: Float, val height: Float) {
fun toIntRect(): Rect2i { fun toIntRect(): Rect2i {
return Rect2i(x.roundToInt(), y.roundToInt(), width.roundToInt(), height.roundToInt()) return Rect2i(x.roundToInt(), y.roundToInt(), width.roundToInt(), height.roundToInt())
@ -998,9 +994,30 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
return false to null return false to null
} }
fun findItemStack(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean = false): Pair<EditablePanel<*>?, ItemStack> { data class PanelOfTypeResult<T>(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 <T> notFoundInterrupt(): PanelOfTypeResult<T> {
return notFound1 as PanelOfTypeResult<T>
}
fun <T> notFoundContinue(): PanelOfTypeResult<T> {
return notFound0 as PanelOfTypeResult<T>
}
}
}
inline fun <reified T> panelOfTypeUnderCursor(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean = false): T? {
return panelOfTypeUnderCursor<T>(mouseX, mouseY, ignoreMouseInputLock) { it is T }.panel
}
fun <T> panelOfTypeUnderCursor(mouseX: Float, mouseY: Float, ignoreMouseInputLock: Boolean, tester: Predicate<EditablePanel<*>>): PanelOfTypeResult<T> {
if (!isVisible()) { if (!isVisible()) {
return null to ItemStack.EMPTY return PanelOfTypeResult.notFoundContinue()
} }
if (!acceptMouseInput && !ignoreMouseInputLock) { if (!acceptMouseInput && !ignoreMouseInputLock) {
@ -1008,20 +1025,20 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
mouseX <= absoluteX + width && mouseX <= absoluteX + width &&
mouseY >= absoluteY && mouseY >= absoluteY &&
mouseY <= absoluteY + height) { mouseY <= absoluteY + height) {
return this to ItemStack.EMPTY return PanelOfTypeResult.notFoundInterrupt()
} else { } else {
return null to ItemStack.EMPTY return PanelOfTypeResult.notFoundContinue()
} }
} }
if (grabMouseInput && this is IItemStackPanel) { if (grabMouseInput && tester.test(this)) {
return this to this.itemStack return PanelOfTypeResult(this as T)
} }
for (child in visibleChildrenInternal) { for (child in visibleChildrenInternal) {
val status = child.findItemStack(mouseX, mouseY, ignoreMouseInputLock) val status = child.panelOfTypeUnderCursor<T>(mouseX, mouseY, ignoreMouseInputLock, tester)
if (status.first != null) { if (status.interrupt) {
return status return status
} }
} }
@ -1032,14 +1049,14 @@ open class EditablePanel<out S : Screen> @JvmOverloads constructor(
mouseY >= absoluteY && mouseY >= absoluteY &&
mouseY <= absoluteY + height mouseY <= absoluteY + height
) { ) {
if (this is IItemStackPanel) { if (tester.test(this)) {
return this to this.itemStack 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 { fun renderTooltips(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {

View File

@ -5,24 +5,26 @@ import net.minecraft.client.renderer.GameRenderer
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraftforge.client.extensions.common.IClientItemExtensions 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.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.MatteryScreen
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel 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 import ru.dbotthepony.mc.otm.core.math.RGBAColor
abstract class AbstractSlotPanel<out S : MatteryScreen<*>> @JvmOverloads constructor( abstract class AbstractSlotPanel<out S : MatteryScreen<*>>(
screen: S, screen: S,
parent: EditablePanel<*>?, parent: EditablePanel<*>?,
x: Float = 0f, x: Float = 0f,
y: Float = 0f, y: Float = 0f,
width: Float = SIZE, width: Float = SIZE,
height: Float = SIZE, height: Float = SIZE,
) : EditablePanel<S>(screen, parent, x, y, width, height), IItemStackPanel { ) : EditablePanel<S>(screen, parent, x, y, width, height) {
open var slotBackground: IGUIRenderable? = null open var slotBackground: IGUIRenderable? = null
open var slotBackgroundEmpty: IGUIRenderable? = null open var slotBackgroundEmpty: IGUIRenderable? = null
abstract val itemStack: ItemStack
protected open fun renderSlotBackground(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { protected open fun renderSlotBackground(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float) {
SLOT_BACKGROUND.render(graphics, width = width, height = height) SLOT_BACKGROUND.render(graphics, width = width, height = height)
slotBackground?.render(graphics, 0f, 0f, width, height) slotBackground?.render(graphics, 0f, 0f, width, height)

View File

@ -3,17 +3,19 @@ package ru.dbotthepony.mc.otm.client.screen.widget
import com.mojang.blaze3d.systems.RenderSystem import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.DefaultVertexFormat import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.VertexFormat import com.mojang.blaze3d.vertex.VertexFormat
import net.minecraft.ChatFormatting
import net.minecraft.client.gui.screens.Screen import net.minecraft.client.gui.screens.Screen
import net.minecraft.client.renderer.GameRenderer import net.minecraft.client.renderer.GameRenderer
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.inventory.InventoryMenu import net.minecraft.world.inventory.InventoryMenu
import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions import net.minecraftforge.client.extensions.common.IClientFluidTypeExtensions
import net.minecraftforge.fml.ModList
import org.lwjgl.opengl.GL11 import org.lwjgl.opengl.GL11
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.client.render.MGUIGraphics
import ru.dbotthepony.mc.otm.client.ShiftPressedCond import ru.dbotthepony.mc.otm.client.ShiftPressedCond
import ru.dbotthepony.mc.otm.client.minecraft 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.sprites.MatterySprite
import ru.dbotthepony.mc.otm.client.render.tesselator 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.EditablePanel
@ -22,6 +24,7 @@ import ru.dbotthepony.mc.otm.core.TranslatableComponent
import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.RGBAColor
import ru.dbotthepony.mc.otm.core.math.linearInterpolation 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.core.util.formatFluidLevel
import ru.dbotthepony.mc.otm.menu.widget.FluidGaugeWidget import ru.dbotthepony.mc.otm.menu.widget.FluidGaugeWidget
@ -37,10 +40,16 @@ open class FluidGaugePanel<out S : Screen>(
} }
protected open fun makeTooltip(): MutableList<Component> { protected open fun makeTooltip(): MutableList<Component> {
return mutableListOf( val tooltip = mutableListOf<Component>(
if (widget.fluid.isEmpty) TranslatableComponent("otm.gui.empty") else TextComponent(String.format("%s: %.2f%%", widget.fluid.displayName.string, widget.percentage * 100.0)), 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) 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 { override fun innerRenderTooltips(graphics: MGUIGraphics, mouseX: Float, mouseY: Float, partialTick: Float): Boolean {

View File

@ -54,11 +54,6 @@ open class ProgressGaugePanel<out S : Screen>(
) )
} }
if (recipeTypeSupplier != null) {
tooltip.add(TextComponent(""))
tooltip.add(TranslatableComponent("jei.tooltip.show.recipes").withStyle(ChatFormatting.GRAY))
}
return tooltip return tooltip
} }

View File

@ -4,6 +4,7 @@ import mezz.jei.api.IModPlugin
import mezz.jei.api.JeiPlugin import mezz.jei.api.JeiPlugin
import mezz.jei.api.constants.RecipeTypes import mezz.jei.api.constants.RecipeTypes
import mezz.jei.api.constants.VanillaTypes import mezz.jei.api.constants.VanillaTypes
import mezz.jei.api.forge.ForgeTypes
import mezz.jei.api.gui.handlers.IGuiContainerHandler import mezz.jei.api.gui.handlers.IGuiContainerHandler
import mezz.jei.api.helpers.IJeiHelpers import mezz.jei.api.helpers.IJeiHelpers
import mezz.jei.api.ingredients.ITypedIngredient 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.client.renderer.Rect2i
import net.minecraft.resources.ResourceLocation import net.minecraft.resources.ResourceLocation
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.minecraftforge.fluids.FluidStack
import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.screen.MatteryScreen 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.filter
import ru.dbotthepony.mc.otm.core.collect.filterIsInstance 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.map
import ru.dbotthepony.mc.otm.core.collect.toList import ru.dbotthepony.mc.otm.core.collect.toList
import ru.dbotthepony.mc.otm.core.filterNotNull
import ru.dbotthepony.mc.otm.core.value import ru.dbotthepony.mc.otm.core.value
import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu import ru.dbotthepony.mc.otm.menu.decorative.PainterMenu
import ru.dbotthepony.mc.otm.menu.matter.MatterEntanglerMenu import ru.dbotthepony.mc.otm.menu.matter.MatterEntanglerMenu
@ -134,22 +138,8 @@ class JEIPlugin : IModPlugin {
mouseX: Double, mouseX: Double,
mouseY: Double mouseY: Double
): Optional<IClickableIngredient<*>> { ): Optional<IClickableIngredient<*>> {
return containerScreen.panelsView return Panel2ClickableIngredient.find(mouseX, mouseY, VanillaTypes.ITEM_STACK, containerScreen.panelsView, AbstractSlotPanel<*>::itemStack).or {
.stream() Panel2ClickableIngredient.find(mouseX, mouseY, ForgeTypes.FLUID_STACK, containerScreen.panelsView) { it: FluidGaugePanel<*> -> it.widget.fluid }
.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<ItemStack> {
override fun getTypedIngredient(): ITypedIngredient<ItemStack> {
return it.second
}
override fun getArea(): Rect2i {
return it.first!!.calculateAbsoluteRectangle().toIntRect()
}
}
} }
} }
}) })

View File

@ -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<P : EditablePanel<*>, T>(val panel: P, val ingredient: ITypedIngredient<T>) : IClickableIngredient<T> {
override fun getTypedIngredient(): ITypedIngredient<T> {
return ingredient
}
override fun getArea(): Rect2i {
return panel.calculateAbsoluteRectangle().toIntRect()
}
companion object {
inline fun <reified P : EditablePanel<*>, T : Any> find(mouseX: Double, mouseY: Double, type: IIngredientType<T>, source: Collection<EditablePanel<*>>, noinline provider: (P) -> T): Optional<IClickableIngredient<*>> {
return source
.stream()
.map { it.panelOfTypeUnderCursor<P>(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) }
}
}
}

View File

@ -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.block.entity.MatteryBlockEntity
import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.onceClient 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.item.QuantumBatteryItem
import ru.dbotthepony.mc.otm.matter.MatterManager import ru.dbotthepony.mc.otm.matter.MatterManager
import java.util.* import java.util.*
@ -69,12 +71,11 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v
val blockEntity = level.getBlockEntity(position) val blockEntity = level.getBlockEntity(position)
if (blockEntity == null) { 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.") val list = backlog.computeIfAbsent(level) { Object2ObjectOpenHashMap() }
backlog.computeIfAbsent(level) { Object2ObjectOpenHashMap() }
.computeIfAbsent(position, Object2ObjectFunction { ArrayList() }) .computeIfAbsent(position, Object2ObjectFunction { ArrayList() })
.add(this)
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 return
} else if (blockEntity !is MatteryBlockEntity) { } else if (blockEntity !is MatteryBlockEntity) {
LOGGER.warn("Dropping BlockEntitySyncPacket received for $position, because there is $blockEntity which is not MatteryBlockEntity!") LOGGER.warn("Dropping BlockEntitySyncPacket received for $position, because there is $blockEntity which is not MatteryBlockEntity!")
@ -89,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)") LOGGER.info("Unfolding ${packets.size} backlog packets for $position (${level.getBlockState(position)}/$blockEntity)")
for (packet in packets) { for (packet in packets) {
blockEntity.synchronizer.read(FastByteArrayInputStream(packet.buffer, 0, packet.validBytes)) blockEntity.synchronizer.read(FastByteArrayInputStream(packet))
} }
} }
@ -104,7 +105,7 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v
} }
companion object { companion object {
private val backlog = WeakHashMap<Level, Object2ObjectOpenHashMap<BlockPos, ArrayList<BlockEntitySyncPacket>>>() private val backlog = WeakHashMap<Level, Object2ObjectOpenHashMap<BlockPos, ArrayList<ByteArray>>>()
fun read(buff: FriendlyByteBuf): BlockEntitySyncPacket { fun read(buff: FriendlyByteBuf): BlockEntitySyncPacket {
val position = buff.readBlockPos() val position = buff.readBlockPos()
@ -121,10 +122,10 @@ class BlockEntitySyncPacket(val position: BlockPos, val buffer: ByteArray, val v
try { try {
if (packets != null) { 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) { for (packet in packets) {
blockEntity.synchronizer.read(FastByteArrayInputStream(packet.buffer, 0, packet.validBytes)) blockEntity.synchronizer.read(FastByteArrayInputStream(packet))
} }
} }
} catch(err: Throwable) { } catch(err: Throwable) {

View File

@ -147,6 +147,7 @@ private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) {
accept(MItems.TRITANIUM_ORE) accept(MItems.TRITANIUM_ORE)
accept(MItems.DEEPSLATE_TRITANIUM_ORE) accept(MItems.DEEPSLATE_TRITANIUM_ORE)
accept(MItems.TRITANIUM_ORE_CLUMP) accept(MItems.TRITANIUM_ORE_CLUMP)
accept(MItems.TRITANIUM_RAW_BLOCK)
accept(MItems.TRITANIUM_DUST) accept(MItems.TRITANIUM_DUST)
accept(MItems.TRITANIUM_NUGGET) accept(MItems.TRITANIUM_NUGGET)
accept(MItems.TRITANIUM_INGOT) accept(MItems.TRITANIUM_INGOT)
@ -185,6 +186,7 @@ private fun addMainCreativeTabItems(consumer: CreativeModeTab.Output) {
fluids(MItems.FLUID_CAPSULE) fluids(MItems.FLUID_CAPSULE)
fluids(MItems.FLUID_TANK) fluids(MItems.FLUID_TANK)
accept(MItems.INFINITE_WATER_SOURCE)
base(MItems.CARGO_CRATE_MINECARTS) base(MItems.CARGO_CRATE_MINECARTS)

View File

@ -129,6 +129,7 @@ object MItems {
machines.addAll(CHEMICAL_GENERATOR.asSupplierArray()) machines.addAll(CHEMICAL_GENERATOR.asSupplierArray())
machines.addAll(ENERGY_SERVO.asSupplierArray()) machines.addAll(ENERGY_SERVO.asSupplierArray())
machines.add(::PHANTOM_ATTRACTOR)
machines.add(::PAINTER) machines.add(::PAINTER)
machines.addAll(COBBLESTONE_GENERATOR.asSupplierArray().iterator()) machines.addAll(COBBLESTONE_GENERATOR.asSupplierArray().iterator())
machines.addAll(ESSENCE_STORAGE.asSupplierArray().iterator()) machines.addAll(ESSENCE_STORAGE.asSupplierArray().iterator())
@ -143,6 +144,9 @@ object MItems {
machines.addAll(MATTER_BOTTLER.asSupplierArray().iterator()) machines.addAll(MATTER_BOTTLER.asSupplierArray().iterator())
machines.add(::MATTER_ENTANGLER) machines.add(::MATTER_ENTANGLER)
machines.addAll(MATTER_RECYCLER.asSupplierArray().iterator()) machines.addAll(MATTER_RECYCLER.asSupplierArray().iterator())
machines.addAll(MATTER_RECONSTRUCTOR.asSupplierArray().iterator())
machines.add(::GRAVITATION_STABILIZER)
machines.add(::STORAGE_BUS) machines.add(::STORAGE_BUS)
machines.add(::STORAGE_IMPORTER) machines.add(::STORAGE_IMPORTER)