From 1c033d5a0de5162b86d86e9221f26bc639c8d95f Mon Sep 17 00:00:00 2001 From: TheBrokenRail Date: Tue, 17 Mar 2020 20:42:02 -0400 Subject: [PATCH] 1.1.17 Update Mappings Add Spell-related Advancements --- CHANGELOG.md | 4 ++ gradle.properties | 4 +- .../sorcerycraft/SorceryCraft.java | 23 +++++++-- .../advancement/CreateSpellCriterion.java | 34 +++++++++++++ .../DiscoverAllSpellsCriterion.java | 51 +++++++++++++++++++ .../sorcerycraft/block/CastingTableBlock.java | 2 +- .../gui/CastingTableScreenHandler.java | 8 ++- .../sorcerycraft/item/SpellItem.java | 4 +- .../mixin/CriterionRegistryHook.java | 15 ++++++ .../packet/SelectSpellC2SPacket.java | 2 +- .../packet/UpdateKnownSpellsS2CPacket.java | 2 +- .../sorcerycraft/spell/util/SpellTag.java | 2 + .../assets/sorcerycraft/lang/en_us.json | 6 +++ .../advancements/adventure/create_spell.json | 23 +++++++++ .../adventure/discover_all_spells.json | 27 ++++++++++ .../adventure/discover_spell.json | 36 +++++++++++++ src/main/resources/sorcerycraft.mixins.json | 3 +- 17 files changed, 233 insertions(+), 13 deletions(-) create mode 100644 src/main/java/com/thebrokenrail/sorcerycraft/advancement/CreateSpellCriterion.java create mode 100644 src/main/java/com/thebrokenrail/sorcerycraft/advancement/DiscoverAllSpellsCriterion.java create mode 100644 src/main/java/com/thebrokenrail/sorcerycraft/mixin/CriterionRegistryHook.java create mode 100644 src/main/resources/data/sorcerycraft/advancements/adventure/create_spell.json create mode 100644 src/main/resources/data/sorcerycraft/advancements/adventure/discover_all_spells.json create mode 100644 src/main/resources/data/sorcerycraft/advancements/adventure/discover_spell.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 322b6e6..0c85e38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +**1.1.17** +* Update Mappings +* Add Spell-related Advancements + **1.1.16** * Consistent Gradle Project Name diff --git a/gradle.properties b/gradle.properties index f654ae4..8b2c892 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,11 +6,11 @@ org.gradle.jvmargs = -Xmx1G minecraft_version = 20w11a curseforge_id = 365308 simple_minecraft_version = 1.16-Snapshot - yarn_mappings = 20w11a+build.11 + yarn_mappings = 20w11a+build.17 fabric_loader_version = 0.7.8+build.187 # Mod Properties - mod_version = 1.1.16 + mod_version = 1.1.17 maven_group = com.thebrokenrail archives_base_name = sorcerycraft diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/SorceryCraft.java b/src/main/java/com/thebrokenrail/sorcerycraft/SorceryCraft.java index d3ed7eb..722dee9 100644 --- a/src/main/java/com/thebrokenrail/sorcerycraft/SorceryCraft.java +++ b/src/main/java/com/thebrokenrail/sorcerycraft/SorceryCraft.java @@ -1,5 +1,7 @@ package com.thebrokenrail.sorcerycraft; +import com.thebrokenrail.sorcerycraft.advancement.CreateSpellCriterion; +import com.thebrokenrail.sorcerycraft.advancement.DiscoverAllSpellsCriterion; import com.thebrokenrail.sorcerycraft.block.CastingTableBlock; import com.thebrokenrail.sorcerycraft.gui.CastingTableScreenHandler; import com.thebrokenrail.sorcerycraft.client.gui.CastingTableScreen; @@ -7,6 +9,7 @@ import com.thebrokenrail.sorcerycraft.client.entity.SpellEntityRenderer; import com.thebrokenrail.sorcerycraft.command.SpellCommand; import com.thebrokenrail.sorcerycraft.entity.SpellEntity; import com.thebrokenrail.sorcerycraft.item.SpellItem; +import com.thebrokenrail.sorcerycraft.mixin.CriterionRegistryHook; import com.thebrokenrail.sorcerycraft.packet.SelectSpellC2SPacket; import com.thebrokenrail.sorcerycraft.packet.UpdateKnownSpellsS2CPacket; import com.thebrokenrail.sorcerycraft.spell.util.RandomSpellLootTableFunction; @@ -62,11 +65,16 @@ import java.util.Objects; public class SorceryCraft implements ModInitializer, ClientModInitializer { public static final String NAMESPACE = "sorcerycraft"; + public static SpellItem SPELL_ITEM; + public static CastingTableBlock CASTING_TABLE_BLOCK; public static BlockItem CASTING_TABLE_BLOCK_ITEM; + public static ItemGroup ITEM_GROUP; + public static EntityType SPELL_ENTITY; + public static final Identifier[] LOOT_TABLES = new Identifier[]{ LootTables.SIMPLE_DUNGEON_CHEST, LootTables.END_CITY_TREASURE_CHEST, @@ -79,8 +87,12 @@ public class SorceryCraft implements ModInitializer, ClientModInitializer { LootTables.PILLAGER_OUTPOST_CHEST, LootTables.WOODLAND_MANSION_CHEST }; - public static Identifier STAT_INTERACT_WITH_CASTING_TABLE; - public static Identifier STAT_CAST_SPELL; + + public static Identifier INTERACT_WITH_CASTING_TABLE_STAT; + public static Identifier CAST_SPELL_STAT; + + public static DiscoverAllSpellsCriterion DISCOVER_ALL_SPELLS_CRITERION; + public static CreateSpellCriterion CREATE_SPELL_CRITERION; public static ModConfig getConfig() { return AutoConfig.getConfigHolder(ModConfig.class).getConfig(); @@ -158,8 +170,11 @@ public class SorceryCraft implements ModInitializer, ClientModInitializer { } }); - STAT_INTERACT_WITH_CASTING_TABLE = registerStat("interact_with_casting_table"); - STAT_CAST_SPELL = registerStat("cast_spell"); + INTERACT_WITH_CASTING_TABLE_STAT = registerStat("interact_with_casting_table"); + CAST_SPELL_STAT = registerStat("cast_spell"); + + DISCOVER_ALL_SPELLS_CRITERION = CriterionRegistryHook.callRegister(new DiscoverAllSpellsCriterion()); + CREATE_SPELL_CRITERION = CriterionRegistryHook.callRegister(new CreateSpellCriterion()); } private Identifier registerStat(String name) { diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/advancement/CreateSpellCriterion.java b/src/main/java/com/thebrokenrail/sorcerycraft/advancement/CreateSpellCriterion.java new file mode 100644 index 0000000..4c50f9a --- /dev/null +++ b/src/main/java/com/thebrokenrail/sorcerycraft/advancement/CreateSpellCriterion.java @@ -0,0 +1,34 @@ +package com.thebrokenrail.sorcerycraft.advancement; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import com.thebrokenrail.sorcerycraft.SorceryCraft; +import net.minecraft.advancement.criterion.AbstractCriterion; +import net.minecraft.advancement.criterion.AbstractCriterionConditions; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.Identifier; + +public class CreateSpellCriterion extends AbstractCriterion { + private static final Identifier ID = new Identifier(SorceryCraft.NAMESPACE, "create_spell"); + + public CreateSpellCriterion() { + } + + public Identifier getId() { + return ID; + } + + public CreateSpellCriterion.Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) { + return new CreateSpellCriterion.Conditions(); + } + + public void trigger(ServerPlayerEntity player) { + test(player.getAdvancementTracker(), (conditions) -> true); + } + + public static class Conditions extends AbstractCriterionConditions { + public Conditions() { + super(ID); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/advancement/DiscoverAllSpellsCriterion.java b/src/main/java/com/thebrokenrail/sorcerycraft/advancement/DiscoverAllSpellsCriterion.java new file mode 100644 index 0000000..e0bc01e --- /dev/null +++ b/src/main/java/com/thebrokenrail/sorcerycraft/advancement/DiscoverAllSpellsCriterion.java @@ -0,0 +1,51 @@ +package com.thebrokenrail.sorcerycraft.advancement; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonObject; +import com.thebrokenrail.sorcerycraft.SorceryCraft; +import com.thebrokenrail.sorcerycraft.spell.api.Spell; +import com.thebrokenrail.sorcerycraft.spell.registry.SpellRegistry; +import com.thebrokenrail.sorcerycraft.spell.util.SpellPlayerEntity; +import net.minecraft.advancement.criterion.AbstractCriterion; +import net.minecraft.advancement.criterion.AbstractCriterionConditions; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.util.Identifier; + +import java.util.Map; + +public class DiscoverAllSpellsCriterion extends AbstractCriterion { + private static final Identifier ID = new Identifier(SorceryCraft.NAMESPACE, "discover_all_spells"); + + public DiscoverAllSpellsCriterion() { + } + + public Identifier getId() { + return ID; + } + + public DiscoverAllSpellsCriterion.Conditions conditionsFromJson(JsonObject jsonObject, JsonDeserializationContext jsonDeserializationContext) { + return new DiscoverAllSpellsCriterion.Conditions(); + } + + public void trigger(ServerPlayerEntity player) { + test(player.getAdvancementTracker(), (conditions) -> { + SpellPlayerEntity spellPlayer = (SpellPlayerEntity) player; + Map spells = spellPlayer.getDiscoveredSpells(); + Spell[] maxSpells = SpellRegistry.getMaxSpells(); + boolean match = true; + for (Spell spell : maxSpells) { + if (!spells.containsKey(spell.getID()) || spells.get(spell.getID()) < (spell.getLevel() - 1)) { + match = false; + break; + } + } + return match; + }); + } + + public static class Conditions extends AbstractCriterionConditions { + public Conditions() { + super(ID); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/block/CastingTableBlock.java b/src/main/java/com/thebrokenrail/sorcerycraft/block/CastingTableBlock.java index e1f96a7..4c22b7f 100644 --- a/src/main/java/com/thebrokenrail/sorcerycraft/block/CastingTableBlock.java +++ b/src/main/java/com/thebrokenrail/sorcerycraft/block/CastingTableBlock.java @@ -29,7 +29,7 @@ public class CastingTableBlock extends Block { public ActionResult onUse(BlockState state, World world, BlockPos pos, PlayerEntity player, Hand hand, BlockHitResult hit) { if (!world.isClient()) { ContainerProviderRegistry.INSTANCE.openContainer(new Identifier(SorceryCraft.NAMESPACE, "casting_table"), player, (buf) -> buf.writeBlockPos(pos)); - player.incrementStat(SorceryCraft.STAT_INTERACT_WITH_CASTING_TABLE); + player.incrementStat(SorceryCraft.INTERACT_WITH_CASTING_TABLE_STAT); } return ActionResult.SUCCESS; } diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/gui/CastingTableScreenHandler.java b/src/main/java/com/thebrokenrail/sorcerycraft/gui/CastingTableScreenHandler.java index 327e3e7..ca9f1bc 100644 --- a/src/main/java/com/thebrokenrail/sorcerycraft/gui/CastingTableScreenHandler.java +++ b/src/main/java/com/thebrokenrail/sorcerycraft/gui/CastingTableScreenHandler.java @@ -15,6 +15,7 @@ import net.minecraft.screen.ScreenHandler; import net.minecraft.screen.ScreenHandlerContext; import net.minecraft.screen.ScreenHandlerType; import net.minecraft.screen.slot.Slot; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.Identifier; import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; @@ -97,7 +98,12 @@ public class CastingTableScreenHandler extends ScreenHandler { player.addExperienceLevels(-spells[index].getXPCost()); } - context.run((BiConsumer) SorceryCraft::playSpellSound); + context.run((world, blockPos) -> { + SorceryCraft.playSpellSound(world, blockPos); + if (!world.isClient()) { + SorceryCraft.CREATE_SPELL_CRITERION.trigger((ServerPlayerEntity) player); + } + }); CastingTableScreenHandler.this.inventory.setInvStack(0, ItemStack.EMPTY); CastingTableScreenHandler.this.inventory.takeInvStack(1, spells[index].getItemCost().getCount()); diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/item/SpellItem.java b/src/main/java/com/thebrokenrail/sorcerycraft/item/SpellItem.java index b391980..efd56dc 100644 --- a/src/main/java/com/thebrokenrail/sorcerycraft/item/SpellItem.java +++ b/src/main/java/com/thebrokenrail/sorcerycraft/item/SpellItem.java @@ -13,11 +13,11 @@ import net.minecraft.item.ItemGroup; import net.minecraft.item.ItemStack; import net.minecraft.text.Text; import net.minecraft.util.ActionResult; -import net.minecraft.util.DefaultedList; import net.minecraft.util.Hand; import net.minecraft.util.Identifier; import net.minecraft.util.Rarity; import net.minecraft.util.TypedActionResult; +import net.minecraft.util.collection.DefaultedList; import net.minecraft.world.World; import java.util.HashMap; @@ -36,7 +36,7 @@ public class SpellItem extends Item { if (!world.isClient()) { SorceryCraft.playSpellSound(playerEntity); - playerEntity.incrementStat(SorceryCraft.STAT_CAST_SPELL); + playerEntity.incrementStat(SorceryCraft.CAST_SPELL_STAT); SpellEntity entity = new SpellEntity(world, playerEntity); entity.setItem(itemStack); diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/mixin/CriterionRegistryHook.java b/src/main/java/com/thebrokenrail/sorcerycraft/mixin/CriterionRegistryHook.java new file mode 100644 index 0000000..af4c0f3 --- /dev/null +++ b/src/main/java/com/thebrokenrail/sorcerycraft/mixin/CriterionRegistryHook.java @@ -0,0 +1,15 @@ +package com.thebrokenrail.sorcerycraft.mixin; + +import net.minecraft.advancement.criterion.Criterion; +import net.minecraft.advancement.criterion.Criterions; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@SuppressWarnings("PublicStaticMixinMember") +@Mixin(Criterions.class) +public interface CriterionRegistryHook { + @Invoker("register") + static > T callRegister(T criterion) { + return criterion; + } +} diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/packet/SelectSpellC2SPacket.java b/src/main/java/com/thebrokenrail/sorcerycraft/packet/SelectSpellC2SPacket.java index 7239dad..45d4585 100644 --- a/src/main/java/com/thebrokenrail/sorcerycraft/packet/SelectSpellC2SPacket.java +++ b/src/main/java/com/thebrokenrail/sorcerycraft/packet/SelectSpellC2SPacket.java @@ -5,10 +5,10 @@ import com.thebrokenrail.sorcerycraft.gui.CastingTableScreenHandler; import io.netty.buffer.Unpooled; import net.fabricmc.fabric.api.network.PacketContext; import net.minecraft.client.MinecraftClient; +import net.minecraft.network.PacketByteBuf; import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket; import net.minecraft.screen.ScreenHandler; import net.minecraft.util.Identifier; -import net.minecraft.util.PacketByteBuf; public class SelectSpellC2SPacket { public static void handle(PacketContext context, PacketByteBuf bytes) { diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/packet/UpdateKnownSpellsS2CPacket.java b/src/main/java/com/thebrokenrail/sorcerycraft/packet/UpdateKnownSpellsS2CPacket.java index a3d3c2d..56c8dc8 100644 --- a/src/main/java/com/thebrokenrail/sorcerycraft/packet/UpdateKnownSpellsS2CPacket.java +++ b/src/main/java/com/thebrokenrail/sorcerycraft/packet/UpdateKnownSpellsS2CPacket.java @@ -6,10 +6,10 @@ import com.thebrokenrail.sorcerycraft.spell.util.SpellTag; import io.netty.buffer.Unpooled; import net.fabricmc.fabric.api.network.PacketContext; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.PacketByteBuf; import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.Identifier; -import net.minecraft.util.PacketByteBuf; public class UpdateKnownSpellsS2CPacket { public static void handle(PacketContext context, PacketByteBuf bytes) { diff --git a/src/main/java/com/thebrokenrail/sorcerycraft/spell/util/SpellTag.java b/src/main/java/com/thebrokenrail/sorcerycraft/spell/util/SpellTag.java index fd63c9e..c041933 100644 --- a/src/main/java/com/thebrokenrail/sorcerycraft/spell/util/SpellTag.java +++ b/src/main/java/com/thebrokenrail/sorcerycraft/spell/util/SpellTag.java @@ -8,6 +8,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; +import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; import net.minecraft.text.TranslatableText; @@ -124,6 +125,7 @@ public class SpellTag { if (changed) { SorceryCraft.playSpellSound(player); spellPlayer.setDiscoveredSpells(playerSpells); + SorceryCraft.DISCOVER_ALL_SPELLS_CRITERION.trigger((ServerPlayerEntity) player); } } } diff --git a/src/main/resources/assets/sorcerycraft/lang/en_us.json b/src/main/resources/assets/sorcerycraft/lang/en_us.json index 0f717e4..80193a9 100644 --- a/src/main/resources/assets/sorcerycraft/lang/en_us.json +++ b/src/main/resources/assets/sorcerycraft/lang/en_us.json @@ -19,6 +19,12 @@ "text.autoconfig.sorcerycraft.option.limitCastingTable": "Limit Casting Table To Discovered Spells", "text.autoconfig.sorcerycraft.option.limitCastingTable.creative": "Creative Mode", "text.autoconfig.sorcerycraft.option.limitCastingTable.survival": "Survival Mode", + "advancements.sorcerycraft.adventure.discover_spell.title": "Witchcraft!", + "advancements.sorcerycraft.adventure.discover_spell.description": "Discover a spell", + "advancements.sorcerycraft.adventure.create_spell.title": "Spellbinding!", + "advancements.sorcerycraft.adventure.create_spell.description": "Cast a spell using a Casting Table", + "advancements.sorcerycraft.adventure.discover_all_spells.title": "Master of Magic!", + "advancements.sorcerycraft.adventure.discover_all_spells.description": "Discover all spells", "spell.sorcerycraft.damage_spell": "Damage", "spell.sorcerycraft.heal_spell": "Heal", "spell.sorcerycraft.dissolve_spell": "Dissolve", diff --git a/src/main/resources/data/sorcerycraft/advancements/adventure/create_spell.json b/src/main/resources/data/sorcerycraft/advancements/adventure/create_spell.json new file mode 100644 index 0000000..7c9ee6f --- /dev/null +++ b/src/main/resources/data/sorcerycraft/advancements/adventure/create_spell.json @@ -0,0 +1,23 @@ +{ + "parent": "sorcerycraft:adventure/discover_spell", + "display": { + "icon": { + "item": "sorcerycraft:casting_table" + }, + "title": { + "translate": "advancements.sorcerycraft.adventure.create_spell.title" + }, + "description": { + "translate": "advancements.sorcerycraft.adventure.create_spell.description" + }, + "frame": "task", + "show_toast": true, + "announce_to_chat": true, + "hidden": false + }, + "criteria": { + "sorcerycraft:casting_table": { + "trigger": "sorcerycraft:create_spell" + } + } +} \ No newline at end of file diff --git a/src/main/resources/data/sorcerycraft/advancements/adventure/discover_all_spells.json b/src/main/resources/data/sorcerycraft/advancements/adventure/discover_all_spells.json new file mode 100644 index 0000000..5a8d485 --- /dev/null +++ b/src/main/resources/data/sorcerycraft/advancements/adventure/discover_all_spells.json @@ -0,0 +1,27 @@ +{ + "parent": "sorcerycraft:adventure/create_spell", + "display": { + "icon": { + "item": "sorcerycraft:spell", + "nbt": "{Spells: [{id: \"sorcerycraft:damage_spell\", level: 0}]}" + }, + "title": { + "translate": "advancements.sorcerycraft.adventure.discover_all_spells.title" + }, + "description": { + "translate": "advancements.sorcerycraft.adventure.discover_all_spells.description" + }, + "frame": "challenge", + "show_toast": true, + "announce_to_chat": true, + "hidden": false + }, + "criteria": { + "sorcerycraft:spell": { + "trigger": "sorcerycraft:discover_all_spells" + } + }, + "rewards": { + "experience": 100 + } +} \ No newline at end of file diff --git a/src/main/resources/data/sorcerycraft/advancements/adventure/discover_spell.json b/src/main/resources/data/sorcerycraft/advancements/adventure/discover_spell.json new file mode 100644 index 0000000..73f55ae --- /dev/null +++ b/src/main/resources/data/sorcerycraft/advancements/adventure/discover_spell.json @@ -0,0 +1,36 @@ +{ + "parent": "minecraft:adventure/root", + "display": { + "icon": { + "item": "sorcerycraft:spell" + }, + "title": { + "translate": "advancements.sorcerycraft.adventure.discover_spell.title" + }, + "description": { + "translate": "advancements.sorcerycraft.adventure.discover_spell.description" + }, + "frame": "task", + "show_toast": true, + "announce_to_chat": true, + "hidden": false + }, + "criteria": { + "sorcerycraft:spell": { + "trigger": "minecraft:inventory_changed", + "conditions": { + "items": [ + { + "item": "sorcerycraft:spell" + } + ] + } + } + }, + "rewards": { + "recipes": [ + "sorcerycraft:spell", + "sorcerycraft:casting_table" + ] + } +} \ No newline at end of file diff --git a/src/main/resources/sorcerycraft.mixins.json b/src/main/resources/sorcerycraft.mixins.json index 018166d..b828f46 100644 --- a/src/main/resources/sorcerycraft.mixins.json +++ b/src/main/resources/sorcerycraft.mixins.json @@ -7,7 +7,8 @@ ], "mixins": [ "MixinPlayerEntity", - "MixinServerPlayerEntity" + "MixinServerPlayerEntity", + "CriterionRegistryHook" ], "injectors": { "defaultRequire": 1