Implement the replace flag for state maps

This commit is contained in:
Sollace 2022-08-29 14:47:25 +02:00
parent 4cfa493654
commit b894665d65
4 changed files with 64 additions and 9 deletions

View file

@ -21,7 +21,7 @@ public class JsonReversableBlockStateConverter implements ReversableBlockStateCo
public JsonReversableBlockStateConverter(JsonElement json) { public JsonReversableBlockStateConverter(JsonElement json) {
this(new ArrayList<>(), null); this(new ArrayList<>(), null);
JsonHelper.getArray(json.getAsJsonObject(), "entries").forEach(entry -> { json.getAsJsonArray().forEach(entry -> {
entries.add(Entry.of(entry.getAsJsonObject(), true)); entries.add(Entry.of(entry.getAsJsonObject(), true));
}); });
} }

View file

@ -1,20 +1,24 @@
package com.minelittlepony.unicopia.block.state; package com.minelittlepony.unicopia.block.state;
import java.io.*;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import com.google.gson.JsonElement; import com.google.common.collect.Maps;
import com.google.gson.*;
import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.Unicopia;
import com.minelittlepony.unicopia.util.Resources; import com.minelittlepony.unicopia.util.Resources;
import com.mojang.logging.LogUtils;
import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener; import net.fabricmc.fabric.api.resource.IdentifiableResourceReloadListener;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.resource.JsonDataLoader; import net.minecraft.resource.*;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.JsonHelper;
import net.minecraft.util.profiler.Profiler; import net.minecraft.util.profiler.Profiler;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -23,6 +27,11 @@ public class StateMapLoader extends JsonDataLoader implements IdentifiableResour
public static final StateMapLoader INSTANCE = new StateMapLoader(); public static final StateMapLoader INSTANCE = new StateMapLoader();
private static final Logger LOGGER = LogUtils.getLogger();
private static final String FILE_SUFFIX = ".json";
private static final int FILE_SUFFIX_LENGTH = ".json".length();
private static final String DATA_TYPE = "state_maps";
private Map<Identifier, ReversableBlockStateConverter> converters = new HashMap<>(); private Map<Identifier, ReversableBlockStateConverter> converters = new HashMap<>();
public StateMapLoader() { public StateMapLoader() {
@ -34,6 +43,46 @@ public class StateMapLoader extends JsonDataLoader implements IdentifiableResour
return ID; return ID;
} }
@Override
protected Map<Identifier, JsonElement> prepare(ResourceManager resourceManager, Profiler profiler) {
Map<Identifier, JsonElement> map = Maps.newHashMap();
int i = DATA_TYPE.length() + 1;
resourceManager.findAllResources(DATA_TYPE, id -> id.getPath().endsWith(FILE_SUFFIX)).entrySet().stream().forEach(entry -> {
Identifier resId = entry.getKey();
String path = resId.getPath();
Identifier id = new Identifier(resId.getNamespace(), path.substring(i, path.length() - FILE_SUFFIX_LENGTH));
JsonArray entries = new JsonArray();
for (var resource : entry.getValue()) {
try (BufferedReader reader = resource.getReader()) {
JsonObject json = JsonHelper.deserialize(Resources.GSON, reader, JsonObject.class);
if (json != null) {
if (json.has("entries")) {
JsonArray incoming = JsonHelper.getArray(json, "entries");
if (json.has("replace") && json.get("replace").getAsBoolean()) {
entries = incoming;
} else {
entries.addAll(incoming);
}
}
continue;
}
LOGGER.error("Couldn't load data file {} from {} as it's null or empty", id, resId);
} catch (JsonParseException | IOException | IllegalArgumentException e) {
LOGGER.error("Couldn't parse data file {} from {}", id, resId, e);
}
}
map.put(id, entries);
});
return map;
}
@Override @Override
protected void apply(Map<Identifier, JsonElement> data, ResourceManager manager, Profiler profiler) { protected void apply(Map<Identifier, JsonElement> data, ResourceManager manager, Profiler profiler) {
converters = data.entrySet().stream().collect(Collectors.toMap( converters = data.entrySet().stream().collect(Collectors.toMap(

View file

@ -110,7 +110,7 @@ public abstract class StatePredicate implements Predicate<BlockState> {
} }
} }
static boolean isPlant(BlockState s) { public static boolean isPlant(BlockState s) {
return s.getBlock() instanceof PlantBlock; return s.getBlock() instanceof PlantBlock;
} }
@ -119,11 +119,11 @@ public abstract class StatePredicate implements Predicate<BlockState> {
} }
public static Predicate<BlockState> ofState(String state) { public static Predicate<BlockState> ofState(String state) {
Identifier id = new Identifier(state.split("{")[0]); Identifier id = new Identifier(state.split("\\{")[0]);
List<PropertyOp> properties = Optional.of(state) List<PropertyOp> properties = Optional.of(state)
.filter(s -> s.contains("{")) .filter(s -> s.contains("{"))
.stream() .stream()
.flatMap(s -> Stream.of(s.split("{")[1].split("}")[0].split(","))) .flatMap(s -> Stream.of(s.split("\\{")[1].split("\\}")[0].split(",")))
.map(PropertyOp::of) .map(PropertyOp::of)
.filter(Optional::isPresent) .filter(Optional::isPresent)
.map(Optional::get) .map(Optional::get)

View file

@ -1,9 +1,15 @@
{ {
"parent": "unicopia:snow_piled",
"replace": false, "replace": false,
"entries": [ "entries": [
{ {
"match": { "state": "minecraft:water" }, "match": { "state": "minecraft:snow{layers<7}" },
"apply": {
"action": "unicopia:cycle_property",
"property": "layers"
}
},
{
"match": { "tag": "minecraft:water" },
"apply": { "apply": {
"action": "unicopia:set_state", "action": "unicopia:set_state",
"state": "minecraft:frosted_ice" "state": "minecraft:frosted_ice"