diff --git a/src/main/java/org/dimdev/dimdoors/pockets/SchematicV2Handler.java b/src/main/java/org/dimdev/dimdoors/pockets/SchematicV2Handler.java index 3d41a4e1..dc73791f 100644 --- a/src/main/java/org/dimdev/dimdoors/pockets/SchematicV2Handler.java +++ b/src/main/java/org/dimdev/dimdoors/pockets/SchematicV2Handler.java @@ -8,6 +8,7 @@ import java.nio.file.Paths; import java.util.*; import java.util.function.BiConsumer; import java.util.function.Function; +import java.util.stream.Collectors; import com.google.common.collect.*; import com.google.gson.*; @@ -20,6 +21,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.dimdev.dimdoors.pockets.generator.PocketGenerator; import org.dimdev.dimdoors.pockets.virtual.VirtualPocket; +import org.dimdev.dimdoors.util.PocketGenerationParameters; +import org.dimdev.dimdoors.util.WeightedList; import org.dimdev.dimdoors.util.schematic.v2.Schematic; public class SchematicV2Handler { @@ -132,6 +135,10 @@ public class SchematicV2Handler { } } + public WeightedList getPocketsMatchingTags(List required, List blackList, boolean exact) { + return new WeightedList<>(pocketGeneratorMap.values().stream().filter(pocketGenerator -> pocketGenerator.checkTags(required, blackList, exact)).collect(Collectors.toList())); + } + public VirtualPocket getGroup(String group) { return pocketGroups.get(group); } diff --git a/src/main/java/org/dimdev/dimdoors/pockets/generator/PocketGenerator.java b/src/main/java/org/dimdev/dimdoors/pockets/generator/PocketGenerator.java index 2832b493..473980d4 100644 --- a/src/main/java/org/dimdev/dimdoors/pockets/generator/PocketGenerator.java +++ b/src/main/java/org/dimdev/dimdoors/pockets/generator/PocketGenerator.java @@ -2,11 +2,13 @@ package org.dimdev.dimdoors.pockets.generator; import com.mojang.serialization.Lifecycle; import net.fabricmc.fabric.api.event.registry.FabricRegistryBuilder; +import net.fabricmc.fabric.api.util.NbtType; import net.minecraft.block.entity.ChestBlockEntity; import net.minecraft.block.entity.DispenserBlockEntity; import net.minecraft.inventory.Inventory; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.StringTag; import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; import net.minecraft.util.registry.Registry; @@ -42,6 +44,8 @@ public abstract class PocketGenerator implements Weighted tags = new ArrayList<>(); + public PocketGenerator() { } public PocketGenerator(String weight) { @@ -87,6 +91,13 @@ public abstract class PocketGenerator implements Weighted 0) tag.put("modifiers", modifiersTag); + + if (tags.size() > 0) { + ListTag listTag = new ListTag(); + for (String tagString : tags) { + listTag.add(StringTag.of(tagString)); + } + tag.put("tags", listTag); + } + + return tag; } @@ -146,6 +167,22 @@ public abstract class PocketGenerator implements Weighted required, List blackList, boolean exact) { + if (exact && required.size() != tags.size()) return false; + if (required != null) { + for (String req : required) { + if (!tags.contains(req)) return false; + } + } + if (blackList != null) { + for (String black : blackList) { + if (tags.contains(black)) return false; + } + } + return true; + } + public interface PocketGeneratorType { PocketGeneratorType SCHEMATIC = register(new Identifier("dimdoors", SchematicGenerator.KEY), SchematicGenerator::new); PocketGeneratorType CHUNK = register(new Identifier("dimdoors", ChunkGenerator.KEY), ChunkGenerator::new); diff --git a/src/main/java/org/dimdev/dimdoors/pockets/virtual/VirtualSingularPocket.java b/src/main/java/org/dimdev/dimdoors/pockets/virtual/VirtualSingularPocket.java index 4c52f057..dc8b363a 100644 --- a/src/main/java/org/dimdev/dimdoors/pockets/virtual/VirtualSingularPocket.java +++ b/src/main/java/org/dimdev/dimdoors/pockets/virtual/VirtualSingularPocket.java @@ -8,6 +8,7 @@ import net.minecraft.util.registry.Registry; import net.minecraft.util.registry.RegistryKey; import net.minecraft.util.registry.SimpleRegistry; import org.dimdev.dimdoors.pockets.virtual.reference.IdReference; +import org.dimdev.dimdoors.pockets.virtual.reference.TagReference; import org.dimdev.dimdoors.pockets.virtual.selection.ConditionalSelector; import java.util.function.Supplier; @@ -53,6 +54,7 @@ public abstract class VirtualSingularPocket implements VirtualPocket { public interface VirtualSingularPocketType { VirtualSingularPocketType ID_REFERENCE = register(new Identifier("dimdoors", IdReference.KEY), IdReference::new); + VirtualSingularPocketType TAG_REFERENCE = register(new Identifier("dimdoors", TagReference.KEY), TagReference::new); VirtualSingularPocketType DEPTH_DEPENDENT_SELECTOR = register(new Identifier("dimdoors", ConditionalSelector.KEY), ConditionalSelector::new); diff --git a/src/main/java/org/dimdev/dimdoors/pockets/virtual/reference/TagReference.java b/src/main/java/org/dimdev/dimdoors/pockets/virtual/reference/TagReference.java new file mode 100644 index 00000000..77c559ae --- /dev/null +++ b/src/main/java/org/dimdev/dimdoors/pockets/virtual/reference/TagReference.java @@ -0,0 +1,97 @@ +package org.dimdev.dimdoors.pockets.virtual.reference; + +import net.fabricmc.fabric.api.util.NbtType; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.StringTag; +import org.dimdev.dimdoors.pockets.SchematicV2Handler; +import org.dimdev.dimdoors.pockets.generator.PocketGenerator; +import org.dimdev.dimdoors.pockets.virtual.VirtualSingularPocket; +import org.dimdev.dimdoors.util.PocketGenerationParameters; +import org.dimdev.dimdoors.util.WeightedList; + +import java.util.ArrayList; +import java.util.List; + +public class TagReference extends PocketGeneratorReference{ + public static final String KEY = "tag"; + + private final List required = new ArrayList<>(); + private final List blackList = new ArrayList<>(); + private Boolean exact; + + private WeightedList pockets; + + @Override + public VirtualSingularPocket fromTag(CompoundTag tag) { + super.fromTag(tag); + + if (tag.contains("required")) { + ListTag listTag = tag.getList("required", NbtType.STRING); + for (int i = 0; i < listTag.size(); i++) { + required.add(listTag.getString(i)); + } + } + + if (tag.contains("blackList")) { + ListTag listTag = tag.getList("blackList", NbtType.STRING); + for (int i = 0; i < listTag.size(); i++) { + blackList.add(listTag.getString(i)); + } + } + + if (tag.contains("exact")) exact = tag.getBoolean("exact"); + + return this; + } + + @Override + public CompoundTag toTag(CompoundTag tag) { + super.toTag(tag); + + if (required.size() > 0) { + ListTag listTag = new ListTag(); + for (String tagString : required) { + listTag.add(StringTag.of(tagString)); + } + tag.put("required", listTag); + } + + if (blackList.size() > 0) { + ListTag listTag = new ListTag(); + for (String tagString : blackList) { + listTag.add(StringTag.of(tagString)); + } + tag.put("blackList", listTag); + } + + if (exact != null) { + tag.putBoolean("exact", exact); + } + + return tag; + } + + + @Override + public VirtualSingularPocketType getType() { + return VirtualSingularPocketType.TAG_REFERENCE; + } + + @Override + public String getKey() { + return KEY; + } + // TODO: this will break if pockets change in between (which they could if we add a tool for creating pocket json config stuff ingame) + @Override + public PocketGenerator peekReferencedPocketGenerator(PocketGenerationParameters parameters) { + if (pockets == null) pockets = SchematicV2Handler.getInstance().getPocketsMatchingTags(required, blackList, exact); + return pockets.peekNextRandomWeighted(parameters); + } + + @Override + public PocketGenerator getReferencedPocketGenerator(PocketGenerationParameters parameters) { + if (pockets == null) pockets = SchematicV2Handler.getInstance().getPocketsMatchingTags(required, blackList, exact); + return pockets.getNextRandomWeighted(parameters); + } +} diff --git a/src/main/java/org/dimdev/dimdoors/util/WeightedList.java b/src/main/java/org/dimdev/dimdoors/util/WeightedList.java index 87830056..321b0170 100644 --- a/src/main/java/org/dimdev/dimdoors/util/WeightedList.java +++ b/src/main/java/org/dimdev/dimdoors/util/WeightedList.java @@ -7,7 +7,10 @@ public class WeightedList, P> extends ArrayList { private T peekedRandom; private boolean peeked = false; - public WeightedList() { + public WeightedList() { } + + public WeightedList(Collection c) { + super(c); } public T getNextRandomWeighted(P parameters) {