Skip to content

Commit 86f371f

Browse files
authored
add FutureMC Composter compat (#308)
* add composter compat * make bonemeal invalid * 8 layers not 7, whoops
1 parent 9786b26 commit 86f371f

File tree

4 files changed

+152
-0
lines changed

4 files changed

+152
-0
lines changed

examples/postInit/futuremc.groovy

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,23 @@ mods.futuremc.campfire.recipeBuilder()
4242
.register()
4343

4444

45+
// Composter:
46+
// Converts input items into a chance to get a layer of compost, with 8 layers providing a single bonemeal.
47+
48+
mods.futuremc.composter.removeByInput(item('minecraft:cactus'))
49+
// mods.futuremc.composter.removeAll()
50+
51+
mods.futuremc.composter.recipeBuilder()
52+
.input(item('minecraft:clay'))
53+
.chance(100)
54+
.register()
55+
56+
mods.futuremc.composter.recipeBuilder()
57+
.input(item('minecraft:gold_ingot'))
58+
.chance(30)
59+
.register()
60+
61+
4562
// Smithing:
4663
// Converts two input itemstacks into an output output itemstack in the Smithing Table.
4764

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package com.cleanroommc.groovyscript.compat.mods.futuremc;
2+
3+
import com.cleanroommc.groovyscript.api.GroovyBlacklist;
4+
import com.cleanroommc.groovyscript.api.GroovyLog;
5+
import com.cleanroommc.groovyscript.api.IIngredient;
6+
import com.cleanroommc.groovyscript.api.documentation.annotations.*;
7+
import com.cleanroommc.groovyscript.compat.mods.ModSupport;
8+
import com.cleanroommc.groovyscript.helper.SimpleObjectStream;
9+
import com.cleanroommc.groovyscript.helper.recipe.AbstractRecipeBuilder;
10+
import com.cleanroommc.groovyscript.registry.VirtualizedRegistry;
11+
import it.unimi.dsi.fastutil.objects.Object2ByteMap;
12+
import net.minecraft.init.Items;
13+
import net.minecraft.item.ItemStack;
14+
import net.minecraft.item.crafting.Ingredient;
15+
import org.apache.commons.lang3.tuple.Pair;
16+
import org.jetbrains.annotations.ApiStatus;
17+
import org.jetbrains.annotations.Nullable;
18+
import thedarkcolour.futuremc.block.villagepillage.ComposterBlock;
19+
20+
import java.util.Arrays;
21+
import java.util.Map;
22+
23+
@RegistryDescription(category = RegistryDescription.Category.ENTRIES)
24+
public class Composter extends VirtualizedRegistry<Map.Entry<Ingredient, Byte>> {
25+
26+
@Override
27+
@GroovyBlacklist
28+
@ApiStatus.Internal
29+
public void onReload() {
30+
var instance = ComposterBlock.ItemsForComposter.INSTANCE;
31+
var entries = instance.getEntries();
32+
removeScripted().forEach(entry -> entries.removeIf(entry.getKey()::equals));
33+
restoreFromBackup().forEach(x -> instance.add(x.getKey(), x.getValue()));
34+
}
35+
36+
@RecipeBuilderDescription(example = {
37+
@Example(".input(item('minecraft:clay')).chance(100)"),
38+
@Example(".input(item('minecraft:gold_ingot')).chance(30)")
39+
})
40+
public RecipeBuilder recipeBuilder() {
41+
return new RecipeBuilder();
42+
}
43+
44+
@MethodDescription(type = MethodDescription.Type.ADDITION)
45+
public boolean add(IIngredient input, byte chance) {
46+
if (input == null) return false;
47+
return add(input.toMcIngredient(), chance);
48+
}
49+
50+
@MethodDescription(type = MethodDescription.Type.ADDITION)
51+
public boolean add(Ingredient input, byte chance) {
52+
if (input == null) return false;
53+
ComposterBlock.ItemsForComposter.INSTANCE.add(input, chance);
54+
return doAddScripted(Pair.of(input, chance));
55+
}
56+
57+
@MethodDescription
58+
public boolean remove(IIngredient input) {
59+
if (input == null) return false;
60+
return remove(input.toMcIngredient());
61+
}
62+
63+
@MethodDescription
64+
public boolean remove(Ingredient input) {
65+
return input != null && ComposterBlock.ItemsForComposter.INSTANCE.getEntries().removeIf(r -> r == input && doAddBackup(Pair.of(input, r.getByteValue())));
66+
}
67+
68+
@MethodDescription(example = @Example("item('minecraft:cactus')"))
69+
public void removeByInput(IIngredient input) {
70+
ComposterBlock.ItemsForComposter.INSTANCE.getEntries().removeIf(r -> Arrays.stream(r.getKey().getMatchingStacks()).anyMatch(input) && doAddBackup(r));
71+
}
72+
73+
@MethodDescription(priority = 2000, example = @Example(commented = true))
74+
public void removeAll() {
75+
var recipes = ComposterBlock.ItemsForComposter.INSTANCE.getEntries();
76+
recipes.forEach(this::addBackup);
77+
recipes.clear();
78+
}
79+
80+
@MethodDescription(type = MethodDescription.Type.QUERY)
81+
public SimpleObjectStream<Object2ByteMap.Entry<Ingredient>> streamRecipes() {
82+
return new SimpleObjectStream<>(ComposterBlock.ItemsForComposter.INSTANCE.getEntries()).setRemover(x -> remove(x.getKey()));
83+
}
84+
85+
@Property(property = "input", comp = @Comp(eq = 1))
86+
public static class RecipeBuilder extends AbstractRecipeBuilder<Pair<Ingredient, Byte>> {
87+
88+
private static final ItemStack BONE_MEAL = new ItemStack(Items.DYE, 1, 15);
89+
90+
@Property(comp = @Comp(gte = 0, lte = 100))
91+
private int chance;
92+
93+
@RecipeBuilderMethodDescription
94+
public RecipeBuilder chance(int chance) {
95+
this.chance = chance;
96+
return this;
97+
}
98+
99+
@Override
100+
protected int getMaxItemInput() {
101+
return 1;
102+
}
103+
104+
@Override
105+
public String getErrorMsg() {
106+
return "Error adding FutureMC Composter recipe";
107+
}
108+
109+
@Override
110+
public void validate(GroovyLog.Msg msg) {
111+
validateItems(msg, 1, 1, 0, 0);
112+
validateFluids(msg);
113+
if (!input.isEmpty()) msg.add(input.get(0).test(BONE_MEAL), "the input item cannot match bonemeal, yet it was {}", input.get(0));
114+
msg.add(chance < 0 || chance > 100, "chance must be greater than or equal to 0 and less than or equal to 100, yet it was {}", chance);
115+
}
116+
117+
@Override
118+
@RecipeBuilderRegistrationMethod
119+
public @Nullable Pair<Ingredient, Byte> register() {
120+
if (!validate()) return null;
121+
// can be safely cast to a byte due to always being between 0-100
122+
ComposterBlock.ItemsForComposter.INSTANCE.add(input.get(0).toMcIngredient(), (byte) chance);
123+
var entry = Pair.of(input.get(0).toMcIngredient(), (byte) chance);
124+
ModSupport.FUTURE_MC.get().composter.addBackup(entry);
125+
return entry;
126+
}
127+
}
128+
}

src/main/java/com/cleanroommc/groovyscript/compat/mods/futuremc/FutureMC.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ public class FutureMC extends GroovyPropertyContainer {
66

77
public final BlastFurnace blastFurnace = new BlastFurnace();
88
public final Campfire campfire = new Campfire();
9+
public final Composter composter = new Composter();
910
public final Smithing smithing = new Smithing();
1011
public final Smoker smoker = new Smoker();
1112
public final Stonecutter stonecutter = new Stonecutter();

src/main/resources/assets/groovyscript/lang/en_us.lang

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,6 +1430,12 @@ groovyscript.wiki.futuremc.campfire.title=Campfire
14301430
groovyscript.wiki.futuremc.campfire.description=Converts an input itemstack into an output itemstack when placed on the Campfire.
14311431
groovyscript.wiki.futuremc.campfire.duration.value=Sets the time in ticks the takes to process
14321432

1433+
groovyscript.wiki.futuremc.composter.title=Composter
1434+
groovyscript.wiki.futuremc.composter.description=Converts input items into a chance to get a layer of compost, with 8 layers providing a single bonemeal
1435+
groovyscript.wiki.futuremc.composter.add=Adds entries in the format `ingredient`, `chance`
1436+
groovyscript.wiki.futuremc.composter.remove=Removes an entry with the same Ingredient
1437+
groovyscript.wiki.futuremc.composter.rarity.value=Sets the chance the recipe has to provide a layer of compost
1438+
14331439
groovyscript.wiki.futuremc.smithing.title=Smithing
14341440
groovyscript.wiki.futuremc.smithing.description=Converts two input itemstacks into an output output itemstack in the Smithing Table.
14351441
groovyscript.wiki.futuremc.smithing.note0=Crafting with stackable items may require picking up and placing an input to allow crafting the recipe again.

0 commit comments

Comments
 (0)