From 0a13e2d5cfefec618814910780a4398eba03a0ed Mon Sep 17 00:00:00 2001 From: Gegy Date: Sun, 16 Jun 2024 21:53:39 +0200 Subject: [PATCH] Add Rule Book item and configuration --- .../nucleoid/extras/NucleoidExtrasConfig.java | 8 +- .../java/xyz/nucleoid/extras/RulesConfig.java | 18 +++++ .../xyz/nucleoid/extras/lobby/NEItems.java | 16 +++- .../extras/lobby/item/RuleBookItem.java | 78 +++++++++++++++++++ .../data/nucleoid_extras/lang/en_us.json | 2 + 5 files changed, 118 insertions(+), 4 deletions(-) create mode 100644 src/main/java/xyz/nucleoid/extras/RulesConfig.java create mode 100644 src/main/java/xyz/nucleoid/extras/lobby/item/RuleBookItem.java diff --git a/src/main/java/xyz/nucleoid/extras/NucleoidExtrasConfig.java b/src/main/java/xyz/nucleoid/extras/NucleoidExtrasConfig.java index 87d8ab5..3c3dff1 100644 --- a/src/main/java/xyz/nucleoid/extras/NucleoidExtrasConfig.java +++ b/src/main/java/xyz/nucleoid/extras/NucleoidExtrasConfig.java @@ -36,6 +36,7 @@ public record NucleoidExtrasConfig( @Nullable IntegrationsConfig integrations, @Nullable CommandAliasConfig aliases, @Nullable ChatFilterConfig chatFilter, + @Nullable RulesConfig rules, @Nullable URL contributorDataUrl, ErrorReportingConfig errorReporting, boolean devServer, @@ -53,19 +54,20 @@ public record NucleoidExtrasConfig( IntegrationsConfig.CODEC.optionalFieldOf("integrations").forGetter(config -> Optional.ofNullable(config.integrations())), CommandAliasConfig.CODEC.optionalFieldOf("aliases").forGetter(config -> Optional.ofNullable(config.aliases())), ChatFilterConfig.CODEC.optionalFieldOf("chat_filter").forGetter(config -> Optional.ofNullable(config.chatFilter())), + RulesConfig.CODEC.optionalFieldOf("rules").forGetter(config -> Optional.ofNullable(config.rules())), MoreCodecs.url("https").optionalFieldOf("contributor_data_url").forGetter(config -> Optional.ofNullable(config.contributorDataUrl())), ErrorReportingConfig.CODEC.optionalFieldOf("error_reporting", ErrorReportingConfig.NONE).forGetter(NucleoidExtrasConfig::errorReporting), Codec.BOOL.optionalFieldOf("dev_server", false).forGetter(NucleoidExtrasConfig::devServer), ExtraCodecs.URI.optionalFieldOf("http_api").forGetter(config -> Optional.ofNullable(config.httpApi())) - ).apply(instance, (sidebar, gamePortalOpener, lobbySpawn, integrations, aliases, filter, contributorDataUrl, errorReporting, devServer, httpApiUrl) -> - new NucleoidExtrasConfig(sidebar, gamePortalOpener, lobbySpawn.orElse(null), integrations.orElse(null), aliases.orElse(null), filter.orElse(null), contributorDataUrl.orElse(null), errorReporting, devServer, httpApiUrl.orElse(null)) + ).apply(instance, (sidebar, gamePortalOpener, lobbySpawn, integrations, aliases, filter, rules, contributorDataUrl, errorReporting, devServer, httpApiUrl) -> + new NucleoidExtrasConfig(sidebar, gamePortalOpener, lobbySpawn.orElse(null), integrations.orElse(null), aliases.orElse(null), filter.orElse(null), rules.orElse(null), contributorDataUrl.orElse(null), errorReporting, devServer, httpApiUrl.orElse(null)) ) ); private static NucleoidExtrasConfig instance; private NucleoidExtrasConfig() { - this(false, Optional.empty(), null, null, null, null, null, ErrorReportingConfig.NONE, false, null); + this(false, Optional.empty(), null, null, null, null, null, null, ErrorReportingConfig.NONE, false, null); } @NotNull diff --git a/src/main/java/xyz/nucleoid/extras/RulesConfig.java b/src/main/java/xyz/nucleoid/extras/RulesConfig.java new file mode 100644 index 0000000..9fe7290 --- /dev/null +++ b/src/main/java/xyz/nucleoid/extras/RulesConfig.java @@ -0,0 +1,18 @@ +package xyz.nucleoid.extras; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.text.Text; +import xyz.nucleoid.codecs.MoreCodecs; +import xyz.nucleoid.plasmid.util.PlasmidCodecs; + +import java.util.List; + +public record RulesConfig( + List> pages +) { + private static final Codec> PAGE_CODEC = MoreCodecs.listOrUnit(PlasmidCodecs.TEXT); + public static final Codec CODEC = RecordCodecBuilder.create(i -> i.group( + PAGE_CODEC.listOf().fieldOf("pages").forGetter(RulesConfig::pages) + ).apply(i, RulesConfig::new)); +} diff --git a/src/main/java/xyz/nucleoid/extras/lobby/NEItems.java b/src/main/java/xyz/nucleoid/extras/lobby/NEItems.java index 7b54680..cdd95b5 100644 --- a/src/main/java/xyz/nucleoid/extras/lobby/NEItems.java +++ b/src/main/java/xyz/nucleoid/extras/lobby/NEItems.java @@ -22,6 +22,7 @@ import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; +import net.minecraft.util.Rarity; import net.minecraft.util.hit.BlockHitResult; import net.minecraft.util.hit.EntityHitResult; import net.minecraft.util.math.BlockPos; @@ -30,7 +31,13 @@ import xyz.nucleoid.extras.NucleoidExtras; import xyz.nucleoid.extras.NucleoidExtrasConfig; import xyz.nucleoid.extras.lobby.block.tater.TinyPotatoBlock; -import xyz.nucleoid.extras.lobby.item.*; +import xyz.nucleoid.extras.lobby.item.GamePortalOpenerItem; +import xyz.nucleoid.extras.lobby.item.LaunchFeatherItem; +import xyz.nucleoid.extras.lobby.item.LobbyBlockItem; +import xyz.nucleoid.extras.lobby.item.LobbyHeadItem; +import xyz.nucleoid.extras.lobby.item.LobbyTallBlockItem; +import xyz.nucleoid.extras.lobby.item.QuickArmorStandItem; +import xyz.nucleoid.extras.lobby.item.RuleBookItem; import xyz.nucleoid.extras.lobby.item.tater.CreativeTaterBoxItem; import xyz.nucleoid.extras.lobby.item.tater.TaterBoxItem; @@ -443,6 +450,8 @@ public class NEItems { public static final Item GAME_PORTAL_OPENER = new GamePortalOpenerItem(new Item.Settings().maxCount(1)); public static final Item LAUNCH_FEATHER = new LaunchFeatherItem(new Item.Settings().maxCount(1)); + public static final Item RULE_BOOK = new RuleBookItem(new Item.Settings().rarity(Rarity.EPIC)); + private static Item createHead(Block head) { if (head instanceof TinyPotatoBlock tinyPotatoBlock) { return new LobbyHeadItem(head, new Item.Settings(), tinyPotatoBlock.getItemTexture()); @@ -805,6 +814,7 @@ public static void register() { register("quick_armor_stand", QUICK_ARMOR_STAND); register("game_portal_opener", GAME_PORTAL_OPENER); register("launch_feather", LAUNCH_FEATHER); + register("rule_book", RULE_BOOK); PolymerItemGroupUtils.registerPolymerItemGroup(NucleoidExtras.identifier("general"), ITEM_GROUP); @@ -841,6 +851,10 @@ public static void giveLobbyItems(ServerPlayerEntity player) { tryOfferStack(player, TATER_BOX); + if (config.rules() != null) { + tryOfferStack(player, RULE_BOOK); + } + config.gamePortalOpener().ifPresent(gamePortal -> { tryOfferStack(player, GAME_PORTAL_OPENER, stack -> { GamePortalOpenerItem.setGamePortalId(stack, gamePortal); diff --git a/src/main/java/xyz/nucleoid/extras/lobby/item/RuleBookItem.java b/src/main/java/xyz/nucleoid/extras/lobby/item/RuleBookItem.java new file mode 100644 index 0000000..580cb1c --- /dev/null +++ b/src/main/java/xyz/nucleoid/extras/lobby/item/RuleBookItem.java @@ -0,0 +1,78 @@ +package xyz.nucleoid.extras.lobby.item; + +import eu.pb4.polymer.core.api.item.PolymerItem; +import net.minecraft.client.item.TooltipContext; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.nbt.NbtList; +import net.minecraft.nbt.NbtString; +import net.minecraft.network.packet.s2c.play.OpenWrittenBookS2CPacket; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.stat.Stats; +import net.minecraft.text.Text; +import net.minecraft.text.Texts; +import net.minecraft.util.CachedMapper; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.Util; +import net.minecraft.world.World; +import org.jetbrains.annotations.Nullable; +import xyz.nucleoid.extras.NucleoidExtrasConfig; +import xyz.nucleoid.extras.RulesConfig; +import xyz.nucleoid.server.translations.api.LocalizationTarget; +import xyz.nucleoid.server.translations.api.language.ServerLanguage; +import xyz.nucleoid.server.translations.impl.ServerTranslations; + +import java.util.List; + +public class RuleBookItem extends Item implements PolymerItem { + private static final CachedMapper ENCODED_PAGES = Util.cachedMapper(rules -> { + NbtList pages = new NbtList(); + for (List page : rules.pages()) { + Text combinedPage = Texts.join(page, Text.literal("\n")); + pages.add(NbtString.of(Text.Serialization.toJsonString(combinedPage))); + } + return pages; + }); + + public RuleBookItem(Settings settings) { + super(settings); + } + + @Override + public TypedActionResult use(World world, PlayerEntity user, Hand hand) { + ItemStack itemStack = user.getStackInHand(hand); + if (user instanceof ServerPlayerEntity serverPlayer) { + serverPlayer.networkHandler.sendPacket(new OpenWrittenBookS2CPacket(hand)); + } + user.incrementStat(Stats.USED.getOrCreateStat(this)); + return TypedActionResult.success(itemStack, world.isClient()); + } + + @Override + public Item getPolymerItem(ItemStack itemStack, @Nullable ServerPlayerEntity player) { + return Items.WRITTEN_BOOK; + } + + @Override + public ItemStack getPolymerItemStack(ItemStack itemStack, TooltipContext context, @Nullable ServerPlayerEntity player) { + LocalizationTarget localizationTarget = player != null ? LocalizationTarget.of(player) : LocalizationTarget.ofSystem(); + ServerLanguage targetLanguage = ServerTranslations.INSTANCE.getLanguage(localizationTarget); + + String translationKey = getTranslationKey(); + ItemStack book = PolymerItem.super.getPolymerItemStack(itemStack, context, player); + NbtCompound nbt = book.getOrCreateNbt(); + nbt.putString("title", targetLanguage.serverTranslations().get(translationKey)); + nbt.putString("author", targetLanguage.serverTranslations().get(translationKey + ".author")); + + RulesConfig rules = NucleoidExtrasConfig.get().rules(); + if (rules != null) { + nbt.put("pages", ENCODED_PAGES.map(rules)); + } + + return book; + } +} diff --git a/src/main/resources/data/nucleoid_extras/lang/en_us.json b/src/main/resources/data/nucleoid_extras/lang/en_us.json index b6d8d2c..c9dae3a 100644 --- a/src/main/resources/data/nucleoid_extras/lang/en_us.json +++ b/src/main/resources/data/nucleoid_extras/lang/en_us.json @@ -361,6 +361,8 @@ "item.nucleoid_extras.tater_box": "Tater Box", "item.nucleoid_extras.creative_tater_box": "Creative Tater Box", "item.nucleoid_extras.quick_armor_stand": "Quick Armor Stand (Lobby only!)", + "item.nucleoid_extras.rule_book": "Rule Book", + "item.nucleoid_extras.rule_book.author": "Server admins", "entity.nucleoid_extras.quick_armor_stand": "Quick Armor Stand",