mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-30 16:28:00 +01:00
Fix a bunch of codec-related stuff
This commit is contained in:
parent
c4e3383c36
commit
9cf6f2818a
5 changed files with 57 additions and 66 deletions
|
@ -13,7 +13,6 @@ import com.minelittlepony.unicopia.item.URecipes;
|
||||||
import com.minelittlepony.unicopia.util.InventoryUtil;
|
import com.minelittlepony.unicopia.util.InventoryUtil;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
import com.mojang.serialization.MapCodec;
|
|
||||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
|
@ -144,7 +143,7 @@ public class SpellCraftingRecipe implements SpellbookRecipe {
|
||||||
public static class Serializer implements RecipeSerializer<SpellCraftingRecipe> {
|
public static class Serializer implements RecipeSerializer<SpellCraftingRecipe> {
|
||||||
private static final Codec<SpellCraftingRecipe> CODEC = RecordCodecBuilder.<SpellCraftingRecipe>create(instance -> instance.group(
|
private static final Codec<SpellCraftingRecipe> CODEC = RecordCodecBuilder.<SpellCraftingRecipe>create(instance -> instance.group(
|
||||||
IngredientWithSpell.CODEC.fieldOf("material").forGetter(recipe -> recipe.material),
|
IngredientWithSpell.CODEC.fieldOf("material").forGetter(recipe -> recipe.material),
|
||||||
((MapCodec<TraitIngredient>)null).forGetter(recipe -> recipe.requiredTraits),
|
TraitIngredient.CODEC.fieldOf("traits").forGetter(recipe -> recipe.requiredTraits),
|
||||||
IngredientWithSpell.CODEC.listOf().fieldOf("ingredients").forGetter(recipe -> recipe.requiredItems),
|
IngredientWithSpell.CODEC.listOf().fieldOf("ingredients").forGetter(recipe -> recipe.requiredItems),
|
||||||
ItemStackWithSpell.CODEC.fieldOf("result").forGetter(recipe -> recipe.output)
|
ItemStackWithSpell.CODEC.fieldOf("result").forGetter(recipe -> recipe.output)
|
||||||
).apply(instance, SpellCraftingRecipe::new));
|
).apply(instance, SpellCraftingRecipe::new));
|
||||||
|
|
|
@ -3,16 +3,31 @@ package com.minelittlepony.unicopia.ability.magic.spell.crafting;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
|
import com.mojang.datafixers.util.Either;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.DataResult;
|
||||||
|
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||||
|
|
||||||
import net.minecraft.network.PacketByteBuf;
|
import net.minecraft.network.PacketByteBuf;
|
||||||
import net.minecraft.util.JsonHelper;
|
import net.minecraft.util.dynamic.Codecs;
|
||||||
|
|
||||||
public record TraitIngredient (
|
public record TraitIngredient (
|
||||||
Optional<SpellTraits> min,
|
Optional<SpellTraits> min,
|
||||||
Optional<SpellTraits> max
|
Optional<SpellTraits> max
|
||||||
) implements Predicate<SpellTraits> {
|
) implements Predicate<SpellTraits> {
|
||||||
|
public static final Codec<TraitIngredient> CODEC = Codecs.xor(
|
||||||
|
SpellTraits.CODEC.flatXmap(
|
||||||
|
traits -> DataResult.success(new TraitIngredient(Optional.ofNullable(traits), Optional.empty())),
|
||||||
|
ingredient -> ingredient.min().map(DataResult::success).orElseGet(() -> DataResult.error(() -> "Cannot serialize an empty trait ingredient"))),
|
||||||
|
RecordCodecBuilder.<TraitIngredient>create(instance -> instance.group(
|
||||||
|
SpellTraits.CODEC.optionalFieldOf("min").forGetter(TraitIngredient::min),
|
||||||
|
SpellTraits.CODEC.optionalFieldOf("max").forGetter(TraitIngredient::max)
|
||||||
|
).apply(instance, TraitIngredient::new))
|
||||||
|
).flatXmap(
|
||||||
|
either -> either.left().or(either::right).map(DataResult::success).orElseGet(() -> DataResult.error(() -> "Invalid traits")),
|
||||||
|
ingredient -> DataResult.success(ingredient.max.isPresent() ? Either.left(ingredient) : Either.right(ingredient))
|
||||||
|
);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(SpellTraits t) {
|
public boolean test(SpellTraits t) {
|
||||||
|
@ -29,22 +44,4 @@ public record TraitIngredient (
|
||||||
public static TraitIngredient fromPacket(PacketByteBuf buf) {
|
public static TraitIngredient fromPacket(PacketByteBuf buf) {
|
||||||
return new TraitIngredient(SpellTraits.fromPacketOrEmpty(buf), SpellTraits.fromPacketOrEmpty(buf));
|
return new TraitIngredient(SpellTraits.fromPacketOrEmpty(buf), SpellTraits.fromPacketOrEmpty(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TraitIngredient fromJson(JsonObject json) {
|
|
||||||
Optional<SpellTraits> min = Optional.empty();
|
|
||||||
Optional<SpellTraits> max = Optional.empty();
|
|
||||||
|
|
||||||
if (json.has("min") || json.has("max")) {
|
|
||||||
if (json.has("min")) {
|
|
||||||
min = SpellTraits.fromJson(JsonHelper.getObject(json, "min"));
|
|
||||||
}
|
|
||||||
if (json.has("max")) {
|
|
||||||
max = SpellTraits.fromJson(JsonHelper.getObject(json, "max"));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
min = SpellTraits.fromJson(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new TraitIngredient(min, max);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,12 @@ import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.google.gson.JsonObject;
|
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
import com.minelittlepony.unicopia.client.gui.ItemTraitsTooltipRenderer;
|
import com.minelittlepony.unicopia.client.gui.ItemTraitsTooltipRenderer;
|
||||||
import com.minelittlepony.unicopia.util.InventoryUtil;
|
import com.minelittlepony.unicopia.util.InventoryUtil;
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.DataResult;
|
||||||
|
|
||||||
import net.fabricmc.api.EnvType;
|
import net.fabricmc.api.EnvType;
|
||||||
import net.fabricmc.api.Environment;
|
import net.fabricmc.api.Environment;
|
||||||
|
@ -30,6 +32,7 @@ import net.minecraft.item.Item;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
import net.minecraft.nbt.NbtElement;
|
import net.minecraft.nbt.NbtElement;
|
||||||
|
import net.minecraft.nbt.NbtOps;
|
||||||
import net.minecraft.network.PacketByteBuf;
|
import net.minecraft.network.PacketByteBuf;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
@ -42,6 +45,10 @@ public final class SpellTraits implements Iterable<Map.Entry<Trait, Float>> {
|
||||||
private static Map<Identifier, SpellTraits> REGISTRY = new HashMap<>();
|
private static Map<Identifier, SpellTraits> REGISTRY = new HashMap<>();
|
||||||
static final Map<Trait, List<Item>> ITEMS = new HashMap<>();
|
static final Map<Trait, List<Item>> ITEMS = new HashMap<>();
|
||||||
|
|
||||||
|
public static final Codec<SpellTraits> CODEC = Codec.unboundedMap(Trait.CODEC, Codec.FLOAT).flatXmap(map -> {
|
||||||
|
return fromEntries(map.entrySet().stream()).map(DataResult::success).orElseGet(() -> DataResult.error(() -> "No traits were supplied"));
|
||||||
|
}, traits -> DataResult.success(traits.traits));
|
||||||
|
|
||||||
public static void load(Map<Identifier, SpellTraits> newRegistry) {
|
public static void load(Map<Identifier, SpellTraits> newRegistry) {
|
||||||
REGISTRY = new HashMap<>(newRegistry);
|
REGISTRY = new HashMap<>(newRegistry);
|
||||||
ITEMS.clear();
|
ITEMS.clear();
|
||||||
|
@ -244,11 +251,7 @@ public final class SpellTraits implements Iterable<Map.Entry<Trait, Float>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<SpellTraits> fromNbt(NbtCompound traits) {
|
public static Optional<SpellTraits> fromNbt(NbtCompound traits) {
|
||||||
return fromEntries(streamFromNbt(traits));
|
return CODEC.decode(NbtOps.INSTANCE, traits).result().map(Pair::getFirst);
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<SpellTraits> fromJson(JsonObject traits) {
|
|
||||||
return fromEntries(streamFromJson(traits));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Optional<SpellTraits> fromPacketOrEmpty(PacketByteBuf buf) {
|
public static Optional<SpellTraits> fromPacketOrEmpty(PacketByteBuf buf) {
|
||||||
|
@ -256,7 +259,6 @@ public final class SpellTraits implements Iterable<Map.Entry<Trait, Float>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SpellTraits fromPacket(PacketByteBuf buf) {
|
public static SpellTraits fromPacket(PacketByteBuf buf) {
|
||||||
|
|
||||||
Map<Trait, Float> entries = new HashMap<>();
|
Map<Trait, Float> entries = new HashMap<>();
|
||||||
int count = buf.readInt();
|
int count = buf.readInt();
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
|
@ -295,26 +297,6 @@ public final class SpellTraits implements Iterable<Map.Entry<Trait, Float>> {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Stream<Map.Entry<Trait, Float>> streamFromNbt(NbtCompound traits) {
|
|
||||||
return traits.getKeys().stream().map(key -> {
|
|
||||||
Trait trait = Trait.fromId(key).orElse(null);
|
|
||||||
if (trait == null || !traits.contains(key, NbtElement.NUMBER_TYPE)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return Map.entry(trait, traits.getFloat(key));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Stream<Map.Entry<Trait, Float>> streamFromJson(JsonObject traits) {
|
|
||||||
return traits.entrySet().stream().map(entry -> {
|
|
||||||
Trait trait = Trait.fromName(entry.getKey()).orElse(null);
|
|
||||||
if (trait == null || !entry.getValue().isJsonPrimitive() && !entry.getValue().getAsJsonPrimitive().isNumber()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return Map.entry(trait, entry.getValue().getAsJsonPrimitive().getAsFloat());
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Optional<SpellTraits> fromEntries(Stream<Map.Entry<Trait, Float>> entries) {
|
public static Optional<SpellTraits> fromEntries(Stream<Map.Entry<Trait, Float>> entries) {
|
||||||
var result = collect(entries);
|
var result = collect(entries);
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,9 @@ import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
import com.minelittlepony.unicopia.command.CommandArgumentEnum;
|
import com.minelittlepony.unicopia.command.CommandArgumentEnum;
|
||||||
|
import com.mojang.datafixers.util.Either;
|
||||||
import com.mojang.serialization.Codec;
|
import com.mojang.serialization.Codec;
|
||||||
|
import com.mojang.serialization.DataResult;
|
||||||
|
|
||||||
import net.minecraft.command.argument.EnumArgumentType;
|
import net.minecraft.command.argument.EnumArgumentType;
|
||||||
import net.minecraft.item.Item;
|
import net.minecraft.item.Item;
|
||||||
|
@ -18,6 +20,7 @@ import net.minecraft.text.*;
|
||||||
import net.minecraft.util.Formatting;
|
import net.minecraft.util.Formatting;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.StringIdentifiable;
|
import net.minecraft.util.StringIdentifiable;
|
||||||
|
import net.minecraft.util.dynamic.Codecs;
|
||||||
|
|
||||||
public enum Trait implements CommandArgumentEnum<Trait> {
|
public enum Trait implements CommandArgumentEnum<Trait> {
|
||||||
/**
|
/**
|
||||||
|
@ -60,8 +63,17 @@ public enum Trait implements CommandArgumentEnum<Trait> {
|
||||||
POISON(TraitGroup.DARKNESS),
|
POISON(TraitGroup.DARKNESS),
|
||||||
BLOOD(TraitGroup.DARKNESS);
|
BLOOD(TraitGroup.DARKNESS);
|
||||||
|
|
||||||
private static final Map<String, Trait> REGISTRY = Arrays.stream(values()).collect(Collectors.toMap(Trait::name, Function.identity()));
|
|
||||||
private static final Map<Identifier, Trait> IDS = Arrays.stream(values()).collect(Collectors.toMap(Trait::getId, Function.identity()));
|
private static final Map<Identifier, Trait> IDS = Arrays.stream(values()).collect(Collectors.toMap(Trait::getId, Function.identity()));
|
||||||
|
@Deprecated
|
||||||
|
private static final EnumCodec<Trait> NAME_CODEC = StringIdentifiable.createCodec(Trait::values);
|
||||||
|
@Deprecated
|
||||||
|
private static final EnumCodec<Trait> ID_CODEC = StringIdentifiable.createCodec(Trait::values, i -> "unicopia:" + i);
|
||||||
|
|
||||||
|
public static final Codec<Trait> CODEC = Codecs.xor(NAME_CODEC, ID_CODEC).flatXmap(
|
||||||
|
either -> either.left().or(either::right).map(DataResult::success).orElseGet(() -> DataResult.error(() -> "Not a proper trait")),
|
||||||
|
trait -> DataResult.success(Either.right(trait))
|
||||||
|
);
|
||||||
|
|
||||||
private final Identifier id;
|
private final Identifier id;
|
||||||
private final Identifier sprite;
|
private final Identifier sprite;
|
||||||
private final TraitGroup group;
|
private final TraitGroup group;
|
||||||
|
@ -149,25 +161,26 @@ public enum Trait implements CommandArgumentEnum<Trait> {
|
||||||
.flatMap(Optional::stream);
|
.flatMap(Optional::stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static Optional<Trait> fromId(Identifier id) {
|
public static Optional<Trait> fromId(Identifier id) {
|
||||||
return Optional.ofNullable(IDS.getOrDefault(id, null));
|
return Optional.ofNullable(ID_CODEC.byId(id.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static Optional<Trait> fromId(String name) {
|
public static Optional<Trait> fromId(String name) {
|
||||||
return Optional.ofNullable(Identifier.tryParse(name)).flatMap(Trait::fromId);
|
return Optional.ofNullable(Identifier.tryParse(name)).flatMap(Trait::fromId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
public static Optional<Trait> fromName(String name) {
|
public static Optional<Trait> fromName(String name) {
|
||||||
return Optional.ofNullable(REGISTRY.getOrDefault(name.toUpperCase(), null));
|
return Optional.ofNullable(NAME_CODEC.byId(name.toUpperCase()));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EnumArgumentType<Trait> argument() {
|
public static EnumArgumentType<Trait> argument() {
|
||||||
return new ArgumentType();
|
return new ArgumentType();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class ArgumentType extends EnumArgumentType<Trait> {
|
public static class ArgumentType extends EnumArgumentType<Trait> {
|
||||||
static final Codec<Trait> CODEC = StringIdentifiable.createCodec(Trait::values);
|
|
||||||
|
|
||||||
protected ArgumentType() {
|
protected ArgumentType() {
|
||||||
super(CODEC, Trait::values);
|
super(CODEC, Trait::values);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,17 +17,6 @@ import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.collection.DefaultedList;
|
import net.minecraft.util.collection.DefaultedList;
|
||||||
|
|
||||||
public interface URecipes {
|
public interface URecipes {
|
||||||
RecipeType<SpellbookRecipe> SPELLBOOK = RecipeType.register("unicopia:spellbook");
|
|
||||||
|
|
||||||
RecipeSerializer<ZapAppleRecipe> ZAP_APPLE_SERIALIZER = RecipeSerializer.register("unicopia:crafting_zap_apple", new ZapAppleRecipe.Serializer());
|
|
||||||
RecipeSerializer<GlowingRecipe> GLOWING_SERIALIZER = RecipeSerializer.register("unicopia:crafting_glowing", new SpecialRecipeSerializer<>(GlowingRecipe::new));
|
|
||||||
RecipeSerializer<JarInsertRecipe> JAR_INSERT_SERIALIZER = RecipeSerializer.register("unicopia:jar_insert", new SpecialRecipeSerializer<>(JarInsertRecipe::new));
|
|
||||||
RecipeSerializer<JarExtractRecipe> JAR_EXTRACT_SERIALIZER = RecipeSerializer.register("unicopia:jar_extract", new SpecialRecipeSerializer<>(JarExtractRecipe::new));
|
|
||||||
RecipeSerializer<ShapedRecipe> CRAFTING_MAGICAL_SERIALIZER = RecipeSerializer.register("unicopia:crafting_magical", new SpellShapedCraftingRecipe.Serializer());
|
|
||||||
RecipeSerializer<SpellCraftingRecipe> TRAIT_REQUIREMENT = RecipeSerializer.register("unicopia:spellbook/crafting", new SpellCraftingRecipe.Serializer());
|
|
||||||
RecipeSerializer<SpellEnhancingRecipe> TRAIT_COMBINING = RecipeSerializer.register("unicopia:spellbook/combining", new SpellEnhancingRecipe.Serializer());
|
|
||||||
RecipeSerializer<SpellDuplicatingRecipe> SPELL_DUPLICATING = RecipeSerializer.register("unicopia:spellbook/duplicating", new SpellDuplicatingRecipe.Serializer());
|
|
||||||
|
|
||||||
Codec<DefaultedList<Ingredient>> SHAPELESS_RECIPE_INGREDIENTS_CODEC = Ingredient.DISALLOW_EMPTY_CODEC.listOf().flatXmap(ingredients -> {
|
Codec<DefaultedList<Ingredient>> SHAPELESS_RECIPE_INGREDIENTS_CODEC = Ingredient.DISALLOW_EMPTY_CODEC.listOf().flatXmap(ingredients -> {
|
||||||
Ingredient[] ingredients2 = ingredients.stream().filter(ingredient -> !ingredient.isEmpty()).toArray(Ingredient[]::new);
|
Ingredient[] ingredients2 = ingredients.stream().filter(ingredient -> !ingredient.isEmpty()).toArray(Ingredient[]::new);
|
||||||
if (ingredients2.length == 0) {
|
if (ingredients2.length == 0) {
|
||||||
|
@ -39,6 +28,17 @@ public interface URecipes {
|
||||||
return DataResult.success(DefaultedList.copyOf(Ingredient.EMPTY, ingredients2));
|
return DataResult.success(DefaultedList.copyOf(Ingredient.EMPTY, ingredients2));
|
||||||
}, DataResult::success);
|
}, DataResult::success);
|
||||||
|
|
||||||
|
RecipeType<SpellbookRecipe> SPELLBOOK = RecipeType.register("unicopia:spellbook");
|
||||||
|
|
||||||
|
RecipeSerializer<ZapAppleRecipe> ZAP_APPLE_SERIALIZER = RecipeSerializer.register("unicopia:crafting_zap_apple", new ZapAppleRecipe.Serializer());
|
||||||
|
RecipeSerializer<GlowingRecipe> GLOWING_SERIALIZER = RecipeSerializer.register("unicopia:crafting_glowing", new SpecialRecipeSerializer<>(GlowingRecipe::new));
|
||||||
|
RecipeSerializer<JarInsertRecipe> JAR_INSERT_SERIALIZER = RecipeSerializer.register("unicopia:jar_insert", new SpecialRecipeSerializer<>(JarInsertRecipe::new));
|
||||||
|
RecipeSerializer<JarExtractRecipe> JAR_EXTRACT_SERIALIZER = RecipeSerializer.register("unicopia:jar_extract", new SpecialRecipeSerializer<>(JarExtractRecipe::new));
|
||||||
|
RecipeSerializer<ShapedRecipe> CRAFTING_MAGICAL_SERIALIZER = RecipeSerializer.register("unicopia:crafting_magical", new SpellShapedCraftingRecipe.Serializer());
|
||||||
|
RecipeSerializer<SpellCraftingRecipe> TRAIT_REQUIREMENT = RecipeSerializer.register("unicopia:spellbook/crafting", new SpellCraftingRecipe.Serializer());
|
||||||
|
RecipeSerializer<SpellEnhancingRecipe> TRAIT_COMBINING = RecipeSerializer.register("unicopia:spellbook/combining", new SpellEnhancingRecipe.Serializer());
|
||||||
|
RecipeSerializer<SpellDuplicatingRecipe> SPELL_DUPLICATING = RecipeSerializer.register("unicopia:spellbook/duplicating", new SpellDuplicatingRecipe.Serializer());
|
||||||
|
|
||||||
static void bootstrap() {
|
static void bootstrap() {
|
||||||
LootTableEvents.MODIFY.register((res, manager, id, supplier, setter) -> {
|
LootTableEvents.MODIFY.register((res, manager, id, supplier, setter) -> {
|
||||||
if (!"minecraft".contentEquals(id.getNamespace())) {
|
if (!"minecraft".contentEquals(id.getNamespace())) {
|
||||||
|
|
Loading…
Reference in a new issue