Skip to content

Ore Ingredient Changes #310

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

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions examples/postInit/immersiveengineering.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ mods.immersiveengineering.blueprint_crafting.recipeBuilder()
.register()


mods.immersiveengineering.blueprint_crafting.streamRecipesByCategory('molds')

// Bottling Machine:
// Converts an input itemstack and fluidstack into an output itemstack.

Expand Down
5 changes: 5 additions & 0 deletions examples/postInit/minecraft.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,11 @@ mods.minecraft.ore_dict.remove('netherStar', item('minecraft:nether_star'))
mods.minecraft.ore_dict.add('ingotGold', item('minecraft:nether_star'))
mods.minecraft.ore_dict.add('netherStar', item('minecraft:gold_ingot'))

mods.minecraft.ore_dict.getOres(~/.*/)
mods.minecraft.ore_dict.getOres(~/.*Gold/)
mods.minecraft.ore_dict.getOres(~/.*or.*/)
mods.minecraft.ore_dict.getOres('ingot*')

// Starting Inventory:
// Sets the starting inventory of the player, including armor slots and offhand.

Expand Down
13 changes: 8 additions & 5 deletions src/main/java/com/cleanroommc/groovyscript/api/IOreDicts.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
package com.cleanroommc.groovyscript.api;

import java.util.List;
import org.jetbrains.annotations.UnmodifiableView;

import java.util.Collection;

/**
* Indicates that the IIngredient represents one or more oredicts.
* Indicates something that represents one or more oredicts, typically an {@link IIngredient}.
*/
public interface IOreDicts extends IIngredient {
public interface IOreDicts {
// TODO
// There are a large number of places currently in the GroovyScript codebase
// that check if something is "instanceof OreDictIngredient".
// these should be replaced by checks against IOreDicts,
// and surrounding code changed appropriately.

/**
* @return a list of oredict strings
* @return a collection of oredict strings
*/
List<String> getOreDicts();
@UnmodifiableView
Collection<String> getOreDicts();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import com.cleanroommc.groovyscript.api.GroovyBlacklist;
import com.cleanroommc.groovyscript.api.GroovyLog;
import com.cleanroommc.groovyscript.api.IIngredient;
import com.cleanroommc.groovyscript.api.documentation.annotations.Example;
import com.cleanroommc.groovyscript.api.documentation.annotations.MethodDescription;
import com.cleanroommc.groovyscript.api.documentation.annotations.RegistryDescription;
import com.cleanroommc.groovyscript.core.mixin.OreDictionaryAccessor;
import com.cleanroommc.groovyscript.helper.Alias;
import com.cleanroommc.groovyscript.helper.SimpleObjectStream;
import com.cleanroommc.groovyscript.helper.ingredient.IngredientHelper;
import com.cleanroommc.groovyscript.helper.ingredient.OreDictMatcherIngredient;
import com.cleanroommc.groovyscript.registry.VirtualizedRegistry;
import net.minecraft.block.Block;
import net.minecraft.item.Item;
Expand All @@ -18,6 +21,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

@RegistryDescription(category = RegistryDescription.Category.ENTRIES)
public class OreDict extends VirtualizedRegistry<OreDictEntry> {
Expand Down Expand Up @@ -150,4 +154,23 @@ public void removeAll() {
}
}
}

@MethodDescription(type = MethodDescription.Type.QUERY)
public SimpleObjectStream<String> streamOreNames() {
return new SimpleObjectStream<>(OreDictionaryAccessor.getIdToName()).setRemover(this::removeAll);
}

@MethodDescription(type = MethodDescription.Type.QUERY, example = @Example("'ingot*'"))
public IIngredient getOres(String pattern) {
return new OreDictMatcherIngredient(pattern);
}

@MethodDescription(type = MethodDescription.Type.QUERY, example = {
@Example("~/.*Gold/"),
@Example("~/.*or.*/"),
@Example("~/.*/"),
})
public IIngredient getOres(Pattern pattern) {
return new OreDictMatcherIngredient(pattern);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ public String exampleBlock() {
}
out.append(documentMethodDescriptionType(MethodDescription.Type.ADDITION));
out.append(documentMethodDescriptionType(MethodDescription.Type.VALUE));
out.append(documentMethodDescriptionType(MethodDescription.Type.QUERY));
return out.toString();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ public static IIngredient toIIngredient(FluidStack fluidStack) {
public static @NotNull List<List<Object>> cartesianProductOres(@NotNull List<IIngredient> inputs) {
List<List<?>> entries = new ArrayList<>();
for (var input : inputs) {
if (input instanceof IOreDicts ore) entries.add(ore.getOreDicts());
if (input instanceof IOreDicts ore) entries.add(new ArrayList<>(ore.getOreDicts()));
else entries.add(Arrays.asList(input.getMatchingStacks()));
}
return Lists.cartesianProduct(entries);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

public class ItemsIngredient extends IngredientBase implements Iterable<ItemStack> {

Expand Down Expand Up @@ -85,11 +84,6 @@ public boolean matches(ItemStack itemStack) {
return false;
}

// protected since modifying un-copied stack directly can result in unexpected results
protected List<ItemStack> getItemStacks() {
return Collections.unmodifiableList(this.itemStacks);
}

@Override
public @NotNull Iterator<ItemStack> iterator() {
return new AbstractIterator<>() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,45 +2,111 @@

import com.cleanroommc.groovyscript.api.IOreDicts;
import com.cleanroommc.groovyscript.compat.vanilla.VanillaModule;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.ImmutableList;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.Ingredient;
import net.minecraftforge.oredict.OreDictionary;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.UnmodifiableView;

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

public class OreDictIngredient extends ItemsIngredient implements Iterable<ItemStack>, IOreDicts {
public class OreDictIngredient extends IngredientBase implements Iterable<ItemStack>, IOreDicts {

private final String oreDict;
private int amount = 1;

public OreDictIngredient(String oreDict) {
super(OreDictionary.getOres(oreDict));
this.oreDict = oreDict;
}

// fast copy
private OreDictIngredient(String oreDict, List<ItemStack> itemStacks) {
super(itemStacks);
this.oreDict = oreDict;
private static ItemStack selectItemStack(List<ItemStack> stacks, int index, int amount) {
if (amount == 0 || stacks.isEmpty() || stacks.size() < index) return ItemStack.EMPTY;
ItemStack stack = stacks.get(index).copy();
stack.setCount(amount);
return stack;
}

public String getOreDict() {
return oreDict;
}

@Override
public List<String> getOreDicts() {
public @UnmodifiableView Collection<String> getOreDicts() {
return ImmutableList.of(getOreDict());
}

@Override
public OreDictIngredient exactCopy() {
OreDictIngredient oreDictIngredient = new OreDictIngredient(this.oreDict, getItemStacks());
oreDictIngredient.setAmount(getAmount());
OreDictIngredient oreDictIngredient = new OreDictIngredient(this.oreDict);
oreDictIngredient.amount = amount;
oreDictIngredient.transformer = transformer;
oreDictIngredient.matchCondition = matchCondition;
return oreDictIngredient;
}

@Override
public Ingredient toMcIngredient() {
return Ingredient.fromStacks(getMatchingStacks());
}

@Override
public ItemStack[] getMatchingStacks() {
var stacks = getItemStacks();
ItemStack[] output = new ItemStack[stacks.size()];
for (int i = 0; i < output.length; i++) {
output[i] = selectItemStack(stacks, i, amount);
}
return output;
}

@Override
public ItemStack getAt(int index) {
return selectItemStack(getItemStacks(), index, amount);
}

@Override
public int getAmount() {
return getItemStacks().isEmpty() ? 0 : amount;
}

@Override
public void setAmount(int amount) {
this.amount = Math.max(0, amount);
}

@Override
public boolean matches(ItemStack itemStack) {
for (ItemStack itemStack1 : getItemStacks()) {
if (OreDictionary.itemMatches(itemStack1, itemStack, false)) {
return true;
}
}
return false;
}

private List<ItemStack> getItemStacks() {
return OreDictionary.getOres(oreDict);
}

@Override
public @NotNull Iterator<ItemStack> iterator() {
return new AbstractIterator<>() {

private int index = 0;

@Override
protected ItemStack computeNext() {
var stacks = getItemStacks();
if (index >= stacks.size()) return endOfData();
return selectItemStack(stacks, index++, amount);
}
};
}

@Override
public String toString() {
return "OreDictIngredient{ " + oreDict + " } * " + getAmount();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package com.cleanroommc.groovyscript.helper.ingredient;

import com.cleanroommc.groovyscript.api.IIngredient;
import com.cleanroommc.groovyscript.api.IOreDicts;
import com.cleanroommc.groovyscript.core.mixin.OreDictionaryAccessor;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import net.minecraft.item.ItemStack;
import net.minecraft.item.crafting.Ingredient;
import net.minecraftforge.oredict.OreDictionary;
import org.jetbrains.annotations.UnmodifiableView;

import java.util.Collection;
import java.util.regex.Pattern;

public class OreDictMatcherIngredient extends IngredientBase implements IOreDicts {

private static final Pattern WILDCARD = Pattern.compile("\\*");

private final Collection<String> oreDicts;
private final ItemStackList itemStacks;
private final Pattern pattern;
private int amount = 1;

public OreDictMatcherIngredient(String pattern) {
this(Pattern.compile(WILDCARD.matcher(pattern).replaceAll(".*")));
}

public OreDictMatcherIngredient(Pattern pattern) {
this.pattern = pattern;
this.oreDicts = new ObjectOpenHashSet<>();
this.itemStacks = new ItemStackList();
generate();
}

private OreDictMatcherIngredient(Pattern pattern, Collection<String> oreDicts, ItemStackList itemStacks) {
this.pattern = pattern;
this.oreDicts = new ObjectOpenHashSet<>(oreDicts);
this.itemStacks = new ItemStackList(itemStacks);
}

private void generate() {
for (var ore : OreDictionaryAccessor.getIdToName()) {
if (pattern.matcher(ore).matches() && oreDicts.add(ore)) {
itemStacks.addAll(OreDictionary.getOres(ore));
}
}
}

@Override
public IIngredient exactCopy() {
var ingredient = new OreDictMatcherIngredient(pattern, oreDicts, itemStacks);
ingredient.amount = amount;
ingredient.transformer = transformer;
ingredient.matchCondition = matchCondition;
return ingredient;
}

@Override
public Ingredient toMcIngredient() {
return Ingredient.fromStacks(getMatchingStacks());
}

@Override
public ItemStack[] getMatchingStacks() {
ItemStack[] stacks = new ItemStack[itemStacks.size()];
for (int i = 0; i < stacks.length; i++) {
stacks[i] = getAt(i);
}
return stacks;
}

@Override
public ItemStack getAt(int index) {
ItemStack stack = this.itemStacks.get(index).copy();
stack.setCount(getAmount());
return stack;
}

@Override
public int getAmount() {
return itemStacks.isEmpty() ? 0 : amount;
}

@Override
public void setAmount(int amount) {
this.amount = amount;
}

@Override
public boolean matches(ItemStack itemStack) {
for (ItemStack itemStack1 : itemStacks) {
if (OreDictionary.itemMatches(itemStack1, itemStack, false)) {
return true;
}
}
return false;
}

@Override
public @UnmodifiableView Collection<String> getOreDicts() {
return oreDicts;
}

public OreDictMatcherIngredient regenerate() {
oreDicts.clear();
itemStacks.clear();
generate();
return this;
}
}
Loading