-
Notifications
You must be signed in to change notification settings - Fork 2
Block Predicates
DataPack Anvil provide Advanced block predicates that can be serialized in datapacks. They all inherit from the IBlockPosPredicate.
The Interface provide the IBlockPosPredicate#test(IWorldReader, BlockPos) that allow us to check if the block at those coordinates match our predicate.
Lets take back the example we use in Data Manager, here is our data with a predicate:
public class MyData {
private String stringValue;
private int integerValue;
private IBlockPosPredicate predicate;
// getters and setters...
}But we still need to serialize and deserialize it.
If you are working with codecs you ca simply use the block predicate codec IBlockPosPredicate#CODEC.
If you are using serializer there are 4 methods in IBlockPosPredicate to serialize and deserialize a predicate to json and PacketBuffer.
JsonElement write()write(PacketBuffer)IBlockPosPredicate read(JsonElement)IBlockPosPredicate read(PacketBuffer)
With our example it will look like this:
private void enqueueIMC(InterModEnqueueEvent event) {
DataManagerIMC.enqueue(() -> new DataManagerIMC<>((new ResourceLoaction("mymod", "mydata"), MY_DATA_MANAGER).withSerializer(
json -> {
MyData myData = new MyData();
myData.setStringValue(JSONUtils.getString(json, "stringValue"));
myData.setIntegerValue(JSONUtils.getInt(json, "integerValue"));
myData.setPredicate(IBlockPosPredicate.read(json.get("predicate")));
return myData;
}, buf -> {
MyData myData = new MyData();
myData.setStringValue(buf.readString());
myData.setIntegerValue(buf.readInt());
myData.setPredicate(IBlockPosPredicate.read(buf));
return myData;
}, (buf, myData) -> {
buf.writeString(myData.getStringValue());
buf.writeInt(myData.getIntegerValue());
myData.getPredicate().write(buf);
}));
}Block predicates offers a few methods to create them using logic operators. This includes:
-
notto get thin inverse of the current predicate -
andto create an and operation between multiple predicates -
orto create an or operation between multiple predicates -
matchcan take aBlock, an array ofBlock, aITag<Block>or aBlockState. this will gives you a predicate that check if a block match the corresponding argument.
A few block predicates are already present:
This predicate always return true.
Example:
{
"type": "dpanvil:any"
}
This predicate always return false.
Example:
{
"type": "dpanvil:none"
}
This predicate is true if all the predicates it contains are true.
Example:
{
"type": "dpanvil:and",
"values": [
...
]
}
This predicate is true if any predicate it contains is true.
Example:
{
"type": "dpanvil:or",
"values": [
...
]
}
This predicate is true if the predicate it contains is false.
Example:
{
"type": "dpanvil:not",
"value": {
...
}
}
This predicate is true if the tested block match its block.
Example:
{
"type": "dpanvil:block",
"block": "minecraft:stone"
}
This predicate is true if the tested block match one of its blocks.
Example:
{
"type": "dpanvil:blocks",
"block": [
"minecraft:stone",
"minecraft:dirt"
]
}
This predicate is true if its tag contains the tested block.
Example:
{
"type": "dpanvil:tag",
"tag": "minecraft:planks"
}
This predicate is true if its blockstate match the tested blockstate.
BlockStates can be found here: https://minecraft.gamepedia.com/Block_states
Example:
{
"type": "dpanvil:blockstate",
"Name": "minecraft:wheat",
"Properties": [
...
]
}
You can create your own implementation of IBlockPostPredicate for your own needs. you only need to implement two methods:
-
test: called when you want to test if this predicate is true or false -
getType: return the type of predicate (can be retrieved using an@ObjectHolder)
Then you need to add it to the BlockPosPredicateType forge registry:
@SubscribeEvent
public static void registerBlockPosPredicateSerializers(RegistryEvent.Register<BlockPosPredicateType<?>> event) {
IForgeRegistry<BlockPosPredicateType<?>> registry = event.getRegistry();
registry.register(new BlockPosPredicateType<>(MyPredicate.CODEC).setRegistryName(new ResourceLocation("mymod", "my_predicate"));
}Note: you need to use a codec, take a look here for useful links on how codecs work.