Skip to content

Commit

Permalink
Immersive Engineering Crusher Recipe Secondary Output (#169)
Browse files Browse the repository at this point in the history
* resolve #167

* simplify float array excavator code

* use fastutil FloatArrayList for Crusher and Excavator
  • Loading branch information
WaitingIdly authored Jun 16, 2024
1 parent f88c6dc commit cac58d4
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 9 deletions.
10 changes: 9 additions & 1 deletion examples/postInit/immersiveengineering.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ mods.immersiveengineering.coke_oven.recipeBuilder()


// Crusher:
// Converts an input itemstack into an output itemstack, consuming energy.
// Converts an input itemstack into an output itemstack with optional additional chanced item outputs, consuming energy.

mods.immersiveengineering.crusher.removeByInput(item('immersiveengineering:material:7'))
mods.immersiveengineering.crusher.removeByOutput(item('minecraft:sand'))
Expand All @@ -128,6 +128,14 @@ mods.immersiveengineering.crusher.recipeBuilder()
.energy(100)
.register()

mods.immersiveengineering.crusher.recipeBuilder()
.input(item('minecraft:diamond_block'))
.output(item('minecraft:diamond'))
.secondaryOutput(item('minecraft:gold_ingot'))
.secondaryOutput(item('minecraft:gold_ingot'), 0.3)
.energy(100)
.register()



// Excavator:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,20 @@
import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper;
import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder;
import com.cleanroommc.groovyscript.registry.VirtualizedRegistry;
import it.unimi.dsi.fastutil.floats.FloatArrayList;
import net.minecraft.item.ItemStack;
import org.jetbrains.annotations.Nullable;

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

@RegistryDescription
public class Crusher extends VirtualizedRegistry<CrusherRecipe> {

@RecipeBuilderDescription(example = @Example(".input(item('minecraft:diamond')).output(item('minecraft:clay')).energy(100)"))
@RecipeBuilderDescription(example = {
@Example(".input(item('minecraft:diamond')).output(item('minecraft:clay')).energy(100)"),
@Example(".input(item('minecraft:diamond_block')).output(item('minecraft:diamond')).secondaryOutput(item('minecraft:gold_ingot')).secondaryOutput(item('minecraft:gold_ingot'), 0.3).energy(100)")
})
public static RecipeBuilder recipeBuilder() {
return new RecipeBuilder();
}
Expand Down Expand Up @@ -103,9 +108,25 @@ public void removeAll() {
@Property(property = "output", valid = @Comp("1"))
public static class RecipeBuilder extends AbstractRecipeBuilder<CrusherRecipe> {

@Property(valid = @Comp("secondaryOutputChances"))
private final List<ItemStack> secondaryOutputItems = new ArrayList<>();
@Property(valid = @Comp("secondaryOutputItems"))
private final FloatArrayList secondaryOutputChances = new FloatArrayList();
@Property(valid = @Comp(value = "0", type = Comp.Type.GTE))
private int energy;

@RecipeBuilderMethodDescription(field = {"secondaryOutputItems", "secondaryOutputChances"})
public RecipeBuilder secondaryOutput(ItemStack item) {
return this.secondaryOutput(item, 1);
}

@RecipeBuilderMethodDescription(field = {"secondaryOutputItems", "secondaryOutputChances"})
public RecipeBuilder secondaryOutput(ItemStack item, float chance) {
this.secondaryOutputItems.add(item);
this.secondaryOutputChances.add(chance);
return this;
}

@RecipeBuilderMethodDescription
public RecipeBuilder energy(int energy) {
this.energy = energy;
Expand All @@ -121,6 +142,8 @@ public String getErrorMsg() {
public void validate(GroovyLog.Msg msg) {
validateItems(msg, 1, 1, 1, 1);
validateFluids(msg);
secondaryOutputChances.trim();
msg.add(secondaryOutputItems.size() != secondaryOutputChances.size(), "secondaryOutputItems and secondaryOutputChances must be of equal length, yet secondaryOutputItems was {} and secondaryOutputChances was {}", secondaryOutputItems.size(), secondaryOutputChances.size());
if (energy < 0) energy = 200;
}

Expand All @@ -129,6 +152,11 @@ public void validate(GroovyLog.Msg msg) {
public @Nullable CrusherRecipe register() {
if (!validate()) return null;
CrusherRecipe recipe = new CrusherRecipe(output.get(0), input.get(0), energy);
if (!secondaryOutputItems.isEmpty()) {
recipe.secondaryOutput = secondaryOutputItems.toArray(new ItemStack[0]);
recipe.secondaryChance = secondaryOutputChances.elements();
recipe.getItemOutputs().addAll(secondaryOutputItems);
}
ModSupport.IMMERSIVE_ENGINEERING.get().crusher.add(recipe);
return recipe;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.cleanroommc.groovyscript.helper.ingredient.OreDictIngredient;
import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder;
import com.cleanroommc.groovyscript.registry.VirtualizedRegistry;
import it.unimi.dsi.fastutil.floats.FloatArrayList;
import org.apache.commons.lang3.tuple.Pair;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -142,7 +143,7 @@ public static class RecipeBuilder extends AbstractRecipeBuilder<ExcavatorHandler
@Property(valid = @Comp("chances"))
private final List<String> ores = new ArrayList<>();
@Property(valid = @Comp("ores"))
private final List<Float> chances = new ArrayList<>();
private final FloatArrayList chances = new FloatArrayList();
@Property
private final List<Integer> dimensions = new ArrayList<>();
@Property(ignoresInheritedMethods = true)
Expand Down Expand Up @@ -230,18 +231,15 @@ public void validate(GroovyLog.Msg msg) {
validateItems(msg);
validateFluids(msg);
msg.add(fail < 0 || fail > 1, "fail must be a float between 0 and 1, yet it was {}", fail);
chances.trim();
msg.add(ores.size() != chances.size(), "ores and chances must be of equal length, yet ores was {} and chances was {}", ores.size(), chances.size());
}

@Override
@RecipeBuilderRegistrationMethod
public @Nullable ExcavatorHandler.MineralMix register() {
if (!validate()) return null;
float[] chanceArray = new float[chances.size()];
for (int i = 0; i < chances.size(); i++) {
chanceArray[i] = chances.get(i);
}
ExcavatorHandler.MineralMix recipe = new ExcavatorHandler.MineralMix(name, fail, ores.toArray(new String[0]), chanceArray);
ExcavatorHandler.MineralMix recipe = new ExcavatorHandler.MineralMix(name, fail, ores.toArray(new String[0]), chances.elements());

int[] dims = dimensions.stream().mapToInt(Integer::intValue).toArray();
if (dims != null) {
Expand Down
4 changes: 3 additions & 1 deletion src/main/resources/assets/groovyscript/lang/en_us.lang
Original file line number Diff line number Diff line change
Expand Up @@ -933,9 +933,11 @@ groovyscript.wiki.immersiveengineering.coke_oven.creosote.value=Sets the amount
groovyscript.wiki.immersiveengineering.coke_oven.time.value=Sets the time in ticks the recipe takes to process

groovyscript.wiki.immersiveengineering.crusher.title=Crusher
groovyscript.wiki.immersiveengineering.crusher.description=Converts an input itemstack into an output itemstack, consuming energy.
groovyscript.wiki.immersiveengineering.crusher.description=Converts an input itemstack into an output itemstack with optional additional chanced item outputs, consuming energy.
groovyscript.wiki.immersiveengineering.crusher.add=Adds recipes in the format `output`, `input`, `energy`
groovyscript.wiki.immersiveengineering.crusher.energy.value=Sets the amount of power consumed to complete the recipe
groovyscript.wiki.immersiveengineering.crusher.secondaryOutputItems.value=Sets the additional items output by the recipe, if any
groovyscript.wiki.immersiveengineering.crusher.secondaryOutputChances.value=Sets the chance of the respective additional items output by the recipe

groovyscript.wiki.immersiveengineering.excavator.title=Excavator
groovyscript.wiki.immersiveengineering.excavator.description=Adds a Mineral Mix with the given name, weight, fail chance, ores, and allowed dimensions. A Mineral Mix can be mined by an Excavator Multiblock and scanned via a Core Sample Drill.
Expand Down

0 comments on commit cac58d4

Please sign in to comment.