Skip to content

Commit

Permalink
EMI support (#190)
Browse files Browse the repository at this point in the history
* Initial EMI support

* Added JEI boiler recipes

* Update EMI version
  • Loading branch information
Edivad99 committed Mar 24, 2024
1 parent 3595425 commit fa22045
Show file tree
Hide file tree
Showing 21 changed files with 599 additions and 38 deletions.
7 changes: 7 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ repositories {
name 'curseforge'
url 'https://www.cursemaven.com'
}
maven {
name 'TerraformersMC'
url 'https://maven.terraformersmc.com/'
}
}

dependencies {
Expand All @@ -139,6 +143,9 @@ dependencies {
compileOnly fg.deobf("mezz.jei:jei-$minecraft_version-forge-api:$jei_version")
runtimeOnly fg.deobf("mezz.jei:jei-$minecraft_version-forge:$jei_version")

compileOnly fg.deobf("dev.emi:emi-forge:$emi_version+$minecraft_version:api")
runtimeOnly fg.deobf("dev.emi:emi-forge:$emi_version+$minecraft_version")

compileOnly fg.deobf("vazkii.patchouli:Patchouli:$patchouli_version:api")
runtimeOnly fg.deobf("vazkii.patchouli:Patchouli:$patchouli_version")

Expand Down
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ mod_license=https://github.com/railcraft-reborn/railcraft/blob/1.20.x/LICENSE.md
mixin_version=0.8.5
jupiter_version=5.10.1
jei_version=15.2.0.27
emi_version=1.1.4
patchouli_version=1.20.1-84-FORGE
jade_id_api=5073670
jade_id=5072729
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// 1.20.1 2024-03-15T11:22:03.38324 Languages: en_us
153278f01cd809c49d4c04d4a8256d2f86c68fa5 assets/railcraft/lang/en_us.json
// 1.20.1 2024-03-23T20:42:22.369464 Languages: en_us
a2e26fd2cc0d5cdaf70d3b26c7c13bfca0f8bc7e assets/railcraft/lang/en_us.json
6 changes: 6 additions & 0 deletions src/generated/resources/assets/railcraft/lang/en_us.json
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,10 @@
"death.railcraft.train.5": "%s bought a one-way ticket to the afterlife",
"death.railcraft.train.6": "%s should have worn their Overalls",
"effect.railcraft.creosote": "Creosote",
"emi.category.railcraft.blasting_category": "Blast Furnace Smelting",
"emi.category.railcraft.coking_category": "Coke Oven Smelting",
"emi.category.railcraft.crushing_category": "Rock Crushing",
"emi.category.railcraft.rolling_category": "Metal Rolling",
"enchantment.railcraft.destruction": "Destruction",
"enchantment.railcraft.destruction.desc": "Deconstructs blocks in a wider area.",
"enchantment.railcraft.implosion": "Implosion",
Expand Down Expand Up @@ -675,7 +679,9 @@
"jei.railcraft.category.blast_furnace": "Blast Furnace Smelting",
"jei.railcraft.category.coke_oven": "Coke Oven Smelting",
"jei.railcraft.category.crusher": "Rock Crushing",
"jei.railcraft.category.fluid_boiler": "Fluid Boiler",
"jei.railcraft.category.rolling": "Metal Rolling",
"jei.railcraft.category.solid_boiler": "Solid Boiler",
"jei.railcraft.desc.block_signal": "This is the basic signal used for cart detection. It pairs one-to-one with an adjacent Block Signal and will detect any carts between the two and sends the resulting aspect to a paired Receiver.",
"jei.railcraft.desc.disposable_battery": "A battery designed to work with the charge network. Good for cheap, single use storage. Comes fully charged.",
"jei.railcraft.desc.disposable_battery_empty": "A battery designed to work with the charge network. Good for cheap, single use storage. This one is empty and can be recycled in the Crusher.",
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/mods/railcraft/Translations.java
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,8 @@ public static class Jei {
public static final String COKE_OVEN = makeKey("jei", "category.coke_oven");
public static final String BLAST_FURNACE = makeKey("jei", "category.blast_furnace");
public static final String CRUSHER = makeKey("jei", "category.crusher");
public static final String SOLID_BOILER = makeKey("jei", "category.solid_boiler");
public static final String FLUID_BOILER = makeKey("jei", "category.fluid_boiler");
public static final String CRUSHER_TIP = makeKey("jei", "tips.crusher");

public static final String MANUAL_ROLLING_MACHINE =
Expand Down Expand Up @@ -398,6 +400,13 @@ public static class Jei {
public static final String SPLIT = makeKey("jei.gui", "split");
}

public static class Emi {
public static final String ROLLING_CATEGORY = makeKey("emi.category", "rolling_category");
public static final String COKING_CATEGORY = makeKey("emi.category", "coking_category");
public static final String BLASTING_CATEGORY = makeKey("emi.category", "blasting_category");
public static final String CRUSHING_CATEGORY = makeKey("emi.category", "crushing_category");
}

public static class LookingAt {
public static final String SIGNALS = makeJadeKey("signals");
public static final String SWITCH_TRACK = makeJadeKey("switch_track");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -874,6 +874,12 @@ private void jeiTranslations() {
this.add(Translations.Jei.COKE_OVEN, "Coke Oven Smelting");
this.add(Translations.Jei.BLAST_FURNACE, "Blast Furnace Smelting");
this.add(Translations.Jei.CRUSHER, "Rock Crushing");
this.add(Translations.Emi.ROLLING_CATEGORY, "Metal Rolling");
this.add(Translations.Emi.COKING_CATEGORY, "Coke Oven Smelting");
this.add(Translations.Emi.BLASTING_CATEGORY, "Blast Furnace Smelting");
this.add(Translations.Emi.CRUSHING_CATEGORY, "Rock Crushing");
this.add(Translations.Jei.SOLID_BOILER, "Solid Boiler");
this.add(Translations.Jei.FLUID_BOILER, "Fluid Boiler");
this.add(Translations.Jei.CRUSHER_TIP, "(%s%% chance)");
this.add(Translations.Jei.MANUAL_ROLLING_MACHINE, """
Machine for rolling various shapes of metal. If there is only enough items in the grid \
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package mods.railcraft.integrations.emi;

import java.util.List;
import dev.emi.emi.api.recipe.BasicEmiRecipe;
import dev.emi.emi.api.render.EmiTexture;
import dev.emi.emi.api.render.EmiTooltipComponents;
import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.api.stack.EmiStack;
import dev.emi.emi.api.widget.WidgetHolder;
import mods.railcraft.integrations.jei.category.BlastFurnaceRecipeCategory;
import mods.railcraft.world.item.RailcraftItems;
import mods.railcraft.world.item.crafting.BlastFurnaceRecipe;
import net.minecraft.SharedConstants;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;

public class BlastFurnaceEmiRecipe extends BasicEmiRecipe {

private final BlastFurnaceRecipe recipe;

public BlastFurnaceEmiRecipe(BlastFurnaceRecipe recipe) {
super(RailcraftEmiPlugin.BLASTING_CATEGORY, recipe.getId(),
BlastFurnaceRecipeCategory.WIDTH, BlastFurnaceRecipeCategory.HEIGHT);
this.recipe = recipe;
this.inputs.add(EmiIngredient.of(recipe.getIngredients().get(0)));
var level = Minecraft.getInstance().level;
this.outputs.add(EmiStack.of(recipe.getResultItem(level.registryAccess())));
if (recipe.getSlagOutput() > 0) {
this.outputs.add(EmiStack.of(
new ItemStack(RailcraftItems.SLAG.get(), recipe.getSlagOutput())));
}
}

@Override
public void addWidgets(WidgetHolder widgets) {
widgets.addTexture(BlastFurnaceRecipeCategory.BACKGROUND,
0, 0, width, height, 55, 16);
widgets.addFillingArrow(24, 18, 10_000).tooltip((x, y) -> {
int cookTime = recipe.getCookingTime();
if (cookTime > 0) {
int cookTimeSeconds = cookTime / SharedConstants.TICKS_PER_SECOND;
var timeString = Component.translatable("gui.jei.category.smelting.time.seconds",
cookTimeSeconds);
return List.of(EmiTooltipComponents.of(timeString));
}
return List.of(EmiTooltipComponents.of(Component.empty()));
});
widgets.addAnimatedTexture(EmiTexture.FULL_FLAME, 1, 20, 10_000, false, true, true);

widgets.addSlot(this.inputs.get(0), 0, 0);
widgets.addSlot(this.outputs.get(0), 56, 0).large(true).recipeContext(this);
if (this.outputs.size() > 1) {
widgets.addSlot(this.outputs.get(1), 60, 36).recipeContext(this);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package mods.railcraft.integrations.emi;

import java.util.List;
import dev.emi.emi.api.forge.ForgeEmiStack;
import dev.emi.emi.api.recipe.BasicEmiRecipe;
import dev.emi.emi.api.render.EmiTexture;
import dev.emi.emi.api.render.EmiTooltipComponents;
import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.api.stack.EmiStack;
import dev.emi.emi.api.widget.WidgetHolder;
import mods.railcraft.integrations.jei.category.CokeOvenRecipeCategory;
import mods.railcraft.world.item.crafting.CokeOvenRecipe;
import net.minecraft.SharedConstants;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;

public class CokeOvenEmiRecipe extends BasicEmiRecipe {

private final CokeOvenRecipe recipe;

public CokeOvenEmiRecipe(CokeOvenRecipe recipe) {
super(RailcraftEmiPlugin.COKING_CATEGORY, recipe.getId(),
CokeOvenRecipeCategory.WIDTH, CokeOvenRecipeCategory.HEIGHT);
this.recipe = recipe;
this.inputs.add(EmiIngredient.of(recipe.getIngredients().get(0)));
var level = Minecraft.getInstance().level;
this.outputs.add(EmiStack.of(recipe.getResultItem(level.registryAccess())));
}

@Override
public void addWidgets(WidgetHolder widgets) {
widgets.addTexture(CokeOvenRecipeCategory.BACKGROUND, 0, 0, width, height, 15, 23);
widgets.addFillingArrow(18, 20, 10_000).tooltip((x, y) -> {
int cookTime = recipe.getCookingTime();
if (cookTime > 0) {
int cookTimeSeconds = cookTime / SharedConstants.TICKS_PER_SECOND;
var timeString = Component.translatable("gui.jei.category.smelting.time.seconds",
cookTimeSeconds);
return List.of(EmiTooltipComponents.of(timeString));
}
return List.of(EmiTooltipComponents.of(Component.empty()));
});
widgets.addAnimatedTexture(EmiTexture.FULL_FLAME, 1, 3, 10_000, false, true, true);

widgets.addSlot(this.inputs.get(0), 0, 19);
widgets.addSlot(this.outputs.get(0), 42, 15).large(true).recipeContext(this);

var fluid = ForgeEmiStack.of(recipe.getCreosote());
widgets.addTank(fluid, 74, 0, 50, 49, 10_000)
.drawBack(false)
.recipeContext(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package mods.railcraft.integrations.emi;

import dev.emi.emi.api.recipe.BasicEmiRecipe;
import dev.emi.emi.api.render.EmiTexture;
import dev.emi.emi.api.render.EmiTooltipComponents;
import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.api.stack.EmiStack;
import dev.emi.emi.api.widget.WidgetHolder;
import mods.railcraft.Translations;
import mods.railcraft.integrations.jei.category.CrusherRecipeCategory;
import mods.railcraft.world.item.crafting.CrusherRecipe;
import net.minecraft.ChatFormatting;
import net.minecraft.SharedConstants;
import net.minecraft.network.chat.Component;
import net.minecraft.world.item.ItemStack;

public class CrusherEmiRecipe extends BasicEmiRecipe {

private final CrusherRecipe recipe;

public CrusherEmiRecipe(CrusherRecipe recipe) {
super(RailcraftEmiPlugin.CRUSHING_CATEGORY, recipe.getId(),
CrusherRecipeCategory.WIDTH, CrusherRecipeCategory.HEIGHT);
this.recipe = recipe;
this.inputs.add(EmiIngredient.of(recipe.getIngredients().get(0)));
this.recipe.getProbabilityOutputs().stream()
.map(CrusherRecipe.CrusherOutput::getOutput)
.map(EmiStack::of)
.forEach(this.outputs::add);
}

@Override
public void addWidgets(WidgetHolder widgets) {
widgets.addTexture(CrusherRecipeCategory.BACKGROUND, 0, 0, width, height, 0, 171);
var crushingTexture = new EmiTexture(CrusherRecipeCategory.BACKGROUND,
144, 171, 29, 53);
widgets.addAnimatedTexture(crushingTexture, 58, 0,
1000 * this.recipe.getProcessTime() / SharedConstants.TICKS_PER_SECOND,
true, false, false);

widgets.addSlot(this.inputs.get(0), 18, 18);

var outputs = recipe.getProbabilityOutputs();
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
int index = 1 + x + (y * 3);
var itemStack = ItemStack.EMPTY;
if (outputs.size() > index - 1) {
itemStack = outputs.get(index - 1).getOutput();
}
if (itemStack.isEmpty()) {
widgets.addSlot(90 + x * 18, y * 18);
} else {
widgets
.addSlot(EmiStack.of(itemStack), 90 + x * 18, y * 18)
.appendTooltip(() -> {
double probability = outputs.get(index - 1).probability() * 100;
var probText = Component.translatable(Translations.Jei.CRUSHER_TIP, probability)
.withStyle(ChatFormatting.GRAY);
return EmiTooltipComponents.of(probText);
})
.recipeContext(this);
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package mods.railcraft.integrations.emi;

import java.util.function.Function;
import dev.emi.emi.api.EmiEntrypoint;
import dev.emi.emi.api.EmiPlugin;
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.recipe.VanillaEmiRecipeCategories;
import dev.emi.emi.api.stack.EmiStack;
import mods.railcraft.api.core.RailcraftConstants;
import mods.railcraft.world.item.crafting.RailcraftRecipeTypes;
import mods.railcraft.world.level.block.RailcraftBlocks;
import net.minecraft.world.Container;
import net.minecraft.world.item.crafting.Recipe;
import net.minecraft.world.item.crafting.RecipeType;

@EmiEntrypoint
public class RailcraftEmiPlugin implements EmiPlugin {

private static final EmiStack MANUAL_ROLLING_MACHINE =
EmiStack.of(RailcraftBlocks.MANUAL_ROLLING_MACHINE.get());
public static final EmiRecipeCategory ROLLING_CATEGORY =
new EmiRecipeCategory(RailcraftConstants.rl("rolling_category"), MANUAL_ROLLING_MACHINE);

private static final EmiStack CRUSHER =
EmiStack.of(RailcraftBlocks.CRUSHER.get());
public static final EmiRecipeCategory CRUSHING_CATEGORY =
new EmiRecipeCategory(RailcraftConstants.rl("crushing_category"), CRUSHER);

private static final EmiStack COKE_OVEN =
EmiStack.of(RailcraftBlocks.COKE_OVEN_BRICKS.get());
public static final EmiRecipeCategory COKING_CATEGORY =
new EmiRecipeCategory(RailcraftConstants.rl("coking_category"), COKE_OVEN);

private static final EmiStack BLAST_FURNACE =
EmiStack.of(RailcraftBlocks.BLAST_FURNACE_BRICKS.get());
public static final EmiRecipeCategory BLASTING_CATEGORY =
new EmiRecipeCategory(RailcraftConstants.rl("blasting_category"), BLAST_FURNACE);

@Override
public void register(EmiRegistry registry) {
// Tell EMI to add a tab for your category
registry.addCategory(ROLLING_CATEGORY);
registry.addCategory(CRUSHING_CATEGORY);
registry.addCategory(COKING_CATEGORY);
registry.addCategory(BLASTING_CATEGORY);

// Add all the workstations your category uses
registry.addWorkstation(ROLLING_CATEGORY, MANUAL_ROLLING_MACHINE);
registry.addWorkstation(ROLLING_CATEGORY,
EmiStack.of(RailcraftBlocks.POWERED_ROLLING_MACHINE.get()));
registry.addWorkstation(CRUSHING_CATEGORY, CRUSHER);
registry.addWorkstation(COKING_CATEGORY, COKE_OVEN);
registry.addWorkstation(BLASTING_CATEGORY, BLAST_FURNACE);
registry.addWorkstation(VanillaEmiRecipeCategories.SMELTING,
EmiStack.of(RailcraftBlocks.STEAM_OVEN.get()));

registerRecipe(registry, RailcraftRecipeTypes.ROLLING.get(), RollingEmiRecipe::new);
registerRecipe(registry, RailcraftRecipeTypes.CRUSHING.get(), CrusherEmiRecipe::new);
registerRecipe(registry, RailcraftRecipeTypes.COKING.get(), CokeOvenEmiRecipe::new);
registerRecipe(registry, RailcraftRecipeTypes.BLASTING.get(), BlastFurnaceEmiRecipe::new);
}

private <C extends Container, T extends Recipe<C>> void registerRecipe(
EmiRegistry registry, RecipeType<T> recipeType, Function<T, EmiRecipe> emiRecipeFunction) {
var manager = registry.getRecipeManager();
for (var x : manager.getAllRecipesFor(recipeType)) {
registry.addRecipe(emiRecipeFunction.apply(x));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package mods.railcraft.integrations.emi;

import java.util.ArrayList;
import java.util.List;
import dev.emi.emi.api.recipe.EmiCraftingRecipe;
import dev.emi.emi.api.recipe.EmiRecipeCategory;
import dev.emi.emi.api.stack.EmiIngredient;
import dev.emi.emi.api.stack.EmiStack;
import mods.railcraft.world.item.crafting.RollingRecipe;
import net.minecraft.client.Minecraft;

public class RollingEmiRecipe extends EmiCraftingRecipe {

public RollingEmiRecipe(RollingRecipe recipe) {
super(padIngredients(recipe),
EmiStack.of(recipe.getResultItem(Minecraft.getInstance().level.registryAccess())),
recipe.getId(), false);
}

@Override
public EmiRecipeCategory getCategory() {
return RailcraftEmiPlugin.ROLLING_CATEGORY;
}

private static List<EmiIngredient> padIngredients(RollingRecipe recipe) {
var list = new ArrayList<EmiIngredient>();
int i = 0;
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
if (x >= recipe.getWidth() || y >= recipe.getHeight() || i >= recipe.getIngredients().size()) {
list.add(EmiStack.EMPTY);
} else {
list.add(EmiIngredient.of(recipe.getIngredients().get(i++)));
}
}
}
return list;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ public void drawInfo(int recipeWidth, int recipeHeight, GuiGraphics guiGraphics,
double mouseY) {
var font = Minecraft.getInstance().font;
int stringWidth = font.width(this.info) / 2;
guiGraphics.drawString(font, this.info, 82 - stringWidth, 0, 0xFF808080, false);
guiGraphics.drawString(font, this.info, 82 - stringWidth, 0,
RailcraftJeiPlugin.TEXT_COLOR, false);
}

@Override
Expand Down

0 comments on commit fa22045

Please sign in to comment.