diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/SpellTraits.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/SpellTraits.java index d6ca4d8c..5c9b9ca8 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/SpellTraits.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/SpellTraits.java @@ -17,6 +17,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.minelittlepony.unicopia.Unicopia; import com.minelittlepony.unicopia.client.gui.ItemTraitsTooltipRenderer; @@ -256,6 +257,12 @@ public final class SpellTraits implements Iterable> { return fromEntries(streamFromJson(traits)); } + public static JsonElement toJson(SpellTraits traits) { + JsonObject json = new JsonObject(); + traits.forEach(entry -> json.addProperty(entry.getKey().getId().toString(), entry.getValue())); + return json; + } + public static Optional fromPacketOrEmpty(PacketByteBuf buf) { return buf.readOptional(SpellTraits::fromPacket).filter(SpellTraits::isPresent); } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java index 8a1e0a05..341525b4 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/Trait.java @@ -61,6 +61,13 @@ public enum Trait implements CommandArgumentEnum { private static final Map REGISTRY = Arrays.stream(values()).collect(Collectors.toMap(Trait::name, Function.identity())); private static final Map IDS = Arrays.stream(values()).collect(Collectors.toMap(Trait::getId, Function.identity())); + + public static final com.mojang.serialization.Codec CODEC = StringIdentifiable.createCodec(Trait::values, n -> Unicopia.id(n.toLowerCase(Locale.ROOT)).toString()); + public static final com.mojang.serialization.Codec> SET_CODEC = CODEC.listOf().xmap( + l -> l.stream().distinct().collect(Collectors.toSet()), + s -> s.stream().toList() + ); + private final Identifier id; private final Identifier sprite; private final TraitGroup group; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java index 929f54e1..29ce78d5 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/trait/TraitDiscovery.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.ability.magic.spell.trait; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -10,6 +11,7 @@ import java.util.stream.Stream; import org.jetbrains.annotations.Nullable; +import com.minelittlepony.unicopia.advancement.UCriteria; import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.network.Channel; import com.minelittlepony.unicopia.network.MsgMarkTraitRead; @@ -76,8 +78,11 @@ public class TraitDiscovery implements NbtSerialisable, Copyable }); unreadTraits.addAll(newTraits); pony.setDirty(); - if (!newTraits.isEmpty() && !pony.asWorld().isClient) { - Channel.UNLOCK_TRAITS.sendToPlayer(new MsgUnlockTraits(newTraits), (ServerPlayerEntity)pony.asEntity()); + if (!newTraits.isEmpty()) { + if (!pony.asWorld().isClient) { + Channel.UNLOCK_TRAITS.sendToPlayer(new MsgUnlockTraits(newTraits), (ServerPlayerEntity)pony.asEntity()); + } + UCriteria.TRAIT_DISCOVERED.trigger(pony.asEntity()); } } @@ -103,6 +108,10 @@ public class TraitDiscovery implements NbtSerialisable, Copyable return traits.contains(trait); } + public boolean isKnown(Collection traits) { + return traits.containsAll(traits); + } + @Environment(EnvType.CLIENT) public void appendTooltip(ItemStack stack, @Nullable World world, List tooltip) { SpellTraits.getEmbeddedTraits(stack) diff --git a/src/main/java/com/minelittlepony/unicopia/advancement/TraitDiscoveredCriterion.java b/src/main/java/com/minelittlepony/unicopia/advancement/TraitDiscoveredCriterion.java new file mode 100644 index 00000000..2a98ed9b --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/advancement/TraitDiscoveredCriterion.java @@ -0,0 +1,63 @@ +package com.minelittlepony.unicopia.advancement; + +import java.util.Set; + +import com.google.gson.JsonObject; +import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; +import com.minelittlepony.unicopia.entity.player.Pony; +import com.mojang.serialization.JsonOps; + +import net.minecraft.advancement.criterion.AbstractCriterion; +import net.minecraft.advancement.criterion.AbstractCriterionConditions; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.predicate.entity.AdvancementEntityPredicateDeserializer; +import net.minecraft.predicate.entity.AdvancementEntityPredicateSerializer; +import net.minecraft.predicate.entity.LootContextPredicate; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.Identifier; +import net.minecraft.util.JsonHelper; + +public class TraitDiscoveredCriterion extends AbstractCriterion { + private static final Identifier ID = Unicopia.id("trait_discovered"); + + @Override + public Identifier getId() { + return ID; + } + + @Override + protected Conditions conditionsFromJson(JsonObject json, LootContextPredicate playerPredicate, AdvancementEntityPredicateDeserializer deserializer) { + return new Conditions(playerPredicate, Trait.SET_CODEC.decode(JsonOps.INSTANCE, JsonHelper.getArray(json, "traits")).result().get().getFirst()); + } + + public static Conditions create(Set traits) { + return new Conditions(LootContextPredicate.EMPTY, traits); + } + + public void trigger(PlayerEntity player) { + if (player instanceof ServerPlayerEntity) { + trigger((ServerPlayerEntity)player, c -> c.test((ServerPlayerEntity)player)); + } + } + + public static class Conditions extends AbstractCriterionConditions { + private final Set traits; + + public Conditions(LootContextPredicate playerPredicate, Set traits) { + super(ID, playerPredicate); + this.traits = traits; + } + + public boolean test(ServerPlayerEntity player) { + return Pony.of(player).getDiscoveries().isKnown(traits); + } + + @Override + public JsonObject toJson(AdvancementEntityPredicateSerializer serializer) { + JsonObject json = super.toJson(serializer); + json.add("traits", Trait.SET_CODEC.encodeStart(JsonOps.INSTANCE, traits).result().get()); + return json; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java b/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java index a652354d..db4d1224 100644 --- a/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java +++ b/src/main/java/com/minelittlepony/unicopia/advancement/UCriteria.java @@ -6,6 +6,7 @@ public interface UCriteria { CustomEventCriterion CUSTOM_EVENT = Criteria.register(new CustomEventCriterion()); RaceChangeCriterion PLAYER_CHANGE_RACE = Criteria.register(new RaceChangeCriterion()); SendViaDragonBreathScrollCriterion SEND_DRAGON_BREATH = Criteria.register(new SendViaDragonBreathScrollCriterion()); + TraitDiscoveredCriterion TRAIT_DISCOVERED = Criteria.register(new TraitDiscoveredCriterion()); CustomEventCriterion.Trigger LOOK_INTO_SUN = CUSTOM_EVENT.createTrigger("look_into_sun"); CustomEventCriterion.Trigger WEAR_SHADES = CUSTOM_EVENT.createTrigger("wear_shades"); diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java b/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java index 24f1f53b..527af08a 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/Datagen.java @@ -7,10 +7,10 @@ import com.minelittlepony.unicopia.datagen.providers.SeasonsGrowthRatesProvider; import com.minelittlepony.unicopia.datagen.providers.UBlockTagProvider; import com.minelittlepony.unicopia.datagen.providers.UItemTagProvider; import com.minelittlepony.unicopia.datagen.providers.UModelProvider; -import com.minelittlepony.unicopia.datagen.providers.URecipeProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UBlockAdditionsLootTableProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UBlockLootTableProvider; import com.minelittlepony.unicopia.datagen.providers.loot.UChestAdditionsLootTableProvider; +import com.minelittlepony.unicopia.datagen.providers.recipe.URecipeProvider; import com.minelittlepony.unicopia.server.world.UWorldGen; import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/BedSheetPatternRecipeBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/BedSheetPatternRecipeBuilder.java similarity index 98% rename from src/main/java/com/minelittlepony/unicopia/datagen/providers/BedSheetPatternRecipeBuilder.java rename to src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/BedSheetPatternRecipeBuilder.java index 2eb01643..0cd69ce6 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/BedSheetPatternRecipeBuilder.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/BedSheetPatternRecipeBuilder.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.datagen.providers; +package com.minelittlepony.unicopia.datagen.providers.recipe; import java.util.Arrays; import java.util.HashMap; diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/ComplexSpellcraftingRecipeJsonBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/ComplexSpellcraftingRecipeJsonBuilder.java new file mode 100644 index 00000000..1f5a9d5c --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/ComplexSpellcraftingRecipeJsonBuilder.java @@ -0,0 +1,55 @@ +package com.minelittlepony.unicopia.datagen.providers.recipe; + +import java.util.function.Consumer; + +import com.google.gson.JsonObject; +import com.minelittlepony.unicopia.Unicopia; +import net.minecraft.data.server.recipe.RecipeJsonProvider; +import net.minecraft.item.ItemConvertible; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.util.Identifier; + +public class ComplexSpellcraftingRecipeJsonBuilder { + private final RecipeSerializer serializer; + + private final ItemConvertible material; + + public ComplexSpellcraftingRecipeJsonBuilder(RecipeSerializer serializer, ItemConvertible material) { + this.serializer = serializer; + this.material = material; + } + + public static ComplexSpellcraftingRecipeJsonBuilder create(RecipeSerializer serializer, ItemConvertible material) { + return new ComplexSpellcraftingRecipeJsonBuilder(serializer, material); + } + + public void offerTo(Consumer exporter, final String recipeId) { + exporter.accept(new RecipeJsonProvider() { + @Override + public void serialize(JsonObject json) { + json.add("material", Ingredient.ofItems(material).toJson()); + } + + @Override + public Identifier getRecipeId() { + return Unicopia.id(recipeId); + } + + @Override + public RecipeSerializer getSerializer() { + return serializer; + } + + @Override + public JsonObject toAdvancementJson() { + return null; + } + + @Override + public Identifier getAdvancementId() { + return new Identifier(""); + } + }); + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/CraftingMaterialHelper.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/CraftingMaterialHelper.java similarity index 70% rename from src/main/java/com/minelittlepony/unicopia/datagen/CraftingMaterialHelper.java rename to src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/CraftingMaterialHelper.java index 76614d70..25118dd3 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/CraftingMaterialHelper.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/CraftingMaterialHelper.java @@ -1,17 +1,24 @@ -package com.minelittlepony.unicopia.datagen; +package com.minelittlepony.unicopia.datagen.providers.recipe; import java.util.Map; import java.util.NoSuchElementException; +import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; +import com.minelittlepony.unicopia.item.URecipes; import com.mojang.datafixers.util.Either; import net.fabricmc.fabric.api.tag.convention.v1.ConventionalItemTags; import net.minecraft.advancement.criterion.InventoryChangedCriterion; import net.minecraft.data.server.recipe.RecipeProvider; import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; +import net.minecraft.data.server.recipe.SingleItemRecipeJsonBuilder; import net.minecraft.data.server.recipe.VanillaRecipeProvider; import net.minecraft.item.Item; import net.minecraft.item.ItemConvertible; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.predicate.item.ItemPredicate; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.book.RecipeCategory; import net.minecraft.registry.Registries; import net.minecraft.registry.tag.ItemTags; import net.minecraft.registry.tag.TagKey; @@ -62,4 +69,22 @@ public interface CraftingMaterialHelper { static String hasTag(TagKey tag) { return "has_" + tag.id(); } + + static InventoryChangedCriterion.Conditions conditionsFromSpell(ItemConvertible gem, SpellType spell) { + NbtCompound nbt = new NbtCompound(); + nbt.putString("spell", spell.getId().toString()); + return RecipeProvider.conditionsFromItemPredicates(ItemPredicate.Builder.create() + .items(gem) + .nbt(nbt) + .build() + ); + } + + static String hasSpell(SpellType spell) { + return "has_" + spell.getId() + "_gemstone"; + } + + static SingleItemRecipeJsonBuilder createCloudShaping(Ingredient input, RecipeCategory category, ItemConvertible output, int count) { + return new SingleItemRecipeJsonBuilder(category, URecipes.CLOUD_SHAPING_SERIALIZER, input, output, count); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/GrowingRecipeJsonBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/GrowingRecipeJsonBuilder.java new file mode 100644 index 00000000..1daab591 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/GrowingRecipeJsonBuilder.java @@ -0,0 +1,131 @@ +package com.minelittlepony.unicopia.datagen.providers.recipe; + +import java.util.Objects; +import java.util.function.Consumer; + +import org.jetbrains.annotations.Nullable; +import org.spongepowered.include.com.google.common.base.Preconditions; + +import com.google.gson.JsonObject; +import com.minelittlepony.unicopia.item.URecipes; +import com.mojang.serialization.JsonOps; + +import net.minecraft.advancement.Advancement; +import net.minecraft.advancement.AdvancementRewards; +import net.minecraft.advancement.CriterionMerger; +import net.minecraft.advancement.criterion.CriterionConditions; +import net.minecraft.advancement.criterion.RecipeUnlockedCriterion; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.data.server.recipe.CraftingRecipeJsonBuilder; +import net.minecraft.data.server.recipe.RecipeJsonProvider; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.registry.Registries; +import net.minecraft.util.Identifier; + +public class GrowingRecipeJsonBuilder { + private final Advancement.Builder advancementBuilder = Advancement.Builder.createUntelemetered(); + @Nullable + private String group; + private final RecipeCategory category; + private final BlockState output; + private Block target; + private BlockState fuel; + + public static GrowingRecipeJsonBuilder create(RecipeCategory category, BlockState output) { + return new GrowingRecipeJsonBuilder(category, output); + } + + protected GrowingRecipeJsonBuilder(RecipeCategory category, BlockState output) { + this.category = category; + this.output = output; + } + + public GrowingRecipeJsonBuilder target(Block target) { + this.target = target; + return this; + } + + public GrowingRecipeJsonBuilder fuel(BlockState fuel) { + this.fuel = fuel; + return this; + } + + public GrowingRecipeJsonBuilder criterion(String name, CriterionConditions condition) { + advancementBuilder.criterion(name, condition); + return this; + } + + public GrowingRecipeJsonBuilder group(String group) { + this.group = group; + return this; + } + + public void offerTo(Consumer exporter, Identifier id) { + Preconditions.checkState(!advancementBuilder.getCriteria().isEmpty(), "No way of obtaining recipe " + id); + advancementBuilder + .parent(CraftingRecipeJsonBuilder.ROOT) + .criterion("has_the_recipe", RecipeUnlockedCriterion.create(id)) + .rewards(AdvancementRewards.Builder.recipe(id)) + .criteriaMerger(CriterionMerger.OR); + exporter.accept(new JsonProvider(id, id.withPrefixedPath("recipes/" + category.getName() + "/"), group, target, fuel)); + } + + public void offerTo(Consumer exporter) { + offerTo(exporter, Registries.BLOCK.getId(output.getBlock())); + } + + public void offerTo(Consumer exporter, String recipePath) { + Identifier recipeId = new Identifier(recipePath); + Identifier id = Registries.BLOCK.getId(output.getBlock()); + if (recipeId.equals(id)) { + throw new IllegalStateException("Recipe " + recipePath + " should remove its 'save' argument as it is equal to default one"); + } + offerTo(exporter, recipeId); + } + + private class JsonProvider implements RecipeJsonProvider { + private final Identifier recipeId; + private final Identifier advancementId; + private final String group; + private final Block target; + private final BlockState fuel; + + JsonProvider(Identifier recipeId, Identifier advancementId, String group, Block target, BlockState fuel) { + this.recipeId = recipeId; + this.advancementId = advancementId; + this.group = group; + this.target = Objects.requireNonNull(target, "Target"); + this.fuel = Objects.requireNonNull(fuel, "Fuel"); + } + + @Override + public void serialize(JsonObject json) { + json.addProperty("group", group); + json.addProperty("target", Registries.BLOCK.getId(target).toString()); + json.add("consume", BlockState.CODEC.encodeStart(JsonOps.INSTANCE, fuel).result().get()); + json.add("output", BlockState.CODEC.encodeStart(JsonOps.INSTANCE, output).result().get()); + } + + @Override + public Identifier getRecipeId() { + return recipeId; + } + + @Override + public RecipeSerializer getSerializer() { + return URecipes.TRANSFORM_CROP_SERIALIZER; + } + + @Override + public JsonObject toAdvancementJson() { + return advancementBuilder.toJson(); + } + + @Override + public Identifier getAdvancementId() { + return advancementId; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/SpellcraftingRecipeJsonBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/SpellcraftingRecipeJsonBuilder.java new file mode 100644 index 00000000..ca8d7b58 --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/SpellcraftingRecipeJsonBuilder.java @@ -0,0 +1,163 @@ +package com.minelittlepony.unicopia.datagen.providers.recipe; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import org.jetbrains.annotations.Nullable; +import org.spongepowered.include.com.google.common.base.Preconditions; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; +import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; +import com.minelittlepony.unicopia.advancement.TraitDiscoveredCriterion; +import com.minelittlepony.unicopia.item.UItems; +import com.minelittlepony.unicopia.item.URecipes; +import net.minecraft.advancement.Advancement; +import net.minecraft.advancement.AdvancementRewards; +import net.minecraft.advancement.CriterionMerger; +import net.minecraft.advancement.criterion.CriterionConditions; +import net.minecraft.advancement.criterion.RecipeUnlockedCriterion; +import net.minecraft.data.server.recipe.CraftingRecipeJsonBuilder; +import net.minecraft.data.server.recipe.RecipeJsonProvider; +import net.minecraft.item.ItemConvertible; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.util.Identifier; + +public class SpellcraftingRecipeJsonBuilder { + private final Advancement.Builder advancementBuilder = Advancement.Builder.createUntelemetered(); + @Nullable + private String group; + private final RecipeCategory category; + + private EnchantedIngredient base = new EnchantedIngredient(UItems.GEMSTONE, SpellType.EMPTY_KEY); + private final EnchantedIngredient output; + private final List ingredients = new ArrayList<>(); + private SpellTraits traits = SpellTraits.EMPTY; + + public static SpellcraftingRecipeJsonBuilder create(RecipeCategory category, ItemConvertible gem, SpellType spell) { + return new SpellcraftingRecipeJsonBuilder(category, new EnchantedIngredient(gem, spell)); + } + + protected SpellcraftingRecipeJsonBuilder(RecipeCategory category, EnchantedIngredient output) { + this.category = category; + this.output = output; + } + + public SpellcraftingRecipeJsonBuilder base(ItemConvertible gem, SpellType spell) { + base = new EnchantedIngredient(gem, spell); + return this; + } + + public SpellcraftingRecipeJsonBuilder input(ItemConvertible gem, SpellType spell) { + ingredients.add(new EnchantedIngredient(gem, spell)); + return this; + } + + public SpellcraftingRecipeJsonBuilder traits(SpellTraits.Builder traits) { + this.traits = traits.build(); + return this; + } + + public SpellcraftingRecipeJsonBuilder criterion(String name, CriterionConditions condition) { + advancementBuilder.criterion(name, condition); + return this; + } + + public SpellcraftingRecipeJsonBuilder group(String group) { + this.group = group; + return this; + } + + public void offerTo(Consumer exporter, Identifier id) { + if (!traits.isEmpty()) { + advancementBuilder.criterion("has_traits", TraitDiscoveredCriterion.create(traits.stream().map(Map.Entry::getKey).collect(Collectors.toUnmodifiableSet()))); + } + Preconditions.checkState(!advancementBuilder.getCriteria().isEmpty(), "No way of obtaining recipe " + id); + advancementBuilder + .parent(CraftingRecipeJsonBuilder.ROOT) + .criterion("has_the_recipe", RecipeUnlockedCriterion.create(id)) + .rewards(AdvancementRewards.Builder.recipe(id)) + .criteriaMerger(CriterionMerger.OR); + exporter.accept(new JsonProvider(id, id.withPrefixedPath("recipes/" + category.getName() + "/"), group, ingredients, traits)); + } + + public void offerTo(Consumer exporter) { + offerTo(exporter, output.spell().getId()); + } + + public void offerTo(Consumer exporter, String recipePath) { + Identifier recipeId = new Identifier(recipePath); + if (recipeId.equals(output.spell().getId())) { + throw new IllegalStateException("Recipe " + recipePath + " should remove its 'save' argument as it is equal to default one"); + } + offerTo(exporter, recipeId); + } + + record EnchantedIngredient (ItemConvertible gem, SpellType spell) { + JsonObject toJson(JsonObject json) { + json.addProperty("item", CraftingRecipeJsonBuilder.getItemId(gem).toString()); + if (!spell.isEmpty()) { + json.addProperty("spell", spell.getId().toString()); + } + return json; + } + } + + private class JsonProvider implements RecipeJsonProvider { + private final Identifier recipeId; + private final Identifier advancementId; + private final String group; + private final List ingredients; + private final SpellTraits traits; + + JsonProvider(Identifier recipeId, Identifier advancementId, String group, List ingredients, SpellTraits traits) { + this.recipeId = recipeId; + this.advancementId = advancementId; + this.group = group; + this.ingredients = new ArrayList<>(ingredients); + this.traits = traits; + } + + @Override + public void serialize(JsonObject json) { + json.addProperty("group", group); + json.add("material", base.toJson(new JsonObject())); + json.add("result", output.toJson(new JsonObject())); + JsonArray ingredientsJson = new JsonArray(); + ingredients.forEach(ingredient -> { + ingredientsJson.add(ingredient.toJson(new JsonObject())); + }); + json.add("ingredients", ingredientsJson); + JsonObject traitsJson = new JsonObject(); + traits.forEach(entry -> { + traitsJson.addProperty(entry.getKey().getId().toString(), entry.getValue()); + }); + json.add("traits", traitsJson); + } + + @Override + public Identifier getRecipeId() { + return recipeId; + } + + @Override + public RecipeSerializer getSerializer() { + return URecipes.TRAIT_REQUIREMENT; + } + + @Override + public JsonObject toAdvancementJson() { + return advancementBuilder.toJson(); + } + + @Override + public Identifier getAdvancementId() { + return advancementId; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java new file mode 100644 index 00000000..bb8df54e --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/TrickCraftingRecipeJsonBuilder.java @@ -0,0 +1,129 @@ +package com.minelittlepony.unicopia.datagen.providers.recipe; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.include.com.google.common.base.Preconditions; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; +import net.minecraft.advancement.Advancement; +import net.minecraft.advancement.AdvancementRewards; +import net.minecraft.advancement.CriterionMerger; +import net.minecraft.advancement.criterion.CriterionConditions; +import net.minecraft.advancement.criterion.RecipeUnlockedCriterion; +import net.minecraft.data.server.recipe.CraftingRecipeJsonBuilder; +import net.minecraft.data.server.recipe.RecipeJsonBuilder; +import net.minecraft.data.server.recipe.RecipeJsonProvider; +import net.minecraft.item.Item; +import net.minecraft.item.ItemConvertible; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.recipe.book.CraftingRecipeCategory; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.registry.Registries; +import net.minecraft.util.Identifier; + +public class TrickCraftingRecipeJsonBuilder extends RecipeJsonBuilder implements CraftingRecipeJsonBuilder { + private final Advancement.Builder advancementBuilder = Advancement.Builder.createUntelemetered(); + @Nullable + private String group; + private final RecipeCategory category; + private final Item output; + + private final List inputs = new ArrayList<>(); + + public TrickCraftingRecipeJsonBuilder(RecipeCategory category, ItemConvertible output) { + this.category = category; + this.output = output.asItem(); + } + + public static TrickCraftingRecipeJsonBuilder create(RecipeCategory category, ItemConvertible output) { + return new TrickCraftingRecipeJsonBuilder(category, output); + } + + @Override + public Item getOutputItem() { + return output; + } + + public TrickCraftingRecipeJsonBuilder input(ItemConvertible input) { + inputs.add(Ingredient.ofItems(input)); + return this; + } + + @Override + public TrickCraftingRecipeJsonBuilder criterion(String name, CriterionConditions condition) { + advancementBuilder.criterion(name, condition); + return this; + } + + @Override + public TrickCraftingRecipeJsonBuilder group(String group) { + this.group = group; + return this; + } + + @Override + public void offerTo(Consumer exporter, Identifier id) { + Preconditions.checkState(!advancementBuilder.getCriteria().isEmpty(), "No way of obtaining recipe " + id); + advancementBuilder + .parent(CraftingRecipeJsonBuilder.ROOT) + .criterion("has_the_recipe", RecipeUnlockedCriterion.create(id)) + .rewards(AdvancementRewards.Builder.recipe(id)) + .criteriaMerger(CriterionMerger.OR); + exporter.accept(new JsonProvider(id, id.withPrefixedPath("recipes/" + category.getName() + "/"), group == null ? "" : group, inputs)); + } + + private class JsonProvider extends RecipeJsonBuilder.CraftingRecipeJsonProvider { + private final Identifier recipeId; + private final String group; + private final List inputs; + private final Identifier advancementId; + + protected JsonProvider(Identifier recipeId, Identifier advancementId, String group, List inputs) { + super(CraftingRecipeCategory.MISC); + this.recipeId = recipeId; + this.advancementId = advancementId; + this.group = group; + this.inputs = new ArrayList<>(inputs); + } + + @Override + public void serialize(JsonObject json) { + super.serialize(json); + if (!group.isEmpty()) { + json.addProperty("group", group); + } + JsonArray jsonArray = new JsonArray(); + for (Ingredient ingredient : inputs) { + jsonArray.add(ingredient.toJson()); + } + json.add("ingredients", jsonArray); + json.addProperty("appearance", Registries.ITEM.getId(output).toString()); + } + + @Override + public RecipeSerializer getSerializer() { + return RecipeSerializer.SHAPELESS; + } + + @Override + public Identifier getRecipeId() { + return this.recipeId; + } + + @Override + @Nullable + public JsonObject toAdvancementJson() { + return advancementBuilder.toJson(); + } + + @Override + @Nullable + public Identifier getAdvancementId() { + return advancementId; + } + } +} diff --git a/src/main/java/com/minelittlepony/unicopia/datagen/providers/URecipeProvider.java b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java similarity index 72% rename from src/main/java/com/minelittlepony/unicopia/datagen/providers/URecipeProvider.java rename to src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java index 274be45f..942131c8 100644 --- a/src/main/java/com/minelittlepony/unicopia/datagen/providers/URecipeProvider.java +++ b/src/main/java/com/minelittlepony/unicopia/datagen/providers/recipe/URecipeProvider.java @@ -1,4 +1,4 @@ -package com.minelittlepony.unicopia.datagen.providers; +package com.minelittlepony.unicopia.datagen.providers.recipe; import java.util.Arrays; import java.util.List; @@ -8,13 +8,16 @@ import org.jetbrains.annotations.Nullable; import com.minelittlepony.unicopia.UConventionalTags; import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; +import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits; +import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait; import com.minelittlepony.unicopia.block.UBlocks; -import com.minelittlepony.unicopia.datagen.CraftingMaterialHelper; import com.minelittlepony.unicopia.datagen.ItemFamilies; import com.minelittlepony.unicopia.datagen.UBlockFamilies; -import com.minelittlepony.unicopia.datagen.providers.BedSheetPatternRecipeBuilder.PatternTemplate; +import com.minelittlepony.unicopia.datagen.providers.recipe.BedSheetPatternRecipeBuilder.PatternTemplate; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.item.URecipes; +import com.minelittlepony.unicopia.server.world.UTreeGen; import com.mojang.datafixers.util.Either; import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; @@ -25,6 +28,7 @@ import net.minecraft.block.Block; import net.minecraft.block.Blocks; import net.minecraft.data.server.recipe.ComplexRecipeJsonBuilder; import net.minecraft.data.server.recipe.RecipeJsonProvider; +import net.minecraft.data.server.recipe.RecipeProvider; import net.minecraft.data.server.recipe.ShapedRecipeJsonBuilder; import net.minecraft.data.server.recipe.ShapelessRecipeJsonBuilder; import net.minecraft.item.Item; @@ -54,6 +58,7 @@ public class URecipeProvider extends FabricRecipeProvider { offerCloudRecipes(exporter); offerFoodRecipes(exporter); offerGemstoneAndMagicRecipes(exporter); + offerMagicSpellRecipes(exporter); offerSeaponyRecipes(exporter); offerEarthPonyRecipes(exporter); @@ -102,11 +107,33 @@ public class URecipeProvider extends FabricRecipeProvider { offer2x2CompactingRecipe(exporter, RecipeCategory.DECORATIONS, UBlocks.SHAPING_BENCH, UBlocks.DENSE_CLOUD); generateFamily(exporter, UBlockFamilies.CLOUD_BRICKS); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CARVED_CLOUD, UBlocks.CLOUD); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.ETCHED_CLOUD, UBlocks.CLOUD); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_BRICKS, UBlocks.CLOUD); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_PLANKS, UBlocks.CLOUD); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_PILLAR, UBlocks.CLOUD); + + // TODO: Cut Cloud, Smooth Cloud, Polished Cloud, Raked Cloud + + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_SLAB, UBlocks.CLOUD, 2); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_STAIRS, UBlocks.CLOUD); + + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_BRICK_SLAB, UBlocks.CLOUD_BRICKS, 2); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_BRICK_STAIRS, UBlocks.CLOUD_BRICKS); + + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_PLANK_SLAB, UBlocks.CLOUD_PLANKS, 2); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.CLOUD_PLANK_STAIRS, UBlocks.CLOUD_PLANKS); + + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.DENSE_CLOUD_SLAB, UBlocks.DENSE_CLOUD, 2); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.DENSE_CLOUD_STAIRS, UBlocks.DENSE_CLOUD); + + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.ETCHED_CLOUD_SLAB, UBlocks.ETCHED_CLOUD, 2); + offerCloudShapingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.ETCHED_CLOUD_STAIRS, UBlocks.ETCHED_CLOUD); + offerCompactingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, UBlocks.DENSE_CLOUD, UBlocks.CLOUD, 4); generateFamily(exporter, UBlockFamilies.DENSE_CLOUD); offer2x3Recipe(exporter, UBlocks.CLOUD_DOOR, UBlocks.DENSE_CLOUD, "door"); - // XXX: Make the unstable cloud recipe shapeless and change output to 8 (to align with making jam toast) ShapelessRecipeJsonBuilder.create(RecipeCategory.REDSTONE, UBlocks.UNSTABLE_CLOUD, 8) .input(UBlocks.CLOUD, 8) .input(Ingredient.ofItems(UItems.LIGHTNING_JAR, UItems.ZAP_APPLE_JAM_JAR)) @@ -129,7 +156,6 @@ public class URecipeProvider extends FabricRecipeProvider { generateFamily(exporter, UBlockFamilies.ZAP); offerPlanksRecipe(exporter, UBlocks.ZAP_PLANKS, UTags.Items.ZAP_LOGS, 4); offerBarkBlockRecipe(exporter, UBlocks.ZAP_WOOD, UBlocks.ZAP_LOG); - // XXX: fixed not being able to craft stripped zap wood and waxed stripped zap wood offerBarkBlockRecipe(exporter, UBlocks.STRIPPED_ZAP_WOOD, UBlocks.STRIPPED_ZAP_LOG); // waxed zap wood @@ -147,12 +173,10 @@ public class URecipeProvider extends FabricRecipeProvider { } private void offerChitinBlocksRecipes(Consumer exporter) { - // XXX: Changed chitin recipe to be reversible offerReversibleCompactingRecipes(exporter, RecipeCategory.BUILDING_BLOCKS, UItems.CARAPACE, RecipeCategory.BUILDING_BLOCKS, UBlocks.CHITIN); generateFamily(exporter, UBlockFamilies.CHISELED_CHITIN); offerHiveRecipe(exporter, UBlocks.HIVE, UBlocks.CHITIN, UBlocks.MYSTERIOUS_EGG); offerHullRecipe(exporter, UBlocks.CHISELLED_CHITIN_HULL, UBlocks.CHISELLED_CHITIN, UBlocks.CHITIN); - // XXX: Changed spikes recipe to give 8 instead of 1 offerSpikesRecipe(exporter, UBlocks.CHITIN_SPIKES, UBlocks.CHITIN); // TODO: polished chitin @@ -164,9 +188,7 @@ public class URecipeProvider extends FabricRecipeProvider { } private void offerGemstoneAndMagicRecipes(Consumer exporter) { - // XXX: Change diamond to shard recipe to give 6 instead of 3 offerShapelessRecipe(exporter, UItems.CRYSTAL_SHARD, Items.DIAMOND, "crystal_shard", 6); - // XXX: Added recipe to get shards from amethyst shards offerShapelessRecipe(exporter, UItems.CRYSTAL_SHARD, Items.AMETHYST_SHARD, "crystal_shard", 3); offer2x2CompactingRecipe(exporter, RecipeCategory.MISC, UItems.GEMSTONE, UItems.CRYSTAL_SHARD); ShapelessRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.SPELLBOOK) @@ -206,14 +228,6 @@ public class URecipeProvider extends FabricRecipeProvider { .pattern("*#*") .offerTo(exporter); - // unicorn amulet - /*ShapelessRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.UNICORN_AMULET) - .input(UItems.PEGASUS_AMULET) - .input(UItems.CRYSTAL_HEART) - .input(UItems.GROGARS_BELL) - .input(Items.TOTEM_OF_UNDYING) - .offerTo(exporter);*/ - // friendship bracelet ShapedRecipeJsonBuilder.create(RecipeCategory.TOOLS, UItems.FRIENDSHIP_BRACELET) .input('*', Items.STRING) @@ -235,12 +249,65 @@ public class URecipeProvider extends FabricRecipeProvider { offerShapelessRecipe(exporter, Items.STICK, UItems.MEADOWBROOKS_STAFF, "stick", 2); } + private void offerMagicSpellRecipes(Consumer exporter) { + offerSpell(exporter, UItems.GEMSTONE, SpellType.DISPLACEMENT, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 10).with(Trait.CHAOS, 10)); + offerSpell(exporter, UItems.GEMSTONE, SpellType.FROST, new SpellTraits.Builder().with(Trait.ICE, 10)); + offerSpell(exporter, UItems.GEMSTONE, SpellType.SCORCH, new SpellTraits.Builder().with(Trait.FIRE, 10)); + offerSpell(exporter, UItems.GEMSTONE, SpellType.SHIELD, new SpellTraits.Builder().with(Trait.STRENGTH, 10).with(Trait.FOCUS, 6).with(Trait.POWER, 10)); + offerSpell(exporter, UItems.GEMSTONE, SpellType.TRANSFORMATION, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 10).with(Trait.LIFE, 10).with(Trait.CHAOS, 4)); + + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.ARCANE_PROTECTION, SpellType.SHIELD, new SpellTraits.Builder().with(Trait.STRENGTH, 10).with(Trait.KNOWLEDGE, 18).with(Trait.DARKNESS, 1)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.BUBBLE, SpellType.CATAPULT, new SpellTraits.Builder().with(Trait.WATER, 9).with(Trait.AIR, 9)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.CATAPULT, SpellType.FLAME, new SpellTraits.Builder().with(Trait.FOCUS, 9).with(Trait.AIR, 9)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.CHILLING_BREATH, SpellType.FROST, new SpellTraits.Builder().with(Trait.ICE, 5).with(Trait.KNOWLEDGE, 10)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.DARK_VORTEX, SpellType.VORTEX, new SpellTraits.Builder().with(Trait.STRENGTH, 10).with(Trait.KNOWLEDGE, 8).with(Trait.DARKNESS, 9).with(Trait.CHAOS, 8)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.FEATHER_FALL, SpellType.SHIELD, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 20).with(Trait.LIFE, 10).with(Trait.CHAOS, 4).with(Trait.GENEROSITY, 10)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.FIRE_BOLT, SpellType.FLAME, new SpellTraits.Builder().with(Trait.FOCUS, 9).with(Trait.FIRE, 30)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.FLAME, SpellType.SCORCH, new SpellTraits.Builder().with(Trait.FIRE, 15)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.INFERNAL, SpellType.FLAME, new SpellTraits.Builder().with(Trait.FIRE, 50).with(Trait.DARKNESS, 10)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.LIGHT, SpellType.FIRE_BOLT, new SpellTraits.Builder().with(Trait.ICE, 30).with(Trait.LIFE, 30).with(Trait.FOCUS, 10)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.MIMIC, SpellType.TRANSFORMATION, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 19).with(Trait.LIFE, 10).with(Trait.CHAOS, 4)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.MIND_SWAP, SpellType.MIMIC, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 19).with(Trait.LIFE, 10).with(Trait.CHAOS, 40)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.NECROMANCY, SpellType.SIPHONING, new SpellTraits.Builder().with(Trait.STRENGTH, 10).with(Trait.KNOWLEDGE, 8).with(Trait.DARKNESS, 19).with(Trait.CHAOS, 8).with(Trait.BLOOD, 10).with(Trait.POISON, 9)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.REVEALING, SpellType.SHIELD, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 18).with(Trait.LIFE, 1).with(Trait.ORDER, 4)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.SIPHONING, SpellType.INFERNAL, new SpellTraits.Builder().with(Trait.BLOOD, 8).with(Trait.POISON, 10)); + offerSpellFromSpell(exporter, UItems.GEMSTONE, SpellType.VORTEX, SpellType.SHIELD, new SpellTraits.Builder().with(Trait.STRENGTH, 10).with(Trait.KNOWLEDGE, 8).with(Trait.AIR, 9)); + + offerSpellFromTwoSpells(exporter, UItems.GEMSTONE, SpellType.DISPEL_EVIL, SpellType.ARCANE_PROTECTION, SpellType.DISPLACEMENT, new SpellTraits.Builder().with(Trait.KINDNESS, 1).with(Trait.POWER, 1)); + offerSpellFromTwoSpells(exporter, UItems.GEMSTONE, SpellType.HYDROPHOBIC, SpellType.FROST, SpellType.SHIELD, new SpellTraits.Builder().with(Trait.FOCUS, 6)); + offerSpellFromTwoSpells(exporter, UItems.GEMSTONE, SpellType.PORTAL, SpellType.DISPLACEMENT, SpellType.DARK_VORTEX, new SpellTraits.Builder().with(Trait.KNOWLEDGE, 18).with(Trait.CHAOS, 20)); + + SpellcraftingRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.ALICORN_AMULET, SpellType.EMPTY_KEY) + .base(UItems.GEMSTONE, SpellType.DARK_VORTEX) + .traits(new SpellTraits.Builder().with(Trait.DARKNESS, 30).with(Trait.POWER, 30).with(Trait.BLOOD, 30)) + .offerTo(exporter, "alicorn_amulet"); + + SpellcraftingRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.UNICORN_AMULET, SpellType.EMPTY_KEY) + .base(UItems.BROKEN_ALICORN_AMULET, SpellType.EMPTY_KEY) + .input(UItems.PEGASUS_AMULET, SpellType.EMPTY_KEY) + .input(UItems.CRYSTAL_HEART, SpellType.EMPTY_KEY) + .input(UItems.GROGARS_BELL, SpellType.EMPTY_KEY) + .input(Items.TOTEM_OF_UNDYING, SpellType.EMPTY_KEY) + .traits(new SpellTraits.Builder()) + .criterion(hasItem(UItems.BROKEN_ALICORN_AMULET), conditionsFromItem(UItems.BROKEN_ALICORN_AMULET)) + .offerTo(exporter, "unicorn_amulet"); + + SpellcraftingRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.DRAGON_BREATH_SCROLL, SpellType.EMPTY_KEY) + .base(Items.PAPER, SpellType.EMPTY_KEY) + .input(Items.PAPER, SpellType.EMPTY_KEY) + .traits(new SpellTraits.Builder().with(Trait.FIRE, 1)) + .offerTo(exporter, "dragon_breath_scroll"); + + ComplexSpellcraftingRecipeJsonBuilder.create(URecipes.SPELL_DUPLICATING, UItems.BOTCHED_GEM).offerTo(exporter, "spell_duplicating"); + ComplexSpellcraftingRecipeJsonBuilder.create(URecipes.TRAIT_COMBINING, UItems.BOTCHED_GEM).offerTo(exporter, "trait_combining_botched_gem"); + ComplexSpellcraftingRecipeJsonBuilder.create(URecipes.TRAIT_COMBINING, UItems.GEMSTONE).offerTo(exporter, "trait_combining_gemstone"); + } + private void offerFoodRecipes(Consumer exporter) { offerShapelessRecipe(exporter, UItems.PINEAPPLE_CROWN, UItems.PINEAPPLE, "seeds", 1); offerShapelessRecipe(exporter, UItems.SWEET_APPLE_SEEDS, UItems.SWEET_APPLE, "seeds", 3); offerShapelessRecipe(exporter, UItems.SOUR_APPLE_SEEDS, UItems.SOUR_APPLE, "seeds", 3); offerShapelessRecipe(exporter, UItems.GREEN_APPLE_SEEDS, UItems.GREEN_APPLE, "seeds", 3); - // XXX: Made golden oak seeds obtainable by crafting offerShapelessRecipe(exporter, UItems.GOLDEN_OAK_SEEDS, Items.GOLDEN_APPLE, "seeds", 1); offerPieRecipe(exporter, UItems.APPLE_PIE, UItems.APPLE_PIE_SLICE, Items.WHEAT, UTags.FRESH_APPLES); @@ -258,7 +325,6 @@ public class URecipeProvider extends FabricRecipeProvider { .group("juice") .offerTo(exporter); appendIngredients(ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.MUFFIN), Items.SUGAR, Items.EGG, Items.POTATO, UItems.JUICE, UItems.WHEAT_WORMS).offerTo(exporter); - // XXX: Removed the complex cider recipe ShapedRecipeJsonBuilder.create(RecipeCategory.MISC, UItems.MUG) .input('*', Items.IRON_NUGGET).criterion(hasItem(Items.IRON_NUGGET), conditionsFromItem(Items.IRON_NUGGET)) .input('#', UConventionalTags.STICKS).criterion(hasItem(Items.STICK), conditionsFromTag(UConventionalTags.STICKS)) @@ -266,7 +332,6 @@ public class URecipeProvider extends FabricRecipeProvider { .pattern("* *") .pattern(" # ") .offerTo(exporter); - // XXX: Changed the simple cider recipe to require apples appendIngredients(ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.CIDER), UItems.BURNED_JUICE, UItems.MUG) .input(Ingredient.fromTag(UTags.FRESH_APPLES)).criterion(hasItem(Items.APPLE), conditionsFromTag(UTags.FRESH_APPLES)) .offerTo(exporter); @@ -308,25 +373,42 @@ public class URecipeProvider extends FabricRecipeProvider { offerSmelting(exporter, List.of(UItems.TOAST), RecipeCategory.FOOD, UItems.BURNED_TOAST, 0.2F, 30, "bread"); offerSmelting(exporter, List.of(UItems.BURNED_JUICE, UItems.BURNED_TOAST), RecipeCategory.FOOD, Items.CHARCOAL, 1, 20, "coal"); offerSmelting(exporter, List.of(UItems.HAY_FRIES), RecipeCategory.FOOD, UItems.CRISPY_HAY_FRIES, 1F, 25, "hay_fries"); - // XXX: Increased experience from cooking zap apples offerSmelting(exporter, List.of(UItems.ZAP_APPLE), RecipeCategory.FOOD, UItems.COOKED_ZAP_APPLE, 1.2F, 430, "zap_apple"); - // XXX: Make zap apple jam jar recipe shapeless ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.ZAP_APPLE_JAM_JAR) .input(UItems.COOKED_ZAP_APPLE, 6).criterion(hasItem(UItems.COOKED_ZAP_APPLE), conditionsFromItem(UItems.COOKED_ZAP_APPLE)) .input(UItems.EMPTY_JAR) .offerTo(exporter); - // XXX: Make jam toast recipe shapeless ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.JAM_TOAST, 8) .input(UItems.ZAP_APPLE_JAM_JAR).criterion(hasItem(UItems.ZAP_APPLE_JAM_JAR), conditionsFromItem(UItems.ZAP_APPLE_JAM_JAR)) .input(UItems.TOAST, 8) .offerTo(exporter); - ShapelessRecipeJsonBuilder.create(RecipeCategory.FOOD, UItems.CANDIED_APPLE) .input(UConventionalTags.STICKS) .input(UTags.FRESH_APPLES).criterion(hasItem(UItems.ZAP_APPLE_JAM_JAR), conditionsFromItem(UItems.ZAP_APPLE_JAM_JAR)) .input(Items.SUGAR, 4) .offerTo(exporter); + + // trick apples + offerTrickRecipe(exporter, UItems.GREEN_APPLE, Items.GREEN_DYE); + offerTrickRecipe(exporter, Items.APPLE, Items.RED_DYE); + offerTrickRecipe(exporter, UItems.SOUR_APPLE, Items.YELLOW_DYE); + offerTrickRecipe(exporter, UItems.SWEET_APPLE, Items.ORANGE_DYE); + offerTrickRecipe(exporter, UItems.ROTTEN_APPLE, Items.ROTTEN_FLESH); + offerTrickRecipe(exporter, UItems.COOKED_ZAP_APPLE, Items.SPIDER_EYE); + offerTrickRecipe(exporter, Items.GOLDEN_APPLE, Items.GOLD_NUGGET); + offerTrickRecipe(exporter, Items.ENCHANTED_GOLDEN_APPLE, Items.GOLD_INGOT); + offerTrickRecipe(exporter, UItems.MANGO, Items.LIME_DYE); + offerTrickRecipe(exporter, UItems.PINEAPPLE, UItems.PINEAPPLE_CROWN); + offerTrickRecipe(exporter, UItems.HORSE_SHOE_FRIES, UItems.IRON_HORSE_SHOE); + offerTrickRecipe(exporter, UItems.MUFFIN, UItems.ROCK); + } + + public static void offerTrickRecipe(Consumer exporter, ItemConvertible output, ItemConvertible input) { + TrickCraftingRecipeJsonBuilder.create(RecipeCategory.FOOD, output) + .input(UItems.ZAP_APPLE).criterion(hasItem(UItems.ZAP_APPLE), conditionsFromItem(UItems.ZAP_APPLE)) + .input(input) + .offerTo(exporter, convertBetween(output, input) + "_trick"); } private void offerSeaponyRecipes(Consumer exporter) { @@ -376,12 +458,15 @@ public class URecipeProvider extends FabricRecipeProvider { .offerTo(exporter, convertBetween(Items.DIRT, UItems.WHEAT_WORMS)); offer2x2CompactingRecipe(exporter, RecipeCategory.BUILDING_BLOCKS, Items.COBBLESTONE, UItems.ROCK); - - // XXX: Made gravel <-> pebbles conversion reversable offerReversibleCompactingRecipesWithReverseRecipeGroup(exporter, RecipeCategory.MISC, UItems.PEBBLES, RecipeCategory.BUILDING_BLOCKS, Blocks.GRAVEL, convertBetween(UItems.PEBBLES, Blocks.GRAVEL), "pebbles"); - // XXX: Added sus gravel -> pebbles recipe offerShapelessRecipe(exporter, UItems.PEBBLES, Blocks.SUSPICIOUS_GRAVEL, "pebbles", 9); offerSmelting(exporter, List.of(UItems.GOLDEN_OAK_SEEDS, UItems.GOLDEN_FEATHER), RecipeCategory.MISC, Items.GOLD_NUGGET, 3F, 10, "gold_nugget"); + + offerGrowing(exporter, UBlocks.CURING_JOKE, Blocks.LAPIS_BLOCK, Blocks.CORNFLOWER); + offerGrowing(exporter, UBlocks.GOLD_ROOT, Blocks.RAW_GOLD_BLOCK, Blocks.CARROTS); + offerGrowing(exporter, UTreeGen.GOLDEN_APPLE_TREE.sapling().get(), Blocks.RAW_GOLD_BLOCK, Blocks.OAK_SAPLING); + offerGrowing(exporter, UBlocks.PLUNDER_VINE_BUD, Blocks.NETHERRACK, Blocks.WITHER_ROSE); + offerGrowing(exporter, UTreeGen.ZAP_APPLE_TREE.sapling().get(), UBlocks.CHITIN, Blocks.DARK_OAK_SAPLING); } private static ShapelessRecipeJsonBuilder appendIngredients(ShapelessRecipeJsonBuilder builder, ItemConvertible...ingredients) { @@ -522,8 +607,6 @@ public class URecipeProvider extends FabricRecipeProvider { private void offerBedSheetRecipes(Consumer exporter) { PatternTemplate.ONE_COLOR.offerWithoutConversion(exporter, UItems.KELP_BED_SHEETS, Items.KELP); - // XXX: Added white bed sheets, and added a recipe to dye white bed sheets any color - // XXX: Added recipes to change any bedsheet into any solid color using the right wool WOOLS.forEach(wool -> PatternTemplate.ONE_COLOR.offerTo(exporter, CraftingMaterialHelper.getItem(Unicopia.id(Registries.ITEM.getId(wool).getPath().replace("_wool", "_bed_sheets"))), wool)); PatternTemplate.TWO_COLOR.offerTo(exporter, UItems.APPLE_BED_SHEETS, Items.GREEN_WOOL, Items.LIME_WOOL); @@ -565,4 +648,42 @@ public class URecipeProvider extends FabricRecipeProvider { .group(getItemPath(output)) .offerTo(exporter, convertBetween(output, Items.HONEYCOMB)); } + + public static void offerCloudShapingRecipe(Consumer exporter, RecipeCategory category, ItemConvertible output, ItemConvertible input) { + offerCloudShapingRecipe(exporter, category, output, input, 1); + } + + public static void offerCloudShapingRecipe(Consumer exporter, RecipeCategory category, ItemConvertible output, ItemConvertible input, int count) { + CraftingMaterialHelper.createCloudShaping(Ingredient.ofItems(input), category, output, count) + .criterion(RecipeProvider.hasItem(input), RecipeProvider.conditionsFromItem(input)) + .offerTo(exporter, RecipeProvider.convertBetween(output, input) + "_cloud_shaping"); + } + + public static void offerGrowing(Consumer exporter, Block output, Block fuel, Block target) { + GrowingRecipeJsonBuilder.create(RecipeCategory.DECORATIONS, output.getDefaultState()) + .fuel(fuel.getDefaultState()) + .target(target).criterion(hasItem(target), conditionsFromItem(target)) + .offerTo(exporter); + } + + public void offerSpell(Consumer exporter, ItemConvertible gemstone, SpellType output, SpellTraits.Builder traits) { + SpellcraftingRecipeJsonBuilder.create(RecipeCategory.MISC, gemstone, output) + .traits(traits) + .offerTo(exporter); + } + + public void offerSpellFromSpell(Consumer exporter, ItemConvertible gemstone, SpellType output, SpellType input, SpellTraits.Builder traits) { + SpellcraftingRecipeJsonBuilder.create(RecipeCategory.MISC, gemstone, output) + .input(gemstone, input) + .traits(traits) + .offerTo(exporter); + } + + public void offerSpellFromTwoSpells(Consumer exporter, ItemConvertible gemstone, SpellType output, SpellType input1, SpellType input2, SpellTraits.Builder traits) { + SpellcraftingRecipeJsonBuilder.create(RecipeCategory.MISC, gemstone, output) + .input(gemstone, input1) + .input(gemstone, input2) + .traits(traits) + .offerTo(exporter); + } } diff --git a/src/main/resources/data/unicopia/recipes/alicorn_amulet.json b/src/main/resources/data/unicopia/recipes/alicorn_amulet.json deleted file mode 100644 index 14db2133..00000000 --- a/src/main/resources/data/unicopia/recipes/alicorn_amulet.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { - "item": "unicopia:gemstone", - "spell": "unicopia:dark_vortex" - }, - "traits": { - "darkness": 30, "power": 30, "blood": 30 - }, - "ingredients": [], - "result": { - "item": "unicopia:alicorn_amulet" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/carving/carved_cloud_cutting.json b/src/main/resources/data/unicopia/recipes/carving/carved_cloud_cutting.json deleted file mode 100644 index 4a933c98..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/carved_cloud_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud" }, - "result": "unicopia:carved_cloud", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_brick_slab_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_brick_slab_cutting.json deleted file mode 100644 index 80f2e283..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_brick_slab_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud_bricks" }, - "result": "unicopia:cloud_brick_slab", - "count": 2 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_brick_stairs_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_brick_stairs_cutting.json deleted file mode 100644 index 536622ad..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_brick_stairs_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud_bricks" }, - "result": "unicopia:cloud_brick_stairs", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_bricks_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_bricks_cutting.json deleted file mode 100644 index fde1cb89..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_bricks_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud" }, - "result": "unicopia:cloud_bricks", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_pillar_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_pillar_cutting.json deleted file mode 100644 index 1d60c72d..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_pillar_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud" }, - "result": "unicopia:cloud_pillar", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_plank_slab_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_plank_slab_cutting.json deleted file mode 100644 index 0ab285b9..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_plank_slab_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud_planks" }, - "result": "unicopia:cloud_plank_slab", - "count": 2 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_plank_stairs_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_plank_stairs_cutting.json deleted file mode 100644 index 77eed444..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_plank_stairs_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud_planks" }, - "result": "unicopia:cloud_plank_stairs", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_planks_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_planks_cutting.json deleted file mode 100644 index 97e40db7..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_planks_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud" }, - "result": "unicopia:cloud_planks", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_slab_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_slab_cutting.json deleted file mode 100644 index 03a75d8e..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_slab_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud" }, - "result": "unicopia:cloud_slab", - "count": 2 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/cloud_stairs_cutting.json b/src/main/resources/data/unicopia/recipes/carving/cloud_stairs_cutting.json deleted file mode 100644 index a43df56c..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/cloud_stairs_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:cloud" }, - "result": "unicopia:cloud_stairs", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/dense_cloud_slab_cutting.json b/src/main/resources/data/unicopia/recipes/carving/dense_cloud_slab_cutting.json deleted file mode 100644 index 45688bd5..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/dense_cloud_slab_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:dense_cloud" }, - "result": "unicopia:dense_cloud_slab", - "count": 2 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/dense_cloud_stairs_cutting.json b/src/main/resources/data/unicopia/recipes/carving/dense_cloud_stairs_cutting.json deleted file mode 100644 index 13b6e197..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/dense_cloud_stairs_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:dense_cloud" }, - "result": "unicopia:dense_cloud_stairs", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/etched_cloud_cutting.json b/src/main/resources/data/unicopia/recipes/carving/etched_cloud_cutting.json deleted file mode 100644 index 9f8b76ff..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/etched_cloud_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:dense_cloud" }, - "result": "unicopia:etched_cloud", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/etched_cloud_slab_cutting.json b/src/main/resources/data/unicopia/recipes/carving/etched_cloud_slab_cutting.json deleted file mode 100644 index 951b6f70..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/etched_cloud_slab_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:etched_cloud" }, - "result": "unicopia:etched_cloud_slab", - "count": 2 -} diff --git a/src/main/resources/data/unicopia/recipes/carving/etched_cloud_stairs_cutting.json b/src/main/resources/data/unicopia/recipes/carving/etched_cloud_stairs_cutting.json deleted file mode 100644 index 85ddf8e0..00000000 --- a/src/main/resources/data/unicopia/recipes/carving/etched_cloud_stairs_cutting.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "type": "unicopia:cloud_shaping", - "ingredient": { "item": "unicopia:etched_cloud" }, - "result": "unicopia:etched_cloud_stairs", - "count": 1 -} diff --git a/src/main/resources/data/unicopia/recipes/dragon_breath_scroll.json b/src/main/resources/data/unicopia/recipes/dragon_breath_scroll.json deleted file mode 100644 index 468565ca..00000000 --- a/src/main/resources/data/unicopia/recipes/dragon_breath_scroll.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { - "item": "minecraft:paper" - }, - "traits": { - "fire": 1 - }, - "ingredients": [ - { "item": "minecraft:paper" } - ], - "result": { - "item": "unicopia:dragon_breath_scroll" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/growing/curing_joke.json b/src/main/resources/data/unicopia/recipes/growing/curing_joke.json deleted file mode 100644 index 61625b41..00000000 --- a/src/main/resources/data/unicopia/recipes/growing/curing_joke.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:transform_crop", - "target": "minecraft:cornflower", - "consume": { - "Name": "minecraft:lapis_block", - "Properties": {} - }, - "output": { - "Name": "unicopia:curing_joke", - "Properties": {} - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/growing/gold_root.json b/src/main/resources/data/unicopia/recipes/growing/gold_root.json deleted file mode 100644 index a6d2d09b..00000000 --- a/src/main/resources/data/unicopia/recipes/growing/gold_root.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:transform_crop", - "target": "minecraft:carrots", - "consume": { - "Name": "minecraft:raw_gold_block", - "Properties": {} - }, - "output": { - "Name": "unicopia:gold_root", - "Properties": {} - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/growing/golden_oak_sapling.json b/src/main/resources/data/unicopia/recipes/growing/golden_oak_sapling.json deleted file mode 100644 index b129e3ae..00000000 --- a/src/main/resources/data/unicopia/recipes/growing/golden_oak_sapling.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:transform_crop", - "target": "minecraft:oak_sapling", - "consume": { - "Name": "minecraft:raw_gold_block", - "Properties": {} - }, - "output": { - "Name": "unicopia:golden_oak_sapling", - "Properties": {} - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/growing/plunder_vine.json b/src/main/resources/data/unicopia/recipes/growing/plunder_vine.json deleted file mode 100644 index df6a6eac..00000000 --- a/src/main/resources/data/unicopia/recipes/growing/plunder_vine.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:transform_crop", - "target": "minecraft:wither_rose", - "consume": { - "Name": "minecraft:netherrack", - "Properties": {} - }, - "output": { - "Name": "unicopia:plunder_vine_bud", - "Properties": {} - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/growing/zapling.json b/src/main/resources/data/unicopia/recipes/growing/zapling.json deleted file mode 100644 index 971c2099..00000000 --- a/src/main/resources/data/unicopia/recipes/growing/zapling.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:transform_crop", - "target": "minecraft:dark_oak_sapling", - "consume": { - "Name": "unicopia:chitin", - "Properties": {} - }, - "output": { - "Name": "unicopia:zapling", - "Properties": {} - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spell_duplicating_botched_gemstone.json b/src/main/resources/data/unicopia/recipes/spell_duplicating_botched_gemstone.json deleted file mode 100644 index 7994e225..00000000 --- a/src/main/resources/data/unicopia/recipes/spell_duplicating_botched_gemstone.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "unicopia:spellbook/duplicating", - "material": { "item": "unicopia:botched_gem" } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/arcane_protection.json b/src/main/resources/data/unicopia/recipes/spells/arcane_protection.json deleted file mode 100644 index 0e394aef..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/arcane_protection.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "strength": 10, "knowledge": 18, "darkness": 1 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:shield" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:arcane_protection" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/bubble.json b/src/main/resources/data/unicopia/recipes/spells/bubble.json deleted file mode 100644 index 49127861..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/bubble.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "water": 9, "air": 9 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:catapult" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:bubble" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/catapult.json b/src/main/resources/data/unicopia/recipes/spells/catapult.json deleted file mode 100644 index d479f3ad..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/catapult.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "focus": 9, "air": 9 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:flame" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:catapult" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/chilling_breath.json b/src/main/resources/data/unicopia/recipes/spells/chilling_breath.json deleted file mode 100644 index aabe879c..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/chilling_breath.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "ice": 5, - "knowledge": 10 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:frost" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:chilling_breath" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/dark_vortex.json b/src/main/resources/data/unicopia/recipes/spells/dark_vortex.json deleted file mode 100644 index 09c5d5d1..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/dark_vortex.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "strength": 10, "knowledge": 8, "darkness": 9, "chaos": 8 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:vortex" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:dark_vortex" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/dispel_evil.json b/src/main/resources/data/unicopia/recipes/spells/dispel_evil.json deleted file mode 100644 index e0993076..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/dispel_evil.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "kindness": 1, - "power": 1 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:arcane_protection" }, - { "item": "unicopia:gemstone", "spell": "unicopia:displacement" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:dispel_evil" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/displacement.json b/src/main/resources/data/unicopia/recipes/spells/displacement.json deleted file mode 100644 index 2cd2aa77..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/displacement.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 18, "chaos": 20 - }, - "ingredients": [], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:displacement" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/feather_fall.json b/src/main/resources/data/unicopia/recipes/spells/feather_fall.json deleted file mode 100644 index 0d3b161a..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/feather_fall.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 20, "life": 10, "chaos": 4, - "generosity": 10 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:shield" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:feather_fall" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/fire_bolt.json b/src/main/resources/data/unicopia/recipes/spells/fire_bolt.json deleted file mode 100644 index b9c4e45e..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/fire_bolt.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "focus": 9, "fire": 30 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:flame" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:fire_bolt" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/flame.json b/src/main/resources/data/unicopia/recipes/spells/flame.json deleted file mode 100644 index dca992e7..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/flame.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "fire": 15 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:scorch" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:flame" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/frost.json b/src/main/resources/data/unicopia/recipes/spells/frost.json deleted file mode 100644 index 4009534a..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/frost.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "ice": 15 - }, - "ingredients": [], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:frost" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/hydrophobic.json b/src/main/resources/data/unicopia/recipes/spells/hydrophobic.json deleted file mode 100644 index 681b1595..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/hydrophobic.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "focus": 6 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:frost" }, - { "item": "unicopia:gemstone", "spell": "unicopia:shield" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:hydrophobic" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/infernal.json b/src/main/resources/data/unicopia/recipes/spells/infernal.json deleted file mode 100644 index 9f2c8995..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/infernal.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "fire": 50, "darkness": 10 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:flame" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:infernal" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/light.json b/src/main/resources/data/unicopia/recipes/spells/light.json deleted file mode 100644 index daee45cb..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/light.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "ice": 30, "life": 30, "focus": 10 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:fire_bolt" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:light" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/mimic.json b/src/main/resources/data/unicopia/recipes/spells/mimic.json deleted file mode 100644 index 546c0908..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/mimic.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 19, "life": 10, "chaos": 4 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:transformation" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:mimic" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/mind_swap.json b/src/main/resources/data/unicopia/recipes/spells/mind_swap.json deleted file mode 100644 index c98d477b..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/mind_swap.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 19, "life": 10, "chaos": 40 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:mimic" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:mind_swap" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/necromancy.json b/src/main/resources/data/unicopia/recipes/spells/necromancy.json deleted file mode 100644 index bd106820..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/necromancy.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "strength": 10, "knowledge": 8, "darkness": 19, "chaos": 8, - "blood": 10, "poison": 9 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:siphoning" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:necromancy" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/portal.json b/src/main/resources/data/unicopia/recipes/spells/portal.json deleted file mode 100644 index 6e6f60f8..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/portal.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 18, "chaos": 20 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:displacement" }, - { "item": "unicopia:gemstone", "spell": "unicopia:dark_vortex" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:portal" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/reveal.json b/src/main/resources/data/unicopia/recipes/spells/reveal.json deleted file mode 100644 index 6b9f8c9c..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/reveal.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 18, "life": 1, "order": 4 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:shield" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:reveal" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/scorch.json b/src/main/resources/data/unicopia/recipes/spells/scorch.json deleted file mode 100644 index 499bce01..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/scorch.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "fire": 10 - }, - "ingredients": [], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:scorch" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/shield.json b/src/main/resources/data/unicopia/recipes/spells/shield.json deleted file mode 100644 index 2b12b91f..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/shield.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "strength": 10, "focus": 6, "power": 10 - }, - "ingredients": [], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:shield" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/siphoning.json b/src/main/resources/data/unicopia/recipes/spells/siphoning.json deleted file mode 100644 index 7c01454d..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/siphoning.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "blood": 8, "poison": 10 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:infernal" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:siphoning" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/transformation.json b/src/main/resources/data/unicopia/recipes/spells/transformation.json deleted file mode 100644 index 588cdcec..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/transformation.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "knowledge": 18, "life": 10, "chaos": 4 - }, - "ingredients": [], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:transformation" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/spells/vortex.json b/src/main/resources/data/unicopia/recipes/spells/vortex.json deleted file mode 100644 index 46e9a351..00000000 --- a/src/main/resources/data/unicopia/recipes/spells/vortex.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { "item": "unicopia:gemstone", "spell": "unicopia:none" }, - "traits": { - "strength": 10, "knowledge": 8, "air": 9 - }, - "ingredients": [ - { "item": "unicopia:gemstone", "spell": "unicopia:shield" } - ], - "result": { - "item": "unicopia:gemstone", - "spell": "unicopia:vortex" - } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trait_combining_botched_gemstone.json b/src/main/resources/data/unicopia/recipes/trait_combining_botched_gemstone.json deleted file mode 100644 index 9950b4dc..00000000 --- a/src/main/resources/data/unicopia/recipes/trait_combining_botched_gemstone.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "unicopia:spellbook/combining", - "material": { "item": "unicopia:botched_gem" } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trait_combining_gemstone.json b/src/main/resources/data/unicopia/recipes/trait_combining_gemstone.json deleted file mode 100644 index 13ab2a9f..00000000 --- a/src/main/resources/data/unicopia/recipes/trait_combining_gemstone.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "unicopia:spellbook/combining", - "material": { "item": "unicopia:gemstone" } -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trick_green_apple.json b/src/main/resources/data/unicopia/recipes/trick_green_apple.json deleted file mode 100644 index b914d534..00000000 --- a/src/main/resources/data/unicopia/recipes/trick_green_apple.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "unicopia:crafting_zap_apple", - "ingredients": [ - { "item": "unicopia:zap_apple" }, - { "item": "minecraft:green_dye" } - ], - "appearance": "unicopia:green_apple" -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trick_red_apple.json b/src/main/resources/data/unicopia/recipes/trick_red_apple.json deleted file mode 100644 index cd5095ea..00000000 --- a/src/main/resources/data/unicopia/recipes/trick_red_apple.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "unicopia:crafting_zap_apple", - "ingredients": [ - { "item": "unicopia:zap_apple" }, - { "item": "minecraft:red_dye" } - ], - "appearance": "minecraft:apple" -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trick_sour_apple.json b/src/main/resources/data/unicopia/recipes/trick_sour_apple.json deleted file mode 100644 index f5be4b69..00000000 --- a/src/main/resources/data/unicopia/recipes/trick_sour_apple.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "unicopia:crafting_zap_apple", - "ingredients": [ - { "item": "unicopia:zap_apple" }, - { "item": "minecraft:yellow_dye" } - ], - "appearance": "unicopia:sour_apple" -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trick_sweet_apple.json b/src/main/resources/data/unicopia/recipes/trick_sweet_apple.json deleted file mode 100644 index 48794044..00000000 --- a/src/main/resources/data/unicopia/recipes/trick_sweet_apple.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "unicopia:crafting_zap_apple", - "ingredients": [ - { "item": "unicopia:zap_apple" }, - { "item": "minecraft:orange_dye" } - ], - "appearance": "unicopia:sweet_apple" -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/trick_zap_apple.json b/src/main/resources/data/unicopia/recipes/trick_zap_apple.json deleted file mode 100644 index 38555616..00000000 --- a/src/main/resources/data/unicopia/recipes/trick_zap_apple.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "type": "unicopia:crafting_zap_apple", - "ingredients": [ - { "item": "unicopia:zap_apple" }, - { "item": "minecraft:rotten_flesh" } - ], - "appearance": "unicopia:cooked_zap_apple" -} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/unicorn_amulet.json b/src/main/resources/data/unicopia/recipes/unicorn_amulet.json deleted file mode 100644 index b5a4f434..00000000 --- a/src/main/resources/data/unicopia/recipes/unicorn_amulet.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "type": "unicopia:spellbook/crafting", - "material": { - "item": "unicopia:broken_alicorn_amulet" - }, - "traits": {}, - "ingredients": [ - { "item": "unicopia:pegasus_amulet" }, - { "item": "unicopia:crystal_heart" }, - { "item": "unicopia:grogars_bell" }, - { "item": "minecraft:totem_of_undying" } - ], - "result": { - "item": "unicopia:unicorn_amulet" - } -} \ No newline at end of file