Skip to content

Remove Recipes from JEI #212

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 47 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
6c9a697
extract ReloadKey to separate file
WaitingIdly Jul 25, 2024
801c881
add some jei accessors
WaitingIdly Jul 25, 2024
f50fc56
add IJEIRemoval interface
WaitingIdly Jul 25, 2024
1eca5cb
add class to remove target
WaitingIdly Jul 25, 2024
e375d0b
add keybind to target
WaitingIdly Jul 25, 2024
492d5f9
allow multiple categories
WaitingIdly Jul 25, 2024
689a189
note a failure to find a recipe
WaitingIdly Jul 25, 2024
7ec0c81
use cached loaded
WaitingIdly Jul 25, 2024
3576436
add asGroovyCode resource location
WaitingIdly Jul 27, 2024
6518f2c
improve base removal operations
WaitingIdly Jul 27, 2024
b022314
set keybind interval to static final
WaitingIdly Jul 30, 2024
856f424
only check on keyboard downpress
WaitingIdly Jul 30, 2024
31470e4
add new GSCC methods to get fluid/item without size
WaitingIdly Jul 30, 2024
8b36383
add nbt tag option to single stack
WaitingIdly Aug 1, 2024
f9c605c
move jei removal to subfolder, rework, and document
WaitingIdly Aug 1, 2024
58d9580
add BetterWithMods jei removal
WaitingIdly Aug 1, 2024
f86429b
add Mekanism jei removal
WaitingIdly Aug 1, 2024
213cbed
add Thaumcraft jei removal
WaitingIdly Aug 1, 2024
bde4a66
implement basics
WaitingIdly Aug 1, 2024
94e142f
implement some more advanced compat
WaitingIdly Aug 1, 2024
2fc26fc
addStygianIronAnvil compat
WaitingIdly Aug 1, 2024
6e873bc
add Inspirations Cauldron compat with note about commented code
WaitingIdly Aug 1, 2024
545d4f7
fix keybind lang keys
WaitingIdly Aug 1, 2024
af0aa79
handle keybind combos and format better
WaitingIdly Aug 1, 2024
afb8e06
remove commented out code
WaitingIdly Aug 1, 2024
ae161c1
world of color
WaitingIdly Aug 1, 2024
e6596d3
increase trim length, store indicator to static final
WaitingIdly Aug 1, 2024
78afd8f
move thaumic jei dep to deobf
WaitingIdly Aug 1, 2024
19c53f6
remove unused accessor method
WaitingIdly Aug 1, 2024
37e0950
make thaumic jei not required
WaitingIdly Aug 1, 2024
85ba657
color gas, infusion, and aspects
WaitingIdly Aug 1, 2024
a4ff5ad
add comment indicating thaumic jei
WaitingIdly Aug 1, 2024
79f2b72
use optional for Immersive Petroleum's Distillation
WaitingIdly Aug 1, 2024
1889921
add format string
WaitingIdly Aug 1, 2024
dfd9b70
add chisel carving compat
WaitingIdly Aug 1, 2024
e0762cc
disable exact method
WaitingIdly Aug 1, 2024
37bb177
add inputItemOperation for ignoring all outputs
WaitingIdly Aug 2, 2024
caffbf9
add include to pair with exclude
WaitingIdly Aug 2, 2024
37cc64c
extract slot focused ingredient logic
WaitingIdly Aug 2, 2024
6a0c3da
go through an ensure methods exist
WaitingIdly Aug 2, 2024
6f47a8a
disable more invalid operations
WaitingIdly Aug 2, 2024
7dbc834
comment out incorrect Fusion and Miniaturization methods
WaitingIdly Aug 2, 2024
b2a909c
remove the default input and output item operations
WaitingIdly Aug 2, 2024
339dd2b
extract remove combo and text logic from keybind
WaitingIdly Aug 2, 2024
d2804a9
add first-operation disclaimer with github link
WaitingIdly Aug 2, 2024
1c16a97
comment todo jei for mekanism methods
WaitingIdly Aug 2, 2024
0762660
move to API, break up file, and reorganize
WaitingIdly Aug 2, 2024
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
5 changes: 1 addition & 4 deletions dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ final def mod_dependencies = [
'roots-246183:3905074' : [project.debug_roots],
'rustic-256141:3107974' : [project.debug_rustic],
'thaumcraft-223628:2629023' : [project.debug_thaum],
'thaumic_jei-285492:2705304' : [project.debug_thaum],
'cofh_core-69162:2920433' : [project.debug_thermal],
'cofh_world-271384:2920434' : [project.debug_thermal],
'thermal_expansion-69163:2926431' : [project.debug_thermal],
Expand Down Expand Up @@ -131,10 +132,6 @@ dependencies {
}
}

if (project.debug_thaum.toBoolean()) {
runtimeOnly 'curse.maven:thaumic_jei-285492:2705304'
}

compileOnly 'com.enderio:endercore:0.5.78'
compileOnly 'crazypants:enderio:5.3.72'
if (project.debug_enderio.toBoolean()) {
Expand Down
44 changes: 17 additions & 27 deletions src/main/java/com/cleanroommc/groovyscript/GroovyScript.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,10 @@
import com.cleanroommc.groovyscript.documentation.linkgenerator.LinkGeneratorHooks;
import com.cleanroommc.groovyscript.event.EventHandler;
import com.cleanroommc.groovyscript.helper.JsonHelper;
import com.cleanroommc.groovyscript.keybind.GroovyScriptKeybinds;
import com.cleanroommc.groovyscript.mapper.ObjectMapper;
import com.cleanroommc.groovyscript.mapper.ObjectMapperManager;
import com.cleanroommc.groovyscript.network.CReload;
import com.cleanroommc.groovyscript.network.NetworkHandler;
import com.cleanroommc.groovyscript.network.NetworkUtils;
import com.cleanroommc.groovyscript.registry.ReloadableRegistryManager;
import com.cleanroommc.groovyscript.sandbox.*;
import com.cleanroommc.groovyscript.sandbox.mapper.GroovyDeobfMapper;
Expand All @@ -29,19 +28,15 @@
import groovy.lang.GroovySystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.command.ICommandSender;
import net.minecraft.item.Item;
import net.minecraft.util.text.Style;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.client.settings.KeyConflictContext;
import net.minecraftforge.client.settings.KeyModifier;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.RegistryEvent;
import net.minecraftforge.fluids.FluidRegistry;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.ModContainer;
Expand All @@ -51,13 +46,13 @@
import net.minecraftforge.fml.common.event.FMLServerStartingEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent;
import net.minecraftforge.fml.relauncher.FMLLaunchHandler;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.lwjgl.input.Keyboard;

import java.io.File;
import java.io.IOException;
Expand Down Expand Up @@ -95,9 +90,6 @@ public class GroovyScript {
private static ModContainer scriptMod;
private static Thread languageServerThread;

private static KeyBinding reloadKey;
private static long timeSinceLastUse;

public static final Random RND = new Random();

@Mod.EventHandler
Expand All @@ -116,17 +108,18 @@ public void onConstruction(FMLConstructionEvent event) {
}
ModSupport.INSTANCE.setup(event.getASMHarvestedData());

if (NetworkUtils.isDedicatedClient()) {
// this resource pack must be added in construction
((DefaultResourcePackAccessor) Minecraft.getMinecraft()).get().add(new GroovyResourcePack());
reloadKey = new KeyBinding("key.groovyscript.reload", KeyConflictContext.IN_GAME, KeyModifier.CONTROL, Keyboard.KEY_R, "key.categories.groovyscript");
ClientRegistry.registerKeyBinding(reloadKey);
}

FluidRegistry.enableUniversalBucket();
getRunConfig().initPackmode();
}

@Mod.EventHandler
@SideOnly(Side.CLIENT)
public void onClientConstruction(FMLConstructionEvent event) {
MinecraftForge.EVENT_BUS.register(GroovyScriptKeybinds.class);
// this resource pack must be added in construction
((DefaultResourcePackAccessor) Minecraft.getMinecraft()).get().add(new GroovyResourcePack());
}

@Mod.EventHandler
public void onInit(FMLInitializationEvent event) {
if (ModSupport.TINKERS_CONSTRUCT.isLoaded()) TinkersConstruct.init();
Expand All @@ -135,6 +128,12 @@ public void onInit(FMLInitializationEvent event) {
}
}

@Mod.EventHandler
@SideOnly(Side.CLIENT)
public void onClientInit(FMLInitializationEvent event) {
GroovyScriptKeybinds.initialize();
}

@SubscribeEvent(priority = EventPriority.LOWEST)
public void onRegisterItem(RegistryEvent.Register<Item> event) {
if (ModSupport.TINKERS_CONSTRUCT.isLoaded()) TinkersConstruct.preInit();
Expand Down Expand Up @@ -207,15 +206,6 @@ public void onServerLoad(FMLServerStartingEvent event) {
event.registerServerCommand(new GSCommand());
}

@SubscribeEvent
public static void onInput(InputEvent.KeyInputEvent event) {
long time = Minecraft.getSystemTime();
if (Minecraft.getMinecraft().isIntegratedServerRunning() && reloadKey.isPressed() && time - timeSinceLastUse >= 1000 && Minecraft.getMinecraft().player.getPermissionLevel() >= 4) {
NetworkHandler.sendToServer(new CReload());
timeSinceLastUse = time;
}
}

@NotNull
public static String getScriptPath() {
return getScriptFile().getPath();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package com.cleanroommc.groovyscript.api.jeiremoval;

import com.cleanroommc.groovyscript.api.jeiremoval.operations.IOperation;
import com.cleanroommc.groovyscript.api.jeiremoval.operations.ISlotOperation;
import com.cleanroommc.groovyscript.compat.mods.jei.removal.OperationHandler;
import mezz.jei.api.gui.IRecipeLayout;
import org.jetbrains.annotations.NotNull;

import java.util.Collection;
import java.util.List;

/**
* Interface that should be implemented on {@link com.cleanroommc.groovyscript.api.INamed} registries,
* primarily those that would be iterated through as part of {@link com.cleanroommc.groovyscript.compat.mods.ModSupport#getAllContainers()},
* and contains methods indicating what JEI Categories the given registry represents
* and how to remove those recipes.
* <p>
* Primarily interacted with by {@link com.cleanroommc.groovyscript.compat.mods.jei.removal.JeiRemovalHelper#getRemovalMethod(String, IRecipeLayout)}.
* <p>
* In most cases, classes should implement {@link Default} instead of directly implementing {@link IJEIRemoval}.
*
* @see Default
*/
public interface IJEIRemoval {

/**
* A list containing any number of strings which
* are the UIDs of a JEI recipe category {@link mezz.jei.api.recipe.IRecipeCategory#getUid()}.
* <br>
* This list is typically immutable.
*
* @return a list of all UIDs associated with the target recipe category
*/
@NotNull
Collection<String> getCategories();

/**
* Generates one or more removal methods for the targeted recipe, if possible,
* using the information from JEI to do so.
* <p>
* If possible, the first removal method should only remove a single recipe,
* but this is not required and may not be possible.
* <p>
* The path to the recipe will automatically be generated before each entry, only the method name and its parameters should be returned.
* <p>
* Any empty list should be returned if generating a removal method is not possible.
*
* @param layout a map of type to group of slots displayed in JEI
* @return a collection of all generated method to remove the targeted recipe
*/
@NotNull
List<String> getRemoval(IRecipeLayout layout);

/**
* Has a default removal method, {@link #getRemoval(IRecipeLayout)},
* which returns a method to remove the recipe for each input and output.
* <p>
* If changing the operations interacted with is required, implementations should generally override
* the {@link #getJEIOperations()} method instead of {@link #getRemoval(IRecipeLayout)}.
*/
interface Default extends IJEIRemoval {

/**
* A shorthand method that modifies the default operations so each
* of the default operations includes the provided slots.
* <p>
* Should be used inside {@link #getJEIOperations()} to provide the return value.
*
* @param included all slots to be included
* @return a list if operations with the given slots included
* @see OperationHandler#defaultOperations()
*/
static List<IOperation> includeSlots(int... included) {
var operations = OperationHandler.defaultOperations();
for (var operation : operations) {
if (operation instanceof ISlotOperation<?> op) op.include(included);
}
return operations;
}

/**
* A shorthand method that modifies the default operations so each
* of the default operations excludes the provided slots.
* <p>
* Should be used inside {@link #getJEIOperations()} to provide the return value.
*
* @param excluded all slots to be excluded
* @return a list if operations with the given slots excluded
* @see OperationHandler#defaultOperations()
*/
static List<IOperation> excludeSlots(int... excluded) {
var operations = OperationHandler.defaultOperations();
for (var operation : operations) {
if (operation instanceof ISlotOperation<?> op) op.exclude(excluded);
}
return operations;
}

/**
* Calls {@link OperationHandler#removalOptions(IRecipeLayout, List)} with the output of {@link #getJEIOperations()}.\
* <p>
* In almost all cases, this should not be overridden and
* {@link #getJEIOperations()} should be manipulated instead.
*
* @see OperationHandler#removalOptions(IRecipeLayout, List)
*/
@Override
default @NotNull List<String> getRemoval(IRecipeLayout layout) {
return OperationHandler.removalOptions(layout, getJEIOperations());
}

/**
* Gets the desired operations that will be parsed through with the target {@link IRecipeLayout}.
* <p>
* Should be overridden to modify the excluded slots, override incorrectly labeled input or output slots,
* or to override the names of the methods.
*
* @return a list of operations to process
* @see OperationHandler#defaultOperations()
* @see OperationHandler#removalOptions(IRecipeLayout, List)
*/
default @NotNull List<IOperation> getJEIOperations() {
return OperationHandler.defaultOperations();
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.cleanroommc.groovyscript.api.jeiremoval.operations;

import mezz.jei.api.gui.IGuiIngredient;

import javax.annotation.ParametersAreNonnullByDefault;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* Abstract class containing the basic logic for input and output slots, what slots are excluded,
* and what method name should be used for a given slot.
*/
@ParametersAreNonnullByDefault
public abstract class BaseSlotOperation<T> implements ISlotOperation<BaseSlotOperation<T>> {

private static final String DEFAULT_INPUT_METHOD_NAME = "removeByInput";
private static final String DEFAULT_OUTPUT_METHOD_NAME = "removeByOutput";

protected final List<Integer> included = new ArrayList<>();
protected final List<Integer> excluded = new ArrayList<>();
protected final List<Integer> reallyInputs = new ArrayList<>();
protected final List<Integer> reallyOutputs = new ArrayList<>();
protected String inputMethodName = DEFAULT_INPUT_METHOD_NAME;
protected String outputMethodName = DEFAULT_OUTPUT_METHOD_NAME;

@Override
public BaseSlotOperation<T> include(int... ints) {
for (var i : ints) this.included.add(i);
return this;
}

@Override
public BaseSlotOperation<T> exclude(int... ints) {
for (var i : ints) this.excluded.add(i);
return this;
}

@Override
public BaseSlotOperation<T> input(int... ints) {
for (var i : ints) this.reallyInputs.add(i);
return this;
}

@Override
public BaseSlotOperation<T> output(int... ints) {
for (var i : ints) this.reallyOutputs.add(i);
return this;
}

@Override
public BaseSlotOperation<T> input(String name) {
this.inputMethodName = name;
return this;
}

@Override
public BaseSlotOperation<T> output(String name) {
this.outputMethodName = name;
return this;
}

/**
* Checks if the slot should be skipped.
* If the slot has no ingredients it is automatically skipped.
* If {@link #included} is empty, checks the {@link #excluded} list and if the slot contains no ingredients.
* Otherwise, if the slot is a member of the {@link #included} list the provided slot will be included.
*
* @param slot the entry slot being parsed
* @return if the slot should be ignored
*/
protected boolean isIgnored(Map.Entry<Integer, ? extends IGuiIngredient<T>> slot) {
if (slot.getValue().getAllIngredients().isEmpty()) return true;
return this.included.isEmpty() ? this.excluded.contains(slot.getKey()) : !this.included.contains(slot.getKey());
}

/**
* Checks if the slot should be considered an input slot.
* By default, checks the {@link #reallyInputs} list for overrides, then if the slot is marked as an input.
*
* @param slot the entry slot being parsed
* @return if the slot is an input
*/
protected boolean isInput(Map.Entry<Integer, ? extends IGuiIngredient<T>> slot) {
return this.reallyInputs.contains(slot.getKey()) || slot.getValue().isInput();
}


/**
* Checks if the slot should be considered an output slot.
* By default, checks the {@link #reallyOutputs} list for overrides, then if the slot is an input via {@link #isInput(Map.Entry)}.
*
* @param slot the entry slot being parsed
* @return if the slot is an output
*/
protected boolean isOutput(Map.Entry<Integer, ? extends IGuiIngredient<T>> slot) {
return this.reallyOutputs.contains(slot.getKey()) || !isInput(slot);
}

/**
* @param slot the entry slot being parsed
* @return the method name used to represent the slot
*/
protected String getMethod(Map.Entry<Integer, ? extends IGuiIngredient<T>> slot) {
return isOutput(slot) ? this.outputMethodName : this.inputMethodName;
}

}
Loading