diff --git a/src/main/java/org/betterx/betterend/integration/emi/EMIInfusionRecipe.java b/src/main/java/org/betterx/betterend/integration/emi/EMIInfusionRecipe.java new file mode 100644 index 00000000..154bdb7a --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/emi/EMIInfusionRecipe.java @@ -0,0 +1,130 @@ +package org.betterx.betterend.integration.emi; + +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.recipe.builders.InfusionRecipe; +import org.betterx.ui.ColorUtil; + +import net.minecraft.client.Minecraft; +import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.Style; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.FormattedCharSequence; +import net.minecraft.world.item.crafting.RecipeManager; + +import dev.emi.emi.api.EmiRegistry; +import dev.emi.emi.api.recipe.EmiRecipe; +import dev.emi.emi.api.recipe.EmiRecipeCategory; +import dev.emi.emi.api.render.EmiTexture; +import dev.emi.emi.api.stack.EmiIngredient; +import dev.emi.emi.api.stack.EmiStack; +import dev.emi.emi.api.widget.WidgetHolder; + +import java.util.List; +import org.jetbrains.annotations.Nullable; + +public class EMIInfusionRecipe implements EmiRecipe { + public final static EmiTexture BACKGROUND = new EmiTexture( + BetterEnd.makeID("textures/gui/infusion.png"), + 0, 0, + 84, 84, 84, 84, 84, 84 + ); + + public final Component[] ORIENTATIONS = { + Component.translatable("betterend.infusion.north").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.north_east").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.east").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.south_east").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.south").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.south_west").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.west").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + Component.translatable("betterend.infusion.north_west").setStyle(Style.EMPTY.withColor(ColorUtil.GRAY)), + }; + private final ResourceLocation id; + private final List input; + private final List output; + + public EMIInfusionRecipe(InfusionRecipe recipe) { + this.id = recipe.getId(); + this.input = recipe.getIngredients().stream().map(i -> EmiIngredient.of(i)).toList(); + this.output = List.of(EmiStack.of(recipe.getResultItem())); + } + + static void addAllRecipes(EmiRegistry emiRegistry, RecipeManager manager) { + for (InfusionRecipe recipe : manager.getAllRecipesFor(InfusionRecipe.TYPE)) { + emiRegistry.addRecipe(new EMIInfusionRecipe(recipe)); + } + } + + + @Override + public EmiRecipeCategory getCategory() { + return EMIPlugin.INFUSION_CATEGORY; + } + + @Override + public @Nullable ResourceLocation getId() { + return id; + } + + @Override + public List getInputs() { + return input; + } + + @Override + public List getOutputs() { + return output; + } + + @Override + public int getDisplayWidth() { + return 4 + 10 + 84 + 68; + } + + @Override + public int getDisplayHeight() { + return 4 + 20 + 84; + } + + @Override + public void addWidgets(WidgetHolder widgets) { + final int radius = 36; + final int halfSize = 9; + final int left = 10; + final int top = 18; + + final int cx = left + 84 / 2; + final int cy = top + 84 / 2; + + final int right = left + 84; + final int bottom = top + 84; + widgets.addTexture(BACKGROUND, left, top); + // Add an arrow texture to indicate processing + widgets.addTexture(EmiTexture.EMPTY_ARROW, right + 10, cy - 8); + + // Adds an input slot on the left + widgets.add(new TransparentSlotWidget(input.get(0), cx - halfSize, cy - halfSize)); + + FormattedCharSequence str = FormattedCharSequence.forward("N", Style.EMPTY); + widgets.addText(str, cx - Minecraft.getInstance().font.width(str) / 2, 4, ColorUtil.WHITE, true); + double a = Math.PI; + for (int i = 1; i < input.size(); i++) { + widgets.add(new TransparentSlotWidget( + input.get(i), + cx - halfSize + (int) (Math.sin(a) * radius), + cy - halfSize + (int) (Math.cos(a) * radius) + )).appendTooltip(ORIENTATIONS[i - 1]); + a -= Math.PI / 4; + } + + // Adds an output slot on the right + // Note that output slots need to call `recipeContext` to inform EMI about their recipe context + // This includes being able to resolve recipe trees, favorite stacks with recipe context, and more + widgets.addSlot(output.get(0), right + 40, cy - (halfSize + 4)).output(true).recipeContext(this); + } + + @Override + public boolean supportsRecipeTree() { + return true; + } +} diff --git a/src/main/java/org/betterx/betterend/integration/emi/EMIPlugin.java b/src/main/java/org/betterx/betterend/integration/emi/EMIPlugin.java index 2795b931..581b27ca 100644 --- a/src/main/java/org/betterx/betterend/integration/emi/EMIPlugin.java +++ b/src/main/java/org/betterx/betterend/integration/emi/EMIPlugin.java @@ -1,10 +1,28 @@ package org.betterx.betterend.integration.emi; +import org.betterx.betterend.BetterEnd; +import org.betterx.betterend.registry.EndBlocks; + +import net.minecraft.world.item.crafting.RecipeManager; + import dev.emi.emi.api.EmiRegistry; +import dev.emi.emi.api.recipe.EmiRecipeCategory; +import dev.emi.emi.api.stack.EmiStack; public class EMIPlugin implements dev.emi.emi.api.EmiPlugin { + public static final EmiStack INFUSION_WORKSTATION = EmiStack.of(EndBlocks.INFUSION_PEDESTAL); + + public static final EmiRecipeCategory INFUSION_CATEGORY = new EmiRecipeCategory( + BetterEnd.makeID("infusion"), + INFUSION_WORKSTATION, + org.betterx.bclib.integration.emi.EMIPlugin.getSprite(0, 16) + ); + @Override public void register(EmiRegistry emiRegistry) { - + final RecipeManager manager = emiRegistry.getRecipeManager(); + emiRegistry.addCategory(INFUSION_CATEGORY); + emiRegistry.addWorkstation(INFUSION_CATEGORY, INFUSION_WORKSTATION); + EMIInfusionRecipe.addAllRecipes(emiRegistry, manager); } } diff --git a/src/main/java/org/betterx/betterend/integration/emi/TransparentSlotWidget.java b/src/main/java/org/betterx/betterend/integration/emi/TransparentSlotWidget.java new file mode 100644 index 00000000..1cc65591 --- /dev/null +++ b/src/main/java/org/betterx/betterend/integration/emi/TransparentSlotWidget.java @@ -0,0 +1,92 @@ +package org.betterx.betterend.integration.emi; + +import org.betterx.ui.layout.components.render.RenderHelper; + +import com.mojang.blaze3d.systems.RenderSystem; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.gui.GuiComponent; +import net.minecraft.client.renderer.GameRenderer; + +import dev.emi.emi.EmiClient; +import dev.emi.emi.EmiConfig; +import dev.emi.emi.EmiRenderHelper; +import dev.emi.emi.api.render.EmiRender; +import dev.emi.emi.api.stack.EmiIngredient; +import dev.emi.emi.api.widget.Bounds; +import dev.emi.emi.api.widget.SlotWidget; + +public class TransparentSlotWidget extends SlotWidget { + + public TransparentSlotWidget(EmiIngredient stack, int x, int y) { + super(stack, x, y); + } + + + @Override + public void render(PoseStack matrices, int mouseX, int mouseY, float delta) { + Bounds bounds = this.getBounds(); + RenderSystem.setShader(GameRenderer::getPositionTexShader); + RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); + int width = bounds.width(); + int height = bounds.height(); + if (this.drawBack) { + if (this.textureId != null) { + RenderSystem.setShaderTexture(0, this.textureId); + GuiComponent.blit( + matrices, + bounds.x(), bounds.y(), width, height, + this.u, this.v, width, height, 256, 256 + ); + } else { + renderSlot(matrices); + } + } + + if (this.getRecipe() == null + && EmiClient.availableForCrafting.containsKey(this.getStack()) + && !this.getStack().isEmpty() + && !(Boolean) EmiClient.availableForCrafting.get(this.getStack())) { + GuiComponent.fill( + matrices, + bounds.x(), bounds.y(), + bounds.x() + bounds.width(), bounds.y() + bounds.height(), + 0x44FF0000 + ); + } + + int xOff = (width - 16) / 2; + int yOff = (height - 16) / 2; + this.getStack().render(matrices, bounds.x() + xOff, bounds.y() + yOff, delta); + if (this.catalyst) { + EmiRender.renderCatalystIcon(this.getStack(), matrices, this.x + xOff, this.y + yOff); + } + + if (EmiConfig.showHoverOverlay && bounds.contains(mouseX, mouseY)) { + EmiRenderHelper.drawSlotHightlight( + matrices, + bounds.x() + 1, bounds.y() + 1, + bounds.width() - 2, bounds.height() - 2 + ); + } + + } + + public void renderSlot(PoseStack matrices) { + Bounds bounds = this.getBounds(); + int width = bounds.width(); + int height = bounds.height(); + + GuiComponent.fill(matrices, bounds.x(), bounds.y(), bounds.x() + width, bounds.y() + height, 0xB08b8b8b); + RenderHelper.outline( + matrices, + bounds.x(), + bounds.y(), + bounds.x() + width, + bounds.y() + height, + 0xFA373737, + 0xFAFFFFFF + ); + RenderHelper.vLine(matrices, bounds.x() + width - 1, bounds.y(), bounds.y(), 0xFA8B8B8B); + RenderHelper.hLine(matrices, bounds.x(), bounds.x(), bounds.y() + bounds.height() - 1, 0xFA8B8B8B); + } +} diff --git a/src/main/resources/assets/betterend/lang/de_de.json b/src/main/resources/assets/betterend/lang/de_de.json index 5c267c6d..2347273f 100644 --- a/src/main/resources/assets/betterend/lang/de_de.json +++ b/src/main/resources/assets/betterend/lang/de_de.json @@ -620,5 +620,14 @@ "item.betterend.thallasium_sword_blade": "Thallasiumschwertklinge", "item.betterend.thallasium_sword_handle": "Thallasiumschwertgriff", "block.betterend.aeternium_anvil": "Ätheramboss", - "tag.betterend.alloying_iron": "Eisenlegierung" + "tag.betterend.alloying_iron": "Eisenlegierung", + "emi.category.betterend.infusion": "Elementarrituale", + "betterend.infusion.north": "Nördlicher Sockel", + "betterend.infusion.north_west": "Nordwestlciher Sockel", + "betterend.infusion.west": "Westlicher Sockel", + "betterend.infusion.south_west": "Südwestlicher Sockel", + "betterend.infusion.south": "Südlicher Sockel", + "betterend.infusion.south_east": "Südöstlicher Sockel", + "betterend.infusion.east": "Östlicher Sockel", + "betterend.infusion.north_east": "Nordöstlicher Sockel" } diff --git a/src/main/resources/assets/betterend/lang/en_us.json b/src/main/resources/assets/betterend/lang/en_us.json index b509b832..b144a918 100644 --- a/src/main/resources/assets/betterend/lang/en_us.json +++ b/src/main/resources/assets/betterend/lang/en_us.json @@ -819,5 +819,14 @@ "block.betterend.pallidium_thin": "Pallidium (Thin Cover)", "block.betterend.pallidium_tiny": "Pallidium (Tiny Cover)", "block.betterend.flammalix": "Flammalix", - "tag.betterend.alloying_iron": "Iron Alloys" + "tag.betterend.alloying_iron": "Iron Alloys", + "emi.category.betterend.infusion": "Infusion Ritual", + "betterend.infusion.north": "Northern Pedestal", + "betterend.infusion.north_west": "North-West Pedestal", + "betterend.infusion.west": "Western Pedestal", + "betterend.infusion.south_west": "South-West Pedestal", + "betterend.infusion.south": "Southern Pedestal", + "betterend.infusion.south_east": "South-East Pedestal", + "betterend.infusion.east": "Eastern Pedestal", + "betterend.infusion.north_east": "North-East Pedestal" } diff --git a/src/main/resources/assets/betterend/textures/gui/infusion.png b/src/main/resources/assets/betterend/textures/gui/infusion.png new file mode 100644 index 00000000..8da80a24 Binary files /dev/null and b/src/main/resources/assets/betterend/textures/gui/infusion.png differ