Got themes working. ><
This commit is contained in:
parent
aed736f968
commit
d6171fb15e
7 changed files with 168 additions and 49 deletions
|
@ -2,25 +2,28 @@ package org.dimdev.dimdoors.datagen;
|
|||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.mojang.datafixers.util.Pair;
|
||||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.Blocks;
|
||||
import net.minecraft.data.DataCache;
|
||||
import net.minecraft.data.DataGenerator;
|
||||
import net.minecraft.data.DataProvider;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.tag.BlockTags;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.api.util.ResourceUtil;
|
||||
import org.dimdev.dimdoors.pockets.theme.Converter;
|
||||
import org.dimdev.dimdoors.pockets.theme.TaggedConverter;
|
||||
import org.dimdev.dimdoors.block.ModBlocks;
|
||||
import org.dimdev.dimdoors.pockets.theme.Theme;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ThemeProvider implements DataProvider {
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
@ -36,7 +39,7 @@ public class ThemeProvider implements DataProvider {
|
|||
public void run(DataCache cache) throws IOException {
|
||||
Path path = this.generator.getOutput();
|
||||
|
||||
BiConsumer<Identifier, JsonObject> consumer = (identifier, json) -> {
|
||||
BiConsumer<Identifier, JsonElement> consumer = (identifier, json) -> {
|
||||
Path outputPath = getOutput(path, identifier);
|
||||
|
||||
try {
|
||||
|
@ -49,20 +52,26 @@ public class ThemeProvider implements DataProvider {
|
|||
generatePatterns(consumer);
|
||||
}
|
||||
|
||||
protected void generatePatterns(BiConsumer<Identifier, JsonObject> consumer) {
|
||||
protected void generatePatterns(BiConsumer<Identifier, JsonElement> consumer) {
|
||||
theme(new Identifier("dimdoors", "oak"),
|
||||
TaggedConverter.of(BlockTags.STAIRS, Blocks.OAK_STAIRS),
|
||||
TaggedConverter.of(BlockTags.LOGS, Blocks.OAK_LOG),
|
||||
TaggedConverter.of(BlockTags.SLABS, Blocks.OAK_SLAB),
|
||||
TaggedConverter.of(BlockTags.LEAVES, Blocks.OAK_LEAVES))
|
||||
of(BlockTags.STAIRS, Blocks.OAK_STAIRS),
|
||||
of(BlockTags.LOGS, Blocks.OAK_LOG),
|
||||
of(BlockTags.SLABS, Blocks.OAK_SLAB),
|
||||
of(BlockTags.LEAVES, Blocks.OAK_LEAVES),
|
||||
of(ModBlocks.BLACK_FABRIC, Blocks.QUARTZ_BLOCK))
|
||||
.run(consumer);
|
||||
}
|
||||
|
||||
private TaggedThemeBuilder theme(Identifier id, Converter... converters) {
|
||||
private Pair<Theme.Entry, Block> of(Object obj, Block block) {
|
||||
return Pair.of(Theme.Entry.of(obj), block);
|
||||
}
|
||||
|
||||
private TaggedThemeBuilder theme(Identifier id, Pair<Theme.Entry, Block>... converters) {
|
||||
return new TaggedThemeBuilder(id, converters);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "Theme";
|
||||
|
@ -73,24 +82,17 @@ public class ThemeProvider implements DataProvider {
|
|||
}
|
||||
|
||||
public static class TaggedThemeBuilder {
|
||||
private final List<Converter> converters;
|
||||
private final Theme theme ;
|
||||
private Identifier id;
|
||||
|
||||
public TaggedThemeBuilder(Identifier id, Converter... converters) {
|
||||
public TaggedThemeBuilder(Identifier id, Pair<Theme.Entry, Block>... converters) {
|
||||
this.id = id;
|
||||
|
||||
this.converters = List.of(converters);
|
||||
this.theme = new Theme(Stream.of(converters).collect(Collectors.toMap(Pair::getFirst, Pair::getSecond)));
|
||||
}
|
||||
|
||||
public void run(BiConsumer<Identifier, JsonObject> consumer) {
|
||||
JsonObject object = new JsonObject();
|
||||
|
||||
JsonArray converters = new JsonArray();
|
||||
|
||||
this.converters.stream().map(converter -> converter.toNbt(new NbtCompound())).map(ResourceUtil.NBT_TO_JSON).forEach(converters::add);
|
||||
|
||||
object.add("converters", converters);
|
||||
|
||||
public void run(BiConsumer<Identifier, JsonElement> consumer) {
|
||||
JsonElement object = JsonOps.INSTANCE.withEncoder(Theme.CODEC).andThen(DataResult::result).andThen(Optional::get).apply(theme);
|
||||
consumer.accept(id, object);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,9 +30,9 @@ public class ResourceUtil {
|
|||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
private static final Gson GSON = new GsonBuilder().setLenient().setPrettyPrinting().create();
|
||||
|
||||
public static final BiFunction<String, Identifier, Path<String>> PATH_KEY_PROVIDER = (startingPath, id) -> Path.stringPath(id.getNamespace() + ":" + id.getPath().substring(0, id.getPath().lastIndexOf(".")).substring(startingPath.length() + (startingPath.endsWith("/") ? 0 : 1)));
|
||||
public static final BiFunction<String, Identifier, Path<String>> PATH_KEY_PROVIDER = (startingPath, id) -> Path.stringPath(id.getNamespace() + ":" + id.getPath().substring(0, id.getPath().lastIndexOf(".")).substring(startingPath.length() + (startingPath.endsWith("/") ? 0 : 1)));
|
||||
|
||||
public static final BiFunction<String, Identifier, Identifier> IDENTIFIER_PROVIDER = (s, identifier) -> identifier;
|
||||
public static final BiFunction<String, Identifier, String> STRING_PROVIDER = (startingPath, id) -> id.getNamespace() + ":" + id.getPath().substring(0, id.getPath().lastIndexOf(".")).substring(startingPath.length() + (startingPath.endsWith("/") ? 0 : 1));
|
||||
|
||||
public static final ComposableFunction<JsonElement, NbtElement> JSON_TO_NBT = json -> JsonOps.INSTANCE.convertTo(NbtOps.INSTANCE, json);
|
||||
|
||||
|
|
|
@ -42,11 +42,10 @@ public class ThemeArgumentType implements ArgumentType<Theme> {
|
|||
return getThemes()
|
||||
.keySet()
|
||||
.parallelStream()
|
||||
.map(id -> "\"" + id + "\"")
|
||||
.collect(Collectors.toCollection(TreeSet::new));
|
||||
}
|
||||
|
||||
private Map<Identifier, Theme> getThemes() {
|
||||
private Map<String, Theme> getThemes() {
|
||||
return PocketLoader.getInstance().getThemes();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,13 +3,13 @@ package org.dimdev.dimdoors.pockets;
|
|||
import net.fabricmc.fabric.api.resource.SimpleSynchronousResourceReloadListener;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtElement;
|
||||
import net.minecraft.nbt.NbtOps;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.util.Identifier;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.dimdev.dimdoors.api.util.*;
|
||||
import org.dimdev.dimdoors.pockets.generator.PocketGenerator;
|
||||
import org.dimdev.dimdoors.pockets.theme.Converter;
|
||||
import org.dimdev.dimdoors.pockets.theme.Theme;
|
||||
import org.dimdev.dimdoors.pockets.virtual.VirtualPocket;
|
||||
import org.dimdev.dimdoors.util.schematic.Schematic;
|
||||
|
@ -29,7 +29,7 @@ public class PocketLoader implements SimpleSynchronousResourceReloadListener {
|
|||
private SimpleTree<String, VirtualPocket> virtualPockets = new SimpleTree<>(String.class);
|
||||
private SimpleTree<String, PocketTemplate> templates = new SimpleTree<>(String.class);
|
||||
private SimpleTree<String, NbtElement> dataTree = new SimpleTree<>(String.class);
|
||||
private Map<Identifier, Theme> themes = new HashMap<>();
|
||||
private Map<String, Theme> themes = new HashMap<>();
|
||||
|
||||
private PocketLoader() {
|
||||
}
|
||||
|
@ -43,8 +43,8 @@ public class PocketLoader implements SimpleSynchronousResourceReloadListener {
|
|||
dataTree.clear();
|
||||
themes.clear();
|
||||
|
||||
dataTree = ResourceUtil.loadResourcePathToMap(manager, "pockets/json", ".json", new SimpleTree<>(String.class), ResourceUtil.NBT_READER.composeIdentity(), ResourceUtil.PATH_KEY_PROVIDER).join();
|
||||
themes = ResourceUtil.loadResourcePathToMap(manager, "pockets/themes", ".json", new HashMap<>(), ResourceUtil.NBT_READER.andThenReader(PocketLoader.this::loadTheme), ResourceUtil.IDENTIFIER_PROVIDER).join();
|
||||
dataTree = ResourceUtil.loadResourcePathToMap(manager, "pockets/jsonss", ".json", new SimpleTree<>(String.class), ResourceUtil.NBT_READER.composeIdentity(), ResourceUtil.PATH_KEY_PROVIDER).join();
|
||||
themes = ResourceUtil.loadResourcePathToMap(manager, "pockets/themes", ".json", new HashMap<>(), ResourceUtil.NBT_READER.andThenReader(this::loadTheme), ResourceUtil.STRING_PROVIDER).join();
|
||||
|
||||
CompletableFuture<SimpleTree<String, PocketGenerator>> futurePocketGeneratorMap = ResourceUtil.loadResourcePathToMap(manager, "pockets/generators", ".json", new SimpleTree<>(String.class), ResourceUtil.NBT_READER.andThenReader(pocketGeneratorLoader(manager)), ResourceUtil.PATH_KEY_PROVIDER);
|
||||
CompletableFuture<SimpleTree<String, VirtualPocket>> futurePocketGroups = ResourceUtil.loadResourcePathToMap(manager, "pockets/groups", ".json", new SimpleTree<>(String.class), ResourceUtil.NBT_READER.andThenReader(virtualPocketLoader(manager)), ResourceUtil.PATH_KEY_PROVIDER);
|
||||
|
@ -106,12 +106,8 @@ public class PocketLoader implements SimpleSynchronousResourceReloadListener {
|
|||
}
|
||||
}
|
||||
|
||||
private Theme loadTheme(NbtElement nbt, Identifier ignore) {
|
||||
if(nbt instanceof NbtCompound compound && compound.contains("converters")) {
|
||||
return new Theme(compound.getList("converters", NbtElement.COMPOUND_TYPE).stream().map(NbtCompound.class::cast).map(Converter::deserialize).collect(Collectors.toList()));
|
||||
} else {
|
||||
return Theme.NONE;
|
||||
}
|
||||
private Theme loadTheme(NbtElement nbt, String ignore) {
|
||||
return NbtOps.INSTANCE.withParser(Theme.CODEC).apply(nbt).setPartial(Theme.NONE).getOrThrow(true, System.out::println);
|
||||
}
|
||||
|
||||
public WeightedList<PocketGenerator, PocketGenerationContext> getPocketsMatchingTags(List<String> required, List<String> blackList, boolean exact) {
|
||||
|
@ -134,12 +130,12 @@ public class PocketLoader implements SimpleSynchronousResourceReloadListener {
|
|||
return this.pocketGroups;
|
||||
}
|
||||
|
||||
public Map<Identifier, Theme> getThemes() {
|
||||
public Map<String, Theme> getThemes() {
|
||||
return this.themes;
|
||||
}
|
||||
|
||||
public Theme getTheme(Identifier id) {
|
||||
return this.themes.get(id);
|
||||
return this.themes.getOrDefault(id.toString(), Theme.NONE);
|
||||
}
|
||||
|
||||
public SimpleTree<String, VirtualPocket> getVirtualPockets() {
|
||||
|
|
|
@ -102,6 +102,7 @@ public interface Modifier extends ReferenceSerializable {
|
|||
ModifierType<RelativeReferenceModifier> RELATIVE_REFERENCE_MODIFIER_TYPE = register(new Identifier("dimdoors", RelativeReferenceModifier.KEY), RelativeReferenceModifier::new);
|
||||
ModifierType<OffsetModifier> OFFSET_MODIFIER_TYPE = register(new Identifier("dimdoors", OffsetModifier.KEY), OffsetModifier::new);
|
||||
ModifierType<AbsoluteRiftBlockEntityModifier> ABSOLUTE_RIFT_BLOCK_ENTITY_MODIFIER_TYPE = register(new Identifier("dimdoors", AbsoluteRiftBlockEntityModifier.KEY), AbsoluteRiftBlockEntityModifier::new);
|
||||
ModifierType<ThemeModifier> THEME_MODIFIER_TYPE = register(new Identifier("dimdoors", ThemeModifier.KEY), ThemeModifier::new);
|
||||
|
||||
Modifier fromNbt(NbtCompound nbt, ResourceManager manager);
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
package org.dimdev.dimdoors.pockets.modifier;
|
||||
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.resource.ResourceManager;
|
||||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.BlockBox;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import org.dimdev.dimdoors.api.util.BlockBoxUtil;
|
||||
import org.dimdev.dimdoors.pockets.PocketGenerationContext;
|
||||
import org.dimdev.dimdoors.pockets.PocketLoader;
|
||||
import org.dimdev.dimdoors.pockets.theme.Theme;
|
||||
import org.dimdev.dimdoors.world.pocket.type.LazyGenerationPocket;
|
||||
import org.dimdev.dimdoors.world.pocket.type.Pocket;
|
||||
|
||||
public class ThemeModifier extends AbstractLazyModifier {
|
||||
public static final String KEY = "theme";
|
||||
|
||||
private Identifier themeId = null;
|
||||
|
||||
@Override
|
||||
protected NbtCompound toNbtInternal(NbtCompound nbt, boolean allowReference) {
|
||||
super.toNbtInternal(nbt, allowReference);
|
||||
if(themeId != null) nbt.putString("theme", themeId.toString());
|
||||
return nbt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyToChunk(LazyGenerationPocket pocket, Chunk chunk) {
|
||||
BlockBox chunkBox = BlockBoxUtil.getBox(chunk);
|
||||
BlockBox pocketBox = pocket.getBox();
|
||||
Theme theme = PocketLoader.getInstance().getTheme(themeId);
|
||||
|
||||
if(pocketBox.intersects(chunkBox)) {
|
||||
BlockPos.stream(pocketBox).forEach(blockBox -> chunk.setBlockState(blockBox, theme.apply(chunk.getBlockState(blockBox)), false));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Modifier fromNbt(NbtCompound nbt, ResourceManager manager) {
|
||||
themeId = null;
|
||||
|
||||
if(nbt.contains("theme")) {
|
||||
themeId = Identifier.tryParse(nbt.getString("theme"));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModifierType<? extends Modifier> getType() {
|
||||
return ModifierType.THEME_MODIFIER_TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getKey() {
|
||||
return KEY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(PocketGenerationContext parameters, RiftManager manager) {
|
||||
if(!manager.isPocketLazy()) {
|
||||
Theme theme = PocketLoader.getInstance().getTheme(themeId);
|
||||
ServerWorld world = parameters.world();
|
||||
|
||||
BlockPos.stream(manager.getPocket().getBox()).forEach(blockPos -> world.setBlockState(blockPos, theme.apply(world.getBlockState(blockPos))));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(PocketGenerationContext parameters, Pocket.PocketBuilder<?, ?> builder) {
|
||||
|
||||
}
|
||||
}
|
|
@ -1,23 +1,69 @@
|
|||
package org.dimdev.dimdoors.pockets.theme;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import com.mojang.serialization.Codec;
|
||||
import net.minecraft.block.Block;
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.state.property.Property;
|
||||
import net.minecraft.tag.TagKey;
|
||||
import net.minecraft.util.dynamic.Codecs;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public record Theme(List<Converter> converters) implements Function<BlockState, BlockState> {
|
||||
public static final Theme NONE = new Theme(List.of());
|
||||
public record Theme(Map<Entry, Block> entries) implements Function<BlockState, BlockState> {
|
||||
public static Codec<Theme> CODEC = Codec.unboundedMap(Entry.CODEC, Registry.BLOCK.getCodec()).xmap(Theme::new, Theme::entries);
|
||||
|
||||
public static final Theme NONE = new Theme(Map.of());
|
||||
|
||||
@Override
|
||||
public BlockState apply(BlockState blockState) {
|
||||
for (Converter converter : converters) {
|
||||
if (converter.test(blockState)) {
|
||||
BlockState apply = converter.apply(blockState);
|
||||
if (apply != null) return apply;
|
||||
if(entries.isEmpty()) return blockState;
|
||||
|
||||
for (Map.Entry<Entry, Block> converter : entries.entrySet()) {
|
||||
if (converter.getKey().test(blockState)) {
|
||||
BlockState apply = converter.getValue().getDefaultState();
|
||||
if (apply != null) {
|
||||
for (Map.Entry<Property<?>, Comparable<?>> a : blockState.getEntries().entrySet()) {
|
||||
if (apply.contains(a.getKey())) {
|
||||
apply = apply.with((Property) a.getKey(), (Comparable) a.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
return apply;
|
||||
}
|
||||
return blockState;
|
||||
}
|
||||
}
|
||||
|
||||
return blockState;
|
||||
}
|
||||
|
||||
public interface Entry extends Predicate<BlockState> {
|
||||
Codec<Entry> CODEC = Codecs.xor(TagKey.stringCodec(Registry.BLOCK_KEY), Registry.BLOCK.getCodec())
|
||||
.xmap(a -> a.mapBoth(TagEntry::new, BlockEntry::new), b -> b.mapBoth(TagEntry::tag, BlockEntry::block))
|
||||
.xmap(either -> either.map(Function.identity(), Function.identity()), entry -> entry instanceof TagEntry ? Either.left((TagEntry) entry) : Either.right((BlockEntry) entry));
|
||||
|
||||
public static Entry of(Object obj) {
|
||||
if(obj instanceof TagKey tag) return new TagEntry(tag);
|
||||
else if(obj instanceof Block block) return new BlockEntry(block);
|
||||
else return null;
|
||||
}
|
||||
|
||||
record TagEntry(TagKey<Block> tag) implements Entry {
|
||||
@Override
|
||||
public boolean test(BlockState blockState) {
|
||||
return blockState.isIn(tag);
|
||||
}
|
||||
}
|
||||
|
||||
record BlockEntry(Block block) implements Entry {
|
||||
@Override
|
||||
public boolean test(BlockState blockState) {
|
||||
return blockState.isOf(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue