Skip to content

Commit

Permalink
Rewrite EMI compat in Java
Browse files Browse the repository at this point in the history
  • Loading branch information
Juuxel committed Jul 29, 2024
1 parent 21db9db commit 15d6b42
Show file tree
Hide file tree
Showing 9 changed files with 231 additions and 192 deletions.
52 changes: 52 additions & 0 deletions common/src/main/java/juuxel/adorn/compat/emi/AdornEmiPlugin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package juuxel.adorn.compat.emi;

import dev.emi.emi.api.EmiEntrypoint;
import dev.emi.emi.api.EmiPlugin;
import dev.emi.emi.api.EmiRegistry;
import dev.emi.emi.api.recipe.EmiRecipeCategory;
import dev.emi.emi.api.render.EmiTexture;
import dev.emi.emi.api.stack.EmiStack;
import juuxel.adorn.AdornCommon;
import juuxel.adorn.block.AdornBlocks;
import juuxel.adorn.client.gui.screen.TradingStationScreen;
import juuxel.adorn.recipe.AdornRecipes;
import juuxel.adorn.recipe.FluidBrewingRecipe;
import juuxel.adorn.recipe.ItemBrewingRecipe;
import juuxel.adorn.util.Logging;
import org.slf4j.Logger;

@EmiEntrypoint
public final class AdornEmiPlugin implements EmiPlugin {
private static final Logger LOGGER = Logging.logger();

public static final EmiRecipeCategory BREWER_CATEGORY = new EmiRecipeCategory(
AdornCommon.id("brewer"),
EmiStack.of(AdornBlocks.INSTANCE.getBREWER()),
new EmiTexture(AdornCommon.id("textures/gui/recipe_viewer/brewer_light.png"), 240, 0, 16, 16)
);

@Override
public void register(EmiRegistry registry) {
registry.addCategory(BREWER_CATEGORY);
registry.addWorkstation(BREWER_CATEGORY, EmiStack.of(AdornBlocks.INSTANCE.getBREWER()));

var recipeManager = registry.getRecipeManager();

for (var entry : recipeManager.listAllOfType(AdornRecipes.BREWING_TYPE.get())) {
BrewingEmiRecipe emiRecipe;
// TODO: Pattern matching
if (entry.value() instanceof ItemBrewingRecipe recipe) {
emiRecipe = new BrewingEmiRecipe(entry.id(), recipe);
} else if (entry.value() instanceof FluidBrewingRecipe recipe) {
emiRecipe = new BrewingEmiRecipe(entry.id(), recipe);
} else {
LOGGER.error("Unknown brewing recipe: {}", entry.value());
continue;
}

registry.addRecipe(emiRecipe);
}

registry.addDragDropHandler(TradingStationScreen.class, new TradingStationDragDropHandler());
}
}
110 changes: 110 additions & 0 deletions common/src/main/java/juuxel/adorn/compat/emi/BrewingEmiRecipe.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package juuxel.adorn.compat.emi;

import dev.emi.emi.api.recipe.EmiRecipe;
import dev.emi.emi.api.recipe.EmiRecipeCategory;
import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.api.stack.EmiStack;
import dev.emi.emi.api.widget.TankWidget;
import dev.emi.emi.api.widget.WidgetHolder;
import juuxel.adorn.AdornCommon;
import juuxel.adorn.block.entity.BrewerBlockEntity;
import juuxel.adorn.client.gui.screen.BrewerScreen;
import juuxel.adorn.item.AdornItems;
import juuxel.adorn.platform.FluidBridge;
import juuxel.adorn.recipe.FluidBrewingRecipe;
import juuxel.adorn.recipe.ItemBrewingRecipe;
import net.minecraft.util.Identifier;

import java.util.List;

public record BrewingEmiRecipe(
Identifier id,
EmiIngredient inputItem,
EmiIngredient firstItemIngredient,
EmiIngredient secondItemIngredient,
EmiIngredient fluidIngredient,
EmiStack result
) implements EmiRecipe {
private static final int PADDING = 0;
private static final int FLUID_SCALE_Z_OFFSET = 100;
private static final Identifier TEXTURE = AdornCommon.id("textures/gui/recipe_viewer/brewer_light.png");

public BrewingEmiRecipe(Identifier id, ItemBrewingRecipe recipe) {
this(
id,
EmiStack.of(AdornItems.INSTANCE.getMUG()),
EmiUtil.withRemainders(EmiIngredient.of(recipe.firstIngredient())),
EmiUtil.withRemainders(EmiIngredient.of(recipe.secondIngredient())),
EmiStack.EMPTY,
EmiStack.of(recipe.result())
);
}

public BrewingEmiRecipe(Identifier id, FluidBrewingRecipe recipe) {
this(
id,
EmiStack.of(AdornItems.INSTANCE.getMUG()),
EmiUtil.withRemainders(EmiIngredient.of(recipe.firstIngredient())),
EmiUtil.withRemainders(EmiIngredient.of(recipe.secondIngredient())),
EmiUtil.emiIngredientOf(recipe.fluid()),
EmiStack.of(recipe.result())
);
}

@Override
public EmiRecipeCategory getCategory() {
return AdornEmiPlugin.BREWER_CATEGORY;
}

@Override
public Identifier getId() {
return id;
}

@Override
public List<EmiIngredient> getInputs() {
return List.of(inputItem, firstItemIngredient, secondItemIngredient, fluidIngredient);
}

@Override
public List<EmiStack> getOutputs() {
return List.of(result);
}

@Override
public int getDisplayWidth() {
return 78 + 27 + 2 * PADDING;
}

@Override
public int getDisplayHeight() {
return 61 + 2 * PADDING;
}

@Override
public void addWidgets(WidgetHolder widgets) {
int leftX = PADDING;
int topY = PADDING;
widgets.addTexture(TEXTURE, leftX, topY, 105, 61, 49, 16);
widgets.addSlot(firstItemIngredient, leftX, topY).drawBack(false);
widgets.addSlot(secondItemIngredient, leftX + 60, topY).drawBack(false);
widgets.addSlot(result, leftX + 26, topY + 35).drawBack(false).recipeContext(this).large(true);
var capacity = BrewerBlockEntity.FLUID_CAPACITY_IN_BUCKETS * FluidBridge.get().getFluidUnit().getBucketVolume();
widgets.add(new TankWidget(fluidIngredient, leftX + 87, topY, 18, BrewerScreen.FLUID_AREA_HEIGHT + 2, capacity).drawBack(false));

// Empty mug
widgets.addSlot(inputItem, leftX + 3, topY + 38).drawBack(false);

// Fluid scale
widgets.addDrawable(leftX + 88, topY + 1, 16, BrewerScreen.FLUID_AREA_HEIGHT, (context, mouseX, mouseY, tickDelta) -> {
context.drawTexture(TEXTURE, 0, 0, FLUID_SCALE_Z_OFFSET, 154f, 17f, 16, BrewerScreen.FLUID_AREA_HEIGHT, 256, 256);
});

// Progress arrow
widgets.addDrawable(leftX + 35, topY + 8, 8, BrewerScreen.FLUID_AREA_HEIGHT, (context, mouseX, mouseY, tickDelta) -> {
float progressFraction = (System.currentTimeMillis() % 4000) / 4000f;
int height = Math.round(progressFraction * 25);
context.drawTexture(TEXTURE, 0, 0, 1, 176f, 0f, 8, height, 256, 256);
});
}
}
34 changes: 34 additions & 0 deletions common/src/main/java/juuxel/adorn/compat/emi/EmiUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package juuxel.adorn.compat.emi;

import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.api.stack.EmiStack;
import juuxel.adorn.fluid.FluidIngredient;
import juuxel.adorn.fluid.FluidUnit;
import juuxel.adorn.platform.FluidBridge;
import net.minecraft.item.Item;

public final class EmiUtil {
public static EmiIngredient emiIngredientOf(FluidIngredient ingredient) {
long amount = FluidUnit.convert(ingredient.amount(), ingredient.unit(), FluidBridge.get().getFluidUnit());
return EmiIngredient.of(
ingredient.fluid()
.getFluids()
.stream()
.map(fluid -> EmiStack.of(fluid, ingredient.nbt(), amount))
.toList()
);
}

public static EmiIngredient withRemainders(EmiIngredient ingredient) {
for (var stack : ingredient.getEmiStacks()) {
var item = stack.getKeyOfType(Item.class);
if (item == null) continue;
if (item.hasRecipeRemainder()) {
// TODO: Use stack-aware recipe remainders
stack.setRemainder(EmiStack.of(item.getRecipeRemainder()));
}
}

return ingredient;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package juuxel.adorn.compat.emi;

import dev.emi.emi.api.EmiDragDropHandler;
import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.api.stack.EmiStack;
import juuxel.adorn.client.gui.screen.TradingStationScreen;
import juuxel.adorn.menu.TradingStationMenu;
import net.minecraft.menu.Slot;

import java.util.List;
import java.util.Optional;

public final class TradingStationDragDropHandler implements EmiDragDropHandler<TradingStationScreen> {
@Override
public boolean dropStack(TradingStationScreen screen, EmiIngredient stack, int x, int y) {
var itemStack = single(stack.getEmiStacks()).map(EmiStack::getItemStack).orElse(null);
if (itemStack == null || itemStack.isEmpty() || !TradingStationMenu.isValidItem(itemStack)) return false;

for (var slot : new Slot[] { screen.getMenu().getSellingSlot(), screen.getMenu().getPriceSlot() }) {
var slotX = slot.x + screen.getPanelX();
var slotY = slot.y + screen.getPanelY();

if (slotX <= x && slotX < slotX + 16 && slotY <= y && y < slotY + 16) {
screen.updateTradeStack(slot, itemStack);
return true;
}
}

return false;
}

private static <T> Optional<T> single(List<T> ts) {
return ts.size() == 1 ? Optional.of(ts.get(0)) : Optional.empty();
}
}
2 changes: 0 additions & 2 deletions common/src/main/java/juuxel/adorn/fluid/FluidIngredient.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.mojang.serialization.codecs.RecordCodecBuilder;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.PacketByteBuf;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Optional;
Expand Down Expand Up @@ -45,7 +44,6 @@ public long getAmount() {
return amount;
}

@NotNull
@Override
public FluidUnit getUnit() {
return unit;
Expand Down
50 changes: 0 additions & 50 deletions common/src/main/kotlin/juuxel/adorn/compat/emi/AdornEmiPlugin.kt

This file was deleted.

90 changes: 0 additions & 90 deletions common/src/main/kotlin/juuxel/adorn/compat/emi/BrewingEmiRecipe.kt

This file was deleted.

Loading

0 comments on commit 15d6b42

Please sign in to comment.