diff --git a/Fabric/src/main/java/vazkii/patchouli/fabric/common/FabricModInitializer.java b/Fabric/src/main/java/vazkii/patchouli/fabric/common/FabricModInitializer.java index 7a830a8d..f197fc75 100644 --- a/Fabric/src/main/java/vazkii/patchouli/fabric/common/FabricModInitializer.java +++ b/Fabric/src/main/java/vazkii/patchouli/fabric/common/FabricModInitializer.java @@ -12,6 +12,7 @@ import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTabs; +import vazkii.patchouli.common.advancement.PatchouliCriteriaTriggers; import vazkii.patchouli.common.base.PatchouliSounds; import vazkii.patchouli.common.book.BookRegistry; import vazkii.patchouli.common.command.OpenBookCommand; @@ -26,6 +27,7 @@ public void onInitialize() { PatchouliSounds.submitRegistrations((id, e) -> Registry.register(BuiltInRegistries.SOUND_EVENT, id, e)); PatchouliItems.submitItemRegistrations((id, e) -> Registry.register(BuiltInRegistries.ITEM, id, e)); PatchouliItems.submitRecipeSerializerRegistrations((id, e) -> Registry.register(BuiltInRegistries.RECIPE_SERIALIZER, id, e)); + PatchouliCriteriaTriggers.submitTriggerRegistrations((id, e) -> Registry.register(BuiltInRegistries.TRIGGER_TYPES, id, e)); FiberPatchouliConfig.setup(); CommandRegistrationCallback.EVENT.register((disp, buildCtx, selection) -> OpenBookCommand.register(disp)); UseBlockCallback.EVENT.register(LecternEventHandler::rightClick); diff --git a/NeoForge/src/main/java/vazkii/patchouli/neoforge/common/NeoForgeModInitializer.java b/NeoForge/src/main/java/vazkii/patchouli/neoforge/common/NeoForgeModInitializer.java index 0379e48e..0dbecd5f 100644 --- a/NeoForge/src/main/java/vazkii/patchouli/neoforge/common/NeoForgeModInitializer.java +++ b/NeoForge/src/main/java/vazkii/patchouli/neoforge/common/NeoForgeModInitializer.java @@ -16,6 +16,7 @@ import net.neoforged.neoforge.registries.RegisterEvent; import vazkii.patchouli.api.PatchouliAPI; +import vazkii.patchouli.common.advancement.PatchouliCriteriaTriggers; import vazkii.patchouli.common.base.PatchouliSounds; import vazkii.patchouli.common.book.BookRegistry; import vazkii.patchouli.common.command.OpenBookCommand; @@ -45,6 +46,7 @@ public static void register(RegisterEvent evt) { evt.register(Registries.RECIPE_SERIALIZER, rh -> { PatchouliItems.submitRecipeSerializerRegistrations(rh::register); }); + evt.register(Registries.TRIGGER_TYPE, rh -> PatchouliCriteriaTriggers.submitTriggerRegistrations(rh::register)); } @SubscribeEvent diff --git a/Xplat/src/main/java/vazkii/patchouli/common/advancement/BookOpenTrigger.java b/Xplat/src/main/java/vazkii/patchouli/common/advancement/BookOpenTrigger.java new file mode 100644 index 00000000..0ec16145 --- /dev/null +++ b/Xplat/src/main/java/vazkii/patchouli/common/advancement/BookOpenTrigger.java @@ -0,0 +1,50 @@ +package vazkii.patchouli.common.advancement; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.advancements.critereon.*; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerPlayer; + +import net.minecraft.util.ExtraCodecs; +import vazkii.patchouli.api.PatchouliAPI; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +/** + * An advancement trigger for opening Patchouli books. + */ +public class BookOpenTrigger extends SimpleCriterionTrigger { + public static final ResourceLocation ID = new ResourceLocation(PatchouliAPI.MOD_ID, "open_book"); + public static final BookOpenTrigger INSTANCE = new BookOpenTrigger(); + + @NotNull + @Override + public Codec codec() { + return BookOpenTrigger.TriggerInstance.CODEC; + } + + public void trigger(@NotNull ServerPlayer player, @NotNull ResourceLocation book) { + trigger(player, instance -> instance.matches(book, null, 0)); + } + + public void trigger(@NotNull ServerPlayer player, @NotNull ResourceLocation book, @Nullable ResourceLocation entry, int page) { + trigger(player, instance -> instance.matches(book, entry, page)); + } + + public record TriggerInstance(Optional player, ResourceLocation book, Optional entry, MinMaxBounds.Ints page) implements SimpleInstance { + public static Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( + ExtraCodecs.strictOptionalField(EntityPredicate.ADVANCEMENT_CODEC, "player").forGetter(TriggerInstance::player), + ResourceLocation.CODEC.fieldOf("book").forGetter(TriggerInstance::book), + ExtraCodecs.strictOptionalField(ResourceLocation.CODEC, "entry").forGetter(TriggerInstance::entry), + ExtraCodecs.strictOptionalField(MinMaxBounds.Ints.CODEC, "page", MinMaxBounds.Ints.ANY).forGetter(TriggerInstance::page) + ).apply(instance, TriggerInstance::new)); + + public boolean matches(@NotNull ResourceLocation book, @Nullable ResourceLocation entry, int page) { + return this.book.equals(book) && (this.entry.isEmpty() || this.entry.get().equals(entry)) && this.page.matches(page); + } + } +} diff --git a/Xplat/src/main/java/vazkii/patchouli/common/advancement/PatchouliCriteriaTriggers.java b/Xplat/src/main/java/vazkii/patchouli/common/advancement/PatchouliCriteriaTriggers.java new file mode 100644 index 00000000..a936ca7b --- /dev/null +++ b/Xplat/src/main/java/vazkii/patchouli/common/advancement/PatchouliCriteriaTriggers.java @@ -0,0 +1,14 @@ +package vazkii.patchouli.common.advancement; + +import net.minecraft.advancements.CriterionTrigger; +import net.minecraft.resources.ResourceLocation; + +import java.util.function.BiConsumer; + +public class PatchouliCriteriaTriggers { + public static final BookOpenTrigger BOOK_OPEN = new BookOpenTrigger(); + + public static void submitTriggerRegistrations(BiConsumer> consumer) { + consumer.accept(BookOpenTrigger.ID, BOOK_OPEN); + } +} diff --git a/Xplat/src/main/java/vazkii/patchouli/common/base/PatchouliAPIImpl.java b/Xplat/src/main/java/vazkii/patchouli/common/base/PatchouliAPIImpl.java index e6b41701..610a906a 100644 --- a/Xplat/src/main/java/vazkii/patchouli/common/base/PatchouliAPIImpl.java +++ b/Xplat/src/main/java/vazkii/patchouli/common/base/PatchouliAPIImpl.java @@ -28,6 +28,7 @@ import vazkii.patchouli.client.book.template.BookTemplate; import vazkii.patchouli.client.book.text.BookTextParser; import vazkii.patchouli.client.handler.MultiblockVisualizationHandler; +import vazkii.patchouli.common.advancement.BookOpenTrigger; import vazkii.patchouli.common.book.Book; import vazkii.patchouli.common.book.BookRegistry; import vazkii.patchouli.common.item.ItemModBook; @@ -80,11 +81,13 @@ public boolean getConfigFlag(String flag) { @Override public void openBookGUI(ServerPlayer player, ResourceLocation book) { + BookOpenTrigger.INSTANCE.trigger(player, book); IXplatAbstractions.INSTANCE.sendOpenBookGui(player, book, null, 0); } @Override public void openBookEntry(ServerPlayer player, ResourceLocation book, ResourceLocation entry, int page) { + BookOpenTrigger.INSTANCE.trigger(player, book, entry, page); IXplatAbstractions.INSTANCE.sendOpenBookGui(player, book, entry, page); }