diff --git a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt index 349bbdbf5..8c345bc12 100644 --- a/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt +++ b/src/data/kotlin/ru/dbotthepony/mc/otm/datagen/lang/English.kt @@ -45,6 +45,8 @@ private fun sounds(provider: MatteryLanguageProvider) { private fun misc(provider: MatteryLanguageProvider) { with(provider.english) { + gui("recipe.ticks", "%s Ticks") + gui("exosuit", "Exosuit Inventory") gui("exosuit.probe1", "This little device feels unnatural to touch, it is almost certainly resilient to any possible attempt to break it open.") 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 0ff83d606..900707ffe 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 @@ -3,13 +3,24 @@ package ru.dbotthepony.mc.otm.compat.jei import mezz.jei.api.IModPlugin import mezz.jei.api.JeiPlugin import mezz.jei.api.constants.RecipeTypes +import mezz.jei.api.helpers.IJeiHelpers import mezz.jei.api.registration.IRecipeCatalystRegistration +import mezz.jei.api.registration.IRecipeCategoryRegistration +import mezz.jei.api.registration.IRecipeRegistration import net.minecraft.resources.ResourceLocation import net.minecraft.world.item.ItemStack import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.registry.MBlocks +import ru.dbotthepony.mc.otm.registry.MItems +import ru.dbotthepony.mc.otm.registry.MRecipes +import ru.dbotthepony.mc.otm.registry.WriteOnce + +var helpers: IJeiHelpers by WriteOnce() + private set @JeiPlugin +@Suppress("unused") class JEIPlugin : IModPlugin { companion object { private val LOCATION = ResourceLocation(OverdriveThatMatters.MOD_ID, "jei_plugin") @@ -20,6 +31,18 @@ class JEIPlugin : IModPlugin { } override fun registerRecipeCatalysts(registration: IRecipeCatalystRegistration) { - registration.addRecipeCatalyst(ItemStack(MBlocks.CHEMICAL_GENERATOR), RecipeTypes.FUELING) + registration.addRecipeCatalyst(ItemStack(MItems.CHEMICAL_GENERATOR), RecipeTypes.FUELING) + registration.addRecipeCatalyst(ItemStack(MItems.PLATE_PRESS), PlatePressRecipeCategory.recipeType) + } + + override fun registerCategories(registration: IRecipeCategoryRegistration) { + helpers = registration.jeiHelpers + registration.addRecipeCategories(PlatePressRecipeCategory) + } + + override fun registerRecipes(registration: IRecipeRegistration) { + val level = minecraft.level ?: throw NullPointerException("No ClientLevel. OLOLOLOLOLOLO") + + registration.addRecipes(PlatePressRecipeCategory.recipeType, level.recipeManager.getAllRecipesFor(MRecipes.PLATE_PRESS).filter { !it.isIncomplete }) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PlatePressRecipeCategory.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PlatePressRecipeCategory.kt new file mode 100644 index 000000000..5246432cd --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/PlatePressRecipeCategory.kt @@ -0,0 +1,103 @@ +package ru.dbotthepony.mc.otm.compat.jei + +import com.mojang.blaze3d.vertex.PoseStack +import mezz.jei.api.gui.builder.IRecipeLayoutBuilder +import mezz.jei.api.gui.drawable.IDrawable +import mezz.jei.api.gui.ingredient.IRecipeSlotsView +import mezz.jei.api.helpers.IJeiHelpers +import mezz.jei.api.recipe.IFocusGroup +import mezz.jei.api.recipe.RecipeIngredientRole +import mezz.jei.api.recipe.RecipeType +import mezz.jei.api.recipe.category.IRecipeCategory +import net.minecraft.network.chat.Component +import net.minecraft.resources.ResourceLocation +import net.minecraft.world.item.ItemStack +import ru.dbotthepony.mc.otm.OverdriveThatMatters +import ru.dbotthepony.mc.otm.client.minecraft +import ru.dbotthepony.mc.otm.client.render.TextAlign +import ru.dbotthepony.mc.otm.client.render.drawAligned +import ru.dbotthepony.mc.otm.client.screen.panels.AbstractSlotPanel +import ru.dbotthepony.mc.otm.client.screen.panels.FramePanel +import ru.dbotthepony.mc.otm.client.screen.widget.ProgressGaugePanel +import ru.dbotthepony.mc.otm.core.RGBAColor +import ru.dbotthepony.mc.otm.core.TranslatableComponent +import ru.dbotthepony.mc.otm.recipe.PlatePressRecipe +import ru.dbotthepony.mc.otm.registry.MItems +import ru.dbotthepony.mc.otm.registry.WriteOnce + +object PlatePressRecipeCategory : IRecipeCategory, IDrawable { + const val X_INPUT = 6f + const val Y_INPUT = 11f + + const val X_OUTPUT = 56f + const val Y_OUTPUT = 11f + + const val X_ARROW = 29f + const val Y_ARROW = 12f + + private val type = RecipeType(ResourceLocation(OverdriveThatMatters.MOD_ID), PlatePressRecipe::class.java) + + override fun getRecipeType(): RecipeType { + return type + } + + override fun getTitle(): Component { + return MItems.PLATE_PRESS.description + } + + override fun draw(poseStack: PoseStack, xOffset: Int, yOffset: Int) { + @Suppress("name_shadowing") + val xOffset = xOffset.toFloat() + + @Suppress("name_shadowing") + val yOffset = yOffset.toFloat() + + AbstractSlotPanel.SLOT_BACKGROUND.render(poseStack, X_INPUT + xOffset, Y_INPUT + yOffset) + AbstractSlotPanel.SLOT_BACKGROUND.render(poseStack, X_OUTPUT + xOffset, Y_OUTPUT + yOffset) + ProgressGaugePanel.GAUGE_BACKGROUND.render(poseStack, X_ARROW + xOffset, Y_ARROW + yOffset) + + ProgressGaugePanel.GAUGE_FOREGROUND.renderPartial( + poseStack, + X_ARROW + xOffset, + Y_ARROW + yOffset, + width = ((System.currentTimeMillis() % 4000L) / 4000f) * ProgressGaugePanel.GAUGE_FOREGROUND.w) + } + + override fun draw( + recipe: PlatePressRecipe, + recipeSlotsView: IRecipeSlotsView, + stack: PoseStack, + mouseX: Double, + mouseY: Double + ) { + minecraft.font.drawAligned(stack, TranslatableComponent("otm.gui.recipe.ticks", recipe.workTime), TextAlign.TOP_CENTER, 40f, 30f, RGBAColor.BLACK) + } + + override fun getWidth(): Int { + return 80 + } + + override fun getHeight(): Int { + return 40 + } + + override fun getBackground(): IDrawable { + return this + } + + private val iconField by lazy { + helpers.guiHelper.createDrawableItemStack(ItemStack(MItems.PLATE_PRESS)) + } + + override fun getIcon(): IDrawable { + return iconField + } + + override fun setRecipe(builder: IRecipeLayoutBuilder, recipe: PlatePressRecipe, focuses: IFocusGroup) { + builder.addSlot(RecipeIngredientRole.INPUT, X_INPUT.toInt() + 1, Y_INPUT.toInt() + 1) + .addIngredients(recipe.input) + + builder.addSlot(RecipeIngredientRole.OUTPUT, X_OUTPUT.toInt() + 1, Y_OUTPUT.toInt() + 1) + .addIngredients(recipe.output) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/SkinDrawable.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/SkinDrawable.kt new file mode 100644 index 000000000..b967edde6 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/SkinDrawable.kt @@ -0,0 +1,19 @@ +package ru.dbotthepony.mc.otm.compat.jei + +import com.mojang.blaze3d.vertex.PoseStack +import mezz.jei.api.gui.drawable.IDrawable +import ru.dbotthepony.mc.otm.client.render.SkinElement + +class SkinDrawable(val element: SkinElement) : IDrawable { + override fun getWidth(): Int { + return element.w.toInt() + } + + override fun getHeight(): Int { + return element.h.toInt() + } + + override fun draw(poseStack: PoseStack, xOffset: Int, yOffset: Int) { + element.render(poseStack, xOffset.toFloat(), yOffset.toFloat()) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/StretchingDrawable.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/StretchingDrawable.kt new file mode 100644 index 000000000..da3566a38 --- /dev/null +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/jei/StretchingDrawable.kt @@ -0,0 +1,19 @@ +package ru.dbotthepony.mc.otm.compat.jei + +import com.mojang.blaze3d.vertex.PoseStack +import mezz.jei.api.gui.drawable.IDrawable +import ru.dbotthepony.mc.otm.client.render.StretchingRectangleElement + +class StretchingDrawable(val element: StretchingRectangleElement, val rectWidth: Int, val rectHeight: Int) : IDrawable { + override fun getWidth(): Int { + return rectWidth + } + + override fun getHeight(): Int { + return rectHeight + } + + override fun draw(poseStack: PoseStack, xOffset: Int, yOffset: Int) { + element.render(poseStack, xOffset.toFloat(), yOffset.toFloat(), rectWidth.toFloat(), rectHeight.toFloat()) + } +} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PlatePressRecipe.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PlatePressRecipe.kt index 9b365def3..6d23fc1e4 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PlatePressRecipe.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/recipe/PlatePressRecipe.kt @@ -7,6 +7,7 @@ import net.minecraft.network.FriendlyByteBuf import net.minecraft.resources.ResourceLocation import net.minecraft.world.Container import net.minecraft.world.item.ItemStack +import net.minecraft.world.item.Items import net.minecraft.world.item.crafting.Ingredient import net.minecraft.world.item.crafting.Recipe import net.minecraft.world.item.crafting.RecipeSerializer @@ -43,7 +44,7 @@ class PlatePressRecipe( } override fun isIncomplete(): Boolean { - return input.isEmpty || output.isEmpty + return !(input.items.any { it.item != Items.BARRIER } && output.items.any { it.item != Items.BARRIER }) } override fun assemble(p_44001_: Container): ItemStack = resultItem.copy() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt index c0bc0eeb2..a8947a0ce 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/registry/MRegistry.kt @@ -65,14 +65,14 @@ private class RegistryDelegate(key: String) { } } -class WriteOnce : ReadWriteProperty { +class WriteOnce : ReadWriteProperty { private var value: V? = null - override fun getValue(thisRef: Any, property: KProperty<*>): V { + override fun getValue(thisRef: Any?, property: KProperty<*>): V { return checkNotNull(value) { "Property ${property.name} is not initialized" } } - override fun setValue(thisRef: Any, property: KProperty<*>, value: V) { + override fun setValue(thisRef: Any?, property: KProperty<*>, value: V) { if (this.value != null) { throw IllegalStateException("Property ${property.name} already initialized") }