/
RecipeUtil.java
167 lines (149 loc) · 5.72 KB
/
RecipeUtil.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
package knightminer.inspirations.library.util;
import java.util.function.Consumer;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.NonNullList;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.oredict.OreDictionary;
public final class RecipeUtil {
private static final Logger log = LogManager.getLogger("inspirations-lib");
private RecipeUtil() {}
/**
* Checks if the string is valid to be parsed using {@link #getItemStackFromString(String, boolean)}
* @param string Input string
* @param allowWildcard If true, -1 will be a valid metadata to use as wildcard
* @return True if the string is valid to parse with
*/
public static boolean isValidItemStack(String string, boolean allowWildcard) {
String metaString = allowWildcard ? "(-1|[0-9]+)" : "[0-9]+";
return string.matches("^[a-z0-9_.-]+:[a-z0-9_.-]+(:" + metaString + ")?$");
}
/**
* Parses an itemstack from a string in the format of "modid:item[:meta]"
* @param string Input string
* @param allowWildcard If true, -1 will be a valid metadata to use as a wildcard.
* Additionally, changes the default metadata to wildcard instead of 0
* @return ItemStack parsed from the string, or EMPTY if it is either an invalid string or the item cannot be found.
* Use (@link {@link #isValidItemStack(String, boolean)} if you need to determine if a string is valid without the item being found
*/
public static ItemStack getItemStackFromString(String string, boolean allowWildcard) {
if(!isValidItemStack(string, allowWildcard)) {
log.warn("Invalid stack string {}", string);
return ItemStack.EMPTY;
}
String[] parts = string.split(":");
Item item = GameRegistry.findRegistry(Item.class).getValue(new ResourceLocation(parts[0], parts[1]));
if(item == null || item == Items.AIR) {
log.debug("Failed to find stack {}", string);
return ItemStack.EMPTY;
}
int meta = allowWildcard ? -1 : 0;
if(parts.length > 2) {
// already validated above
meta = Integer.parseInt(parts[2]);
}
if(meta == -1) {
meta = OreDictionary.WILDCARD_VALUE;
}
return new ItemStack(item, 1, meta);
}
/**
* Runs the provided callback on all itemstacks obtained from the given stack string
* @param string Input string in the format of "modid:item[:meta]". Treats no meta as wildcard
* @param callback Callback function to run for all stacks
*/
public static void forStackInString(String string, Consumer<ItemStack> callback) {
ItemStack stack = getItemStackFromString(string, true);
if(stack.isEmpty()) {
return;
}
// if wildcard, run all stacks
if(stack.getMetadata() == OreDictionary.WILDCARD_VALUE) {
NonNullList<ItemStack> subItems = NonNullList.create();
stack.getItem().getSubItems(CreativeTabs.SEARCH, subItems);
for(ItemStack subStack : subItems) {
callback.accept(subStack);
}
} else {
callback.accept(stack);
}
}
/**
* Gets a block and meta from a string
* @param string Input string in the format "modid:block[:meta]"
* @return Pair of block and meta, or block and null if meta is unspecified or -1. Null if errored
*/
private static Pair<Block, Integer> getBlockFromString(String string) {
if(!isValidItemStack(string, false)) {
log.warn("Invalid block string {}", string);
return null;
}
String[] parts = string.split(":");
Block block = GameRegistry.findRegistry(Block.class).getValue(new ResourceLocation(parts[0], parts[1]));
if(block == null || block == Blocks.AIR) {
log.debug("Failed to find block {}", string);
return null;
}
Integer meta = null;
if(parts.length > 2) {
// already validated above
meta = Integer.parseInt(parts[2]);
if(meta == -1) {
meta = null;
}
}
return Pair.of(block, meta);
}
/**
* Returns a blockstate from the given string
* @param string Input string, in the form "modid:block[:meta]". If meta is unset or -1 it returns the default state
* @return Block state for the given string
*/
@SuppressWarnings("deprecation")
public static IBlockState getBlockStateFromString(String string) {
Pair<Block, Integer> pair = getBlockFromString(string);
if(pair == null) {
return null;
}
if(pair.getRight() == null) {
return pair.getLeft().getDefaultState();
} else {
return pair.getLeft().getStateFromMeta(pair.getRight());
}
}
/**
* Runs the given callback on all states returned by the block state string
* @param string Input string in the format "modid:block[:meta]"
* @param stateConsumer Callback for block state results
* @param blockConsumer Callback for block results. If null, runs the state consumer on all possible block states
*/
@SuppressWarnings("deprecation")
public static void forBlockInString(String string, Consumer<IBlockState> stateConsumer, Consumer<Block> blockConsumer) {
Pair<Block, Integer> pair = getBlockFromString(string);
if(pair == null) {
return;
}
if(pair.getRight() == null) {
// if we have no metadata and no block consumer, run the state consumer on all valid states
if(blockConsumer == null) {
for(IBlockState state : pair.getLeft().getBlockState().getValidStates()) {
stateConsumer.accept(state);
}
} else {
// if there is a block consumer use that
blockConsumer.accept(pair.getLeft());
}
} else {
stateConsumer.accept(pair.getLeft().getStateFromMeta(pair.getRight()));
}
}
}