package net.minecraft.data.models.blockstates; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.google.common.collect.ImmutableList.Builder; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.mojang.datafixers.util.Pair; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.stream.Stream; import net.minecraft.Util; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.properties.Property; public class MultiVariantGenerator implements BlockStateGenerator { private final Block block; private final List baseVariants; private final Set> seenProperties = Sets.>newHashSet(); private final List declaredPropertySets = Lists.newArrayList(); private MultiVariantGenerator(Block block, List baseVariants) { this.block = block; this.baseVariants = baseVariants; } public MultiVariantGenerator with(PropertyDispatch propertyDispatch) { propertyDispatch.getDefinedProperties().forEach(property -> { if (this.block.getStateDefinition().getProperty(property.getName()) != property) { throw new IllegalStateException("Property " + property + " is not defined for block " + this.block); } else if (!this.seenProperties.add(property)) { throw new IllegalStateException("Values of property " + property + " already defined for block " + this.block); } }); this.declaredPropertySets.add(propertyDispatch); return this; } public JsonElement get() { Stream>> stream = Stream.of(Pair.of(Selector.empty(), this.baseVariants)); for (PropertyDispatch propertyDispatch : this.declaredPropertySets) { Map> map = propertyDispatch.getEntries(); stream = stream.flatMap(pair -> map.entrySet().stream().map(entry -> { Selector selector = ((Selector)pair.getFirst()).extend((Selector)entry.getKey()); List list = mergeVariants((List)pair.getSecond(), (List)entry.getValue()); return Pair.of(selector, list); })); } Map map2 = new TreeMap(); stream.forEach(pair -> map2.put(((Selector)pair.getFirst()).getKey(), Variant.convertList((List)pair.getSecond()))); JsonObject jsonObject = new JsonObject(); jsonObject.add("variants", Util.make(new JsonObject(), jsonObjectx -> map2.forEach(jsonObjectx::add))); return jsonObject; } private static List mergeVariants(List variants1, List variants2) { Builder builder = ImmutableList.builder(); variants1.forEach(variant -> variants2.forEach(variant2 -> builder.add(Variant.merge(variant, variant2)))); return builder.build(); } @Override public Block getBlock() { return this.block; } public static MultiVariantGenerator multiVariant(Block block) { return new MultiVariantGenerator(block, ImmutableList.of(Variant.variant())); } public static MultiVariantGenerator multiVariant(Block block, Variant variant) { return new MultiVariantGenerator(block, ImmutableList.of(variant)); } public static MultiVariantGenerator multiVariant(Block block, Variant... variants) { return new MultiVariantGenerator(block, ImmutableList.copyOf(variants)); } }