Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ repositories {
url = "https://maven.blamejared.com"
}
maven { url "https://maven.ryanliptak.com/" }
maven {
// EMI
url = "https://maven.terraformersmc.com/"
}
}

base {
Expand Down Expand Up @@ -114,6 +118,8 @@ dependencies {
compileOnly "squeek.appleskin:appleskin-neoforge:${appleskin_version}:api"
runtimeOnly "squeek.appleskin:appleskin-neoforge:${appleskin_version}"

compileOnly "dev.emi:emi-neoforge:${emi_version}:api"

def ctDep = "com.blamejared.crafttweaker:CraftTweaker-neoforge-${crafttweaker_minecraft}:${crafttweaker_version}"
compileOnly ctDep
runtimeOnly ctDep
Expand Down
3 changes: 2 additions & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ org.gradle.configuration-cache=true

# Parchment
parchment_minecraft_version=1.21
parchment_mappings_version=2024.07.28
parchment_mappings_version=2024.07.07

# Minecraft
minecraft_version=1.21.1
Expand All @@ -27,6 +27,7 @@ mod_description=A cozy farming and cooking expansion for Minecraft!
# Dependency Info
jei_minecraft=1.21
jei_version=19.8.2.99
emi_version=1.1.12+1.21
appleskin_version=mc1.21-3.0.5
crafttweaker_minecraft=1.21
crafttweaker_version=20.0.21
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package vectorwing.farmersdelight.integration.emi;

import dev.emi.emi.api.EmiEntrypoint;
import dev.emi.emi.api.EmiPlugin;
import dev.emi.emi.api.EmiRegistry;
import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.api.stack.EmiStack;
import net.minecraft.client.Minecraft;
import net.minecraft.world.item.crafting.RecipeHolder;
import vectorwing.farmersdelight.common.crafting.CookingPotRecipe;
import vectorwing.farmersdelight.common.crafting.CuttingBoardRecipe;
import vectorwing.farmersdelight.common.registry.ModMenuTypes;
import vectorwing.farmersdelight.common.registry.ModRecipeTypes;
import vectorwing.farmersdelight.integration.emi.handler.CookingPotEmiRecipeHandler;
import vectorwing.farmersdelight.integration.emi.recipe.CookingPotEmiRecipe;
import vectorwing.farmersdelight.integration.emi.recipe.CuttingEmiRecipe;
import vectorwing.farmersdelight.integration.emi.recipe.DecompositionEmiRecipe;

@EmiEntrypoint
public class EMIPlugin implements EmiPlugin {

@Override
public void register(EmiRegistry registry) {
registry.addCategory(FDRecipeCategories.COOKING);
registry.addCategory(FDRecipeCategories.CUTTING);
registry.addCategory(FDRecipeCategories.DECOMPOSITION);

registry.addWorkstation(FDRecipeCategories.COOKING, FDRecipeWorkstations.COOKING_POT);
registry.addWorkstation(FDRecipeCategories.CUTTING, FDRecipeWorkstations.CUTTING_BOARD);
registry.addRecipeHandler(ModMenuTypes.COOKING_POT.get(), new CookingPotEmiRecipeHandler());

for (RecipeHolder<CookingPotRecipe> recipe : registry.getRecipeManager().getAllRecipesFor(ModRecipeTypes.COOKING.get())) {
registry.addRecipe(new CookingPotEmiRecipe(recipe.id(), recipe.value().getIngredients().stream().map(EmiIngredient::of).toList(),
EmiStack.of(recipe.value().getResultItem(Minecraft.getInstance().level.registryAccess())), EmiStack.of(recipe.value().getOutputContainer()), recipe.value().getCookTime(), recipe.value().getExperience()));
}

for (RecipeHolder<CuttingBoardRecipe> recipe : registry.getRecipeManager().getAllRecipesFor(ModRecipeTypes.CUTTING.get())) {
registry.addRecipe(new CuttingEmiRecipe(recipe.id(), EmiIngredient.of(recipe.value().getTool()), EmiIngredient.of(recipe.value().getIngredients().get(0)),
recipe.value().getRollableResults().stream().map(chanceResult -> EmiStack.of(chanceResult.stack()).setChance(chanceResult.chance())).toList()));
}
registry.addRecipe(new DecompositionEmiRecipe());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package vectorwing.farmersdelight.integration.emi;

import dev.emi.emi.api.recipe.EmiRecipeCategory;
import dev.emi.emi.api.render.EmiRenderable;
import net.minecraft.resources.ResourceLocation;
import vectorwing.farmersdelight.FarmersDelight;

public class FDRecipeCategories {
private static final ResourceLocation SIMPLIFIED_TEXTURES = ResourceLocation.fromNamespaceAndPath(FarmersDelight.MODID, "textures/gui/emi/simplified.png");

public static final EmiRecipeCategory COOKING = new EmiRecipeCategory(ResourceLocation.fromNamespaceAndPath(FarmersDelight.MODID, "cooking"), FDRecipeWorkstations.COOKING_POT, simplifiedRenderer(0, 0));
public static final EmiRecipeCategory CUTTING = new EmiRecipeCategory(ResourceLocation.fromNamespaceAndPath(FarmersDelight.MODID, "cutting"), FDRecipeWorkstations.CUTTING_BOARD, simplifiedRenderer(16, 0));
public static final EmiRecipeCategory DECOMPOSITION = new EmiRecipeCategory(ResourceLocation.fromNamespaceAndPath(FarmersDelight.MODID, "decomposition"), FDRecipeWorkstations.ORGANIC_COMPOST, simplifiedRenderer(32, 0));

private static EmiRenderable simplifiedRenderer(int u, int v) {
return (draw, x, y, delta) -> {
draw.blit(SIMPLIFIED_TEXTURES, x, y, u, v, 16, 16, 48, 16);
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package vectorwing.farmersdelight.integration.emi;

import dev.emi.emi.api.stack.EmiStack;
import vectorwing.farmersdelight.common.registry.ModItems;

public class FDRecipeWorkstations {
public static final EmiStack COOKING_POT = EmiStack.of(ModItems.COOKING_POT.get());
public static final EmiStack CUTTING_BOARD = EmiStack.of(ModItems.CUTTING_BOARD.get());
public static final EmiStack ORGANIC_COMPOST = EmiStack.of(ModItems.ORGANIC_COMPOST.get());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package vectorwing.farmersdelight.integration.emi.handler;

import dev.emi.emi.api.recipe.EmiRecipe;
import dev.emi.emi.api.recipe.handler.StandardRecipeHandler;
import net.minecraft.world.inventory.Slot;
import org.jetbrains.annotations.Nullable;
import vectorwing.farmersdelight.common.block.entity.container.CookingPotMenu;
import vectorwing.farmersdelight.integration.emi.FDRecipeCategories;

import java.util.ArrayList;
import java.util.List;

public class CookingPotEmiRecipeHandler implements StandardRecipeHandler<CookingPotMenu> {
@Override
public List<Slot> getInputSources(CookingPotMenu handler) {
List<Slot> slots = new ArrayList<>();

for (int i = 0; i < 7; ++i) {
slots.add(handler.getSlot(i));
}

for (int i = 9; i < 9 + 36; ++i) {
slots.add(handler.getSlot(i));
}

return slots;
}

@Override
public List<Slot> getCraftingSlots(CookingPotMenu handler) {
List<Slot> slots = new ArrayList<>();

for (int i = 0; i < 7; ++i) {
slots.add(handler.getSlot(i));
}

return slots;
}

@Override
public @Nullable Slot getOutputSlot(CookingPotMenu handler) {
return handler.slots.get(8);
}

@Override
public boolean supportsRecipe(EmiRecipe recipe) {
return recipe.getCategory() == FDRecipeCategories.COOKING && recipe.supportsRecipeTree();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package vectorwing.farmersdelight.integration.emi.recipe;

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.SlotWidget;
import dev.emi.emi.api.widget.WidgetHolder;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
import vectorwing.farmersdelight.FarmersDelight;
import vectorwing.farmersdelight.common.utility.ClientRenderUtils;
import vectorwing.farmersdelight.integration.emi.FDRecipeCategories;

import java.util.ArrayList;
import java.util.List;

public class CookingPotEmiRecipe implements EmiRecipe {
private static final ResourceLocation BACKGROUND = ResourceLocation.fromNamespaceAndPath(FarmersDelight.MODID, "textures/gui/cooking_pot.png");

private final ResourceLocation id;
private final List<EmiIngredient> inputs;
private final EmiStack output;
private final EmiStack container;
private final int cookTime;
private final float experience;
private final List<ClientTooltipComponent> tooltipComponents;

public CookingPotEmiRecipe(ResourceLocation id, List<EmiIngredient> inputs, EmiStack output,
EmiStack container, int cookTime, float experience) {
this.id = id;
this.inputs = inputs;
this.output = output;
this.container = container;
this.cookTime = cookTime;
this.experience = experience;
this.tooltipComponents = createTooltipComponents();
}

private List<ClientTooltipComponent> createTooltipComponents() {
List<ClientTooltipComponent> tooltipStrings = new ArrayList<>();

if (cookTime > 0) {
int cookTimeSeconds = cookTime / 20;
tooltipStrings.add(ClientTooltipComponent.create(Component.translatable("emi.cooking.time", cookTimeSeconds).getVisualOrderText()));
}
if (experience > 0) {
tooltipStrings.add(ClientTooltipComponent.create(Component.translatable("emi.cooking.experience", experience).getVisualOrderText()));
}

return tooltipStrings;
}

@Override
public EmiRecipeCategory getCategory() {
return FDRecipeCategories.COOKING;
}

@Override
public @Nullable ResourceLocation getId() {
return id;
}

@Override
public List<EmiIngredient> getInputs() {
return inputs;
}

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

@Override
public List<EmiIngredient> getCatalysts() {
return List.of(container);
}

@Override
public int getDisplayWidth() {
return 117;
}

@Override
public int getDisplayHeight() {
return 56;
}

@Override
public void addWidgets(WidgetHolder widgets) {
widgets.addTexture(BACKGROUND, 0, 0, 116, 56, 29, 16);

int borderSlotSize = 18;
for (int row = 0; row < 2; ++row) {
for (int column = 0; column < 3; ++column) {
int inputIndex = row * 3 + column;
if (inputIndex < inputs.size()) {
addSlot(widgets, inputs.get(inputIndex), (column * borderSlotSize), (row * borderSlotSize));
}
}
}
addSlot(widgets, output, 94, 9);
addSlot(widgets, container, 62, 38);
addSlot(widgets, output, 94, 38).recipeContext(this);

// Arrow
widgets.addAnimatedTexture(BACKGROUND, 60, 9, 24, 17, 176, 15, 1000 * 10, true, false, false);
// Heat Indicator
widgets.addTexture(BACKGROUND, 18, 39, 17, 15, 176, 0);
// Time Icon
widgets.addTexture(BACKGROUND, 64, 2, 8, 11, 176, 32);
// Experience Icon
if (experience > 0) {
widgets.addTexture(BACKGROUND, 63,21, 9, 9, 176, 43);
}

widgets.addTooltip((mouseX, mouseY) -> {
if (ClientRenderUtils.isCursorInsideBounds(60, 2, 22, 28, mouseX, mouseY)) {
return tooltipComponents;
}
return List.of();
}, 0, 0, widgets.getWidth(), widgets.getHeight());
}

private SlotWidget addSlot(WidgetHolder widgets, EmiIngredient ingredient, int x, int y) {
return widgets.addSlot(ingredient, x, y).drawBack(false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package vectorwing.farmersdelight.integration.emi.recipe;

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.WidgetHolder;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
import vectorwing.farmersdelight.FarmersDelight;
import vectorwing.farmersdelight.integration.emi.FDRecipeCategories;

import java.util.List;

public class CuttingEmiRecipe implements EmiRecipe {
private static final ResourceLocation BACKGROUND = ResourceLocation.fromNamespaceAndPath(FarmersDelight.MODID, "textures/gui/jei/cutting_board.png");
public static final int OUTPUT_GRID_X = 69;
public static final int OUTPUT_GRID_Y = 3;

private final ResourceLocation id;
private final EmiIngredient tool;
private final EmiIngredient input;
private final List<EmiStack> outputs;

public CuttingEmiRecipe(ResourceLocation id, EmiIngredient tool, EmiIngredient input, List<EmiStack> outputs) {
this.id = id;
this.tool = tool;
this.input = input;
this.outputs = outputs;

}

@Override
public EmiRecipeCategory getCategory() {
return FDRecipeCategories.CUTTING;
}

@Override
public @Nullable ResourceLocation getId() {
return id;
}

@Override
public List<EmiIngredient> getInputs() {
return List.of(input);
}

@Override
public List<EmiStack> getOutputs() {
return outputs;
}

@Override
public List<EmiIngredient> getCatalysts() {
return List.of(tool);
}

@Override
public int getDisplayWidth() {
return 111;
}

@Override
public int getDisplayHeight() {
return 44;
}

@Override
public void addWidgets(WidgetHolder widgets) {
widgets.addTexture(BACKGROUND, 0, 0, 111, 44, 4, 7);

widgets.addSlot(tool, 11, 0).drawBack(false);
widgets.addSlot(input, 11, 19).drawBack(false);

int size = outputs.size();
int centerX = size > 1 ? 1 : 10;
int centerY = size > 2 ? 1 : 10;

for (int i = 0; i < size; i++) {
int xOffset = centerX + (i % 2 == 0 ? 0 : 19);
int yOffset = centerY + ((i / 2) * 19);

EmiIngredient output = outputs.get(i);
widgets.addSlot(output, OUTPUT_GRID_X + xOffset, OUTPUT_GRID_Y + yOffset).backgroundTexture(BACKGROUND, output.getChance() < 1 ? 18 : 0, 58).recipeContext(this);
}
}
}
Loading