Public Access
This commit is contained in:
1 parent
3109938a97
commit
2b916ccd0b
19 files changed
+437
-24
No files matched your search
@@ -7,6 +7,7 @@ import net.dnorberg.rivencraft.registry.ModItems;
|
||||
import net.dnorberg.rivencraft.registry.ModBlocks;
|
||||
import net.dnorberg.rivencraft.registry.ModBlockEntities;
|
||||
import net.dnorberg.rivencraft.event.BookStandConversionHandler;
|
||||
import net.dnorberg.rivencraft.network.ModNetworking;
|
||||
import net.neoforged.bus.api.IEventBus;
|
||||
import net.neoforged.fml.common.Mod;
|
||||
import net.neoforged.neoforge.common.NeoForge;
|
||||
@@ -18,6 +19,7 @@ public final class Rivencraft {
|
||||
public static final Logger LOGGER = LogUtils.getLogger();
|
||||
|
||||
public Rivencraft(IEventBus modEventBus) {
|
||||
modEventBus.addListener(ModNetworking::register);
|
||||
ModDataComponents.register(modEventBus);
|
||||
ModBlocks.register(modEventBus);
|
||||
ModBlockEntities.register(modEventBus);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.dnorberg.rivencraft.book;
|
||||
|
||||
import com.mojang.serialization.Codec;
|
||||
import com.mojang.serialization.codecs.RecordCodecBuilder;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import java.util.UUID;
|
||||
import net.minecraft.core.UUIDUtil;
|
||||
@@ -13,11 +14,21 @@ import net.minecraft.network.codec.StreamCodec;
|
||||
* Books only retain the identifier so dimension regeneration or migration does
|
||||
* not invalidate every existing book.</p>
|
||||
*/
|
||||
public record AgeReference(UUID id) {
|
||||
public static final Codec<AgeReference> CODEC = UUIDUtil.STRING_CODEC.xmap(AgeReference::new, AgeReference::id);
|
||||
public record AgeReference(UUID id, String name) {
|
||||
private static final String UNNAMED_AGE = "Unnamed Age";
|
||||
private static final Codec<AgeReference> RECORD_CODEC = RecordCodecBuilder.create(instance -> instance.group(
|
||||
UUIDUtil.STRING_CODEC.fieldOf("id").forGetter(AgeReference::id),
|
||||
Codec.STRING.optionalFieldOf("name", UNNAMED_AGE).forGetter(AgeReference::name)
|
||||
).apply(instance, AgeReference::new));
|
||||
public static final Codec<AgeReference> CODEC = Codec.withAlternative(
|
||||
RECORD_CODEC,
|
||||
UUIDUtil.STRING_CODEC.xmap(id -> new AgeReference(id, UNNAMED_AGE), AgeReference::id)
|
||||
);
|
||||
public static final StreamCodec<ByteBuf, AgeReference> STREAM_CODEC = StreamCodec.composite(
|
||||
UUIDUtil.STREAM_CODEC,
|
||||
AgeReference::id,
|
||||
net.minecraft.network.codec.ByteBufCodecs.STRING_UTF8,
|
||||
AgeReference::name,
|
||||
AgeReference::new
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package net.dnorberg.rivencraft.client;
|
||||
|
||||
import net.dnorberg.rivencraft.client.screen.LinkingBookScreen;
|
||||
import net.dnorberg.rivencraft.client.screen.DescriptiveBookScreen;
|
||||
import net.dnorberg.rivencraft.registry.ModItems;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.neoforged.neoforge.event.entity.player.PlayerInteractEvent;
|
||||
|
||||
public final class ClientBookInteractionHandler {
|
||||
private ClientBookInteractionHandler() {
|
||||
}
|
||||
|
||||
public static void onRightClickItem(PlayerInteractEvent.RightClickItem event) {
|
||||
boolean linkingBook = event.getItemStack().is(ModItems.LINKING_BOOK.get());
|
||||
boolean descriptiveBook = event.getItemStack().is(ModItems.DESCRIPTIVE_BOOK.get());
|
||||
if (!linkingBook && !descriptiveBook) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.setCanceled(true);
|
||||
event.setCancellationResult(InteractionResult.SUCCESS);
|
||||
if (linkingBook) {
|
||||
Minecraft.getInstance().setScreen(new LinkingBookScreen(event.getHand(), event.getItemStack().copy()));
|
||||
} else {
|
||||
Minecraft.getInstance().setScreen(new DescriptiveBookScreen(event.getItemStack().copy()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,8 @@ import net.dnorberg.rivencraft.registry.ModBlockEntities;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
import net.neoforged.fml.common.EventBusSubscriber;
|
||||
import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent;
|
||||
import net.neoforged.neoforge.common.NeoForge;
|
||||
import net.neoforged.neoforge.client.event.EntityRenderersEvent;
|
||||
|
||||
@EventBusSubscriber(modid = Rivencraft.MOD_ID, value = Dist.CLIENT)
|
||||
@@ -16,4 +18,9 @@ public final class ClientEvents {
|
||||
public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) {
|
||||
event.registerBlockEntityRenderer(ModBlockEntities.BOOK_STAND.get(), BookStandRenderer::new);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void clientSetup(FMLClientSetupEvent event) {
|
||||
NeoForge.EVENT_BUS.addListener(ClientBookInteractionHandler::onRightClickItem);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package net.dnorberg.rivencraft.client.preview;
|
||||
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
|
||||
public interface DestinationPreviewRenderer extends AutoCloseable {
|
||||
void tick();
|
||||
|
||||
void render(GuiGraphics graphics, int left, int top, int width, int height, float partialTick);
|
||||
|
||||
@Override
|
||||
default void close() {
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
package net.dnorberg.rivencraft.client.preview;
|
||||
|
||||
import net.createmod.ponder.api.level.PonderLevel;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
|
||||
/**
|
||||
* Initial Ponder-backed preview boundary.
|
||||
*
|
||||
* <p>The isolated level is ready to receive server-provided snapshot blocks.
|
||||
* Until snapshot networking lands, the panel renders an animated loading
|
||||
* state rather than reading arbitrary remote chunks from the client.</p>
|
||||
*/
|
||||
public final class PonderDestinationPreviewRenderer implements DestinationPreviewRenderer {
|
||||
private final PonderLevel previewLevel;
|
||||
private int ticks;
|
||||
|
||||
public PonderDestinationPreviewRenderer() {
|
||||
Minecraft minecraft = Minecraft.getInstance();
|
||||
previewLevel = new PonderLevel(BlockPos.ZERO, minecraft.level);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
ticks++;
|
||||
previewLevel.tick();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(GuiGraphics graphics, int left, int top, int width, int height, float partialTick) {
|
||||
graphics.fill(left, top, left + width, top + height, 0xFF080C18);
|
||||
graphics.renderOutline(left, top, width, height, 0xFF7B6AA8);
|
||||
|
||||
double angle = (ticks + partialTick) * 0.04;
|
||||
int centerX = left + width / 2;
|
||||
int centerY = top + height / 2;
|
||||
int orbitX = centerX + (int)(Math.cos(angle) * Math.max(8, width / 4));
|
||||
int orbitY = centerY + (int)(Math.sin(angle) * Math.max(4, height / 8));
|
||||
graphics.fill(orbitX - 2, orbitY - 2, orbitX + 3, orbitY + 3, 0xFF8ED6FF);
|
||||
graphics.drawCenteredString(
|
||||
Minecraft.getInstance().font,
|
||||
Component.translatable("screen.rivencraft.book.preview_pending"),
|
||||
centerX,
|
||||
centerY - 4,
|
||||
0xFFB8C5E0
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package net.dnorberg.rivencraft.client.screen;
|
||||
|
||||
import net.dnorberg.rivencraft.book.AgeReference;
|
||||
import net.dnorberg.rivencraft.registry.ModDataComponents;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
|
||||
public final class DescriptiveBookScreen extends Screen {
|
||||
private final AgeReference age;
|
||||
|
||||
public DescriptiveBookScreen(ItemStack book) {
|
||||
super(book.getHoverName());
|
||||
age = book.get(ModDataComponents.AGE_REFERENCE.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
addRenderableWidget(Button.builder(Component.translatable("gui.done"), button -> onClose())
|
||||
.bounds(width / 2 - 75, height / 2 + 55, 150, 20)
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
|
||||
super.render(graphics, mouseX, mouseY, partialTick);
|
||||
int centerX = width / 2;
|
||||
graphics.drawCenteredString(font, title, centerX, height / 2 - 70, 0xFFFFFFFF);
|
||||
if (age == null) {
|
||||
graphics.drawCenteredString(font, Component.translatable("screen.rivencraft.book.unwritten"),
|
||||
centerX, height / 2 - 4, 0xFFAAAAAA);
|
||||
} else {
|
||||
graphics.drawCenteredString(font, Component.literal(age.name()), centerX, height / 2 - 16, 0xFFE7D7A9);
|
||||
graphics.drawCenteredString(font, Component.literal(age.id().toString()), centerX, height / 2 + 4, 0xFF777777);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
package net.dnorberg.rivencraft.client.screen;
|
||||
|
||||
import net.dnorberg.rivencraft.book.LinkTarget;
|
||||
import net.dnorberg.rivencraft.client.preview.DestinationPreviewRenderer;
|
||||
import net.dnorberg.rivencraft.client.preview.PonderDestinationPreviewRenderer;
|
||||
import net.dnorberg.rivencraft.network.BindLinkingBookPayload;
|
||||
import net.dnorberg.rivencraft.network.ModNetworking;
|
||||
import net.dnorberg.rivencraft.network.UseLinkingBookPayload;
|
||||
import net.dnorberg.rivencraft.registry.ModDataComponents;
|
||||
import net.minecraft.client.gui.GuiGraphics;
|
||||
import net.minecraft.client.gui.components.Button;
|
||||
import net.minecraft.client.gui.components.EditBox;
|
||||
import net.minecraft.client.gui.screens.Screen;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.neoforge.network.PacketDistributor;
|
||||
|
||||
public final class LinkingBookScreen extends Screen {
|
||||
private static final int PANEL_WIDTH = 180;
|
||||
private static final int PREVIEW_HEIGHT = 100;
|
||||
|
||||
private final InteractionHand hand;
|
||||
private final ItemStack book;
|
||||
private final LinkTarget target;
|
||||
private DestinationPreviewRenderer preview;
|
||||
private EditBox titleInput;
|
||||
|
||||
public LinkingBookScreen(InteractionHand hand, ItemStack book) {
|
||||
super(book.getHoverName());
|
||||
this.hand = hand;
|
||||
this.book = book;
|
||||
target = book.get(ModDataComponents.LINK_TARGET.get());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void init() {
|
||||
int left = (width - PANEL_WIDTH) / 2;
|
||||
int buttonY = height / 2 + 72;
|
||||
if (target == null) {
|
||||
titleInput = new EditBox(font, left, height / 2 - 10, PANEL_WIDTH, 20,
|
||||
Component.translatable("screen.rivencraft.book.title"));
|
||||
titleInput.setMaxLength(ModNetworking.MAX_BOOK_TITLE_LENGTH);
|
||||
titleInput.setHint(Component.translatable("screen.rivencraft.book.title_hint"));
|
||||
addRenderableWidget(titleInput);
|
||||
setInitialFocus(titleInput);
|
||||
addRenderableWidget(Button.builder(Component.translatable("screen.rivencraft.book.bind"), button -> bind())
|
||||
.bounds(left, height / 2 + 20, 86, 20)
|
||||
.build());
|
||||
addRenderableWidget(Button.builder(Component.translatable("gui.cancel"), button -> onClose())
|
||||
.bounds(left + 94, height / 2 + 20, 86, 20)
|
||||
.build());
|
||||
} else {
|
||||
preview = new PonderDestinationPreviewRenderer();
|
||||
addRenderableWidget(Button.builder(Component.translatable("screen.rivencraft.book.link"), button -> link())
|
||||
.bounds(left, buttonY, 86, 20)
|
||||
.build());
|
||||
addRenderableWidget(Button.builder(Component.translatable("gui.done"), button -> onClose())
|
||||
.bounds(left + 94, buttonY, 86, 20)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
if (preview != null) {
|
||||
preview.tick();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void render(GuiGraphics graphics, int mouseX, int mouseY, float partialTick) {
|
||||
super.render(graphics, mouseX, mouseY, partialTick);
|
||||
int centerX = width / 2;
|
||||
graphics.drawCenteredString(font, title, centerX, height / 2 - 82, 0xFFFFFFFF);
|
||||
if (target == null) {
|
||||
graphics.drawCenteredString(font, Component.translatable("screen.rivencraft.book.name_prompt"),
|
||||
centerX, height / 2 - 34, 0xFFB8B8B8);
|
||||
return;
|
||||
}
|
||||
|
||||
int left = (width - PANEL_WIDTH) / 2;
|
||||
int previewTop = height / 2 - 60;
|
||||
preview.render(graphics, left, previewTop, PANEL_WIDTH, PREVIEW_HEIGHT, partialTick);
|
||||
BlockPos pos = target.location().pos();
|
||||
graphics.drawCenteredString(font, Component.literal(
|
||||
target.location().dimension().location() + " " + pos.getX() + ", " + pos.getY() + ", " + pos.getZ()),
|
||||
centerX, previewTop + PREVIEW_HEIGHT + 8, 0xFFB8B8B8);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removed() {
|
||||
if (preview != null) {
|
||||
preview.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void bind() {
|
||||
String name = titleInput.getValue().strip();
|
||||
if (!name.isEmpty()) {
|
||||
PacketDistributor.sendToServer(new BindLinkingBookPayload(hand == InteractionHand.OFF_HAND, name));
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
|
||||
private void link() {
|
||||
PacketDistributor.sendToServer(new UseLinkingBookPayload(hand == InteractionHand.OFF_HAND));
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
@@ -37,7 +37,7 @@ public final class DescriptiveBookItem extends Item {
|
||||
AgeReference age = stack.get(ModDataComponents.AGE_REFERENCE.get());
|
||||
MutableComponent status = age == null
|
||||
? Component.translatable("item.rivencraft.descriptive_book.unwritten")
|
||||
: Component.translatable("item.rivencraft.descriptive_book.age", age.shortId());
|
||||
: Component.translatable("item.rivencraft.descriptive_book.age", age.name());
|
||||
tooltipComponents.add(status.withStyle(ChatFormatting.GRAY));
|
||||
}
|
||||
}
|
||||
@@ -33,19 +33,9 @@ public final class LinkingBookItem extends Item {
|
||||
|
||||
LinkTarget target = stack.get(ModDataComponents.LINK_TARGET.get());
|
||||
if (target == null) {
|
||||
if (!player.isShiftKeyDown()) {
|
||||
player.displayClientMessage(Component.translatable("message.rivencraft.linking_book.bind_hint"), true);
|
||||
return InteractionResultHolder.fail(stack);
|
||||
}
|
||||
|
||||
target = LinkTarget.from(serverPlayer);
|
||||
stack.set(ModDataComponents.LINK_TARGET.get(), target);
|
||||
level.playSound(null, player.blockPosition(), SoundEvents.BOOK_PAGE_TURN, SoundSource.PLAYERS, 1.0F, 1.0F);
|
||||
player.displayClientMessage(Component.translatable("message.rivencraft.linking_book.bound"), true);
|
||||
return InteractionResultHolder.success(stack);
|
||||
return InteractionResultHolder.consume(stack);
|
||||
}
|
||||
|
||||
return useBoundBook(serverPlayer, stack);
|
||||
return InteractionResultHolder.consume(stack);
|
||||
}
|
||||
|
||||
public static InteractionResultHolder<ItemStack> useBoundBook(ServerPlayer player, ItemStack stack) {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package net.dnorberg.rivencraft.network;
|
||||
|
||||
import net.dnorberg.rivencraft.Rivencraft;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public record BindLinkingBookPayload(boolean offhand, String title) implements CustomPacketPayload {
|
||||
public static final Type<BindLinkingBookPayload> TYPE = new Type<>(
|
||||
ResourceLocation.fromNamespaceAndPath(Rivencraft.MOD_ID, "bind_linking_book")
|
||||
);
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, BindLinkingBookPayload> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.BOOL,
|
||||
BindLinkingBookPayload::offhand,
|
||||
ByteBufCodecs.STRING_UTF8,
|
||||
BindLinkingBookPayload::title,
|
||||
BindLinkingBookPayload::new
|
||||
);
|
||||
|
||||
@Override
|
||||
public Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package net.dnorberg.rivencraft.network;
|
||||
|
||||
import net.dnorberg.rivencraft.book.LinkTarget;
|
||||
import net.dnorberg.rivencraft.item.LinkingBookItem;
|
||||
import net.dnorberg.rivencraft.registry.ModDataComponents;
|
||||
import net.dnorberg.rivencraft.registry.ModItems;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.neoforged.neoforge.network.event.RegisterPayloadHandlersEvent;
|
||||
import net.neoforged.neoforge.network.handling.IPayloadContext;
|
||||
import net.neoforged.neoforge.network.registration.PayloadRegistrar;
|
||||
|
||||
public final class ModNetworking {
|
||||
public static final int MAX_BOOK_TITLE_LENGTH = 32;
|
||||
|
||||
private ModNetworking() {
|
||||
}
|
||||
|
||||
public static void register(RegisterPayloadHandlersEvent event) {
|
||||
PayloadRegistrar registrar = event.registrar("1");
|
||||
registrar.playToServer(BindLinkingBookPayload.TYPE, BindLinkingBookPayload.STREAM_CODEC, ModNetworking::bindBook);
|
||||
registrar.playToServer(UseLinkingBookPayload.TYPE, UseLinkingBookPayload.STREAM_CODEC, ModNetworking::useBook);
|
||||
}
|
||||
|
||||
private static void bindBook(BindLinkingBookPayload payload, IPayloadContext context) {
|
||||
if (!(context.player() instanceof ServerPlayer player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack stack = player.getItemInHand(hand(payload.offhand()));
|
||||
if (!stack.is(ModItems.LINKING_BOOK.get()) || stack.has(ModDataComponents.LINK_TARGET.get())) {
|
||||
return;
|
||||
}
|
||||
|
||||
String title = normalizeTitle(payload.title());
|
||||
if (title.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
stack.set(ModDataComponents.LINK_TARGET.get(), LinkTarget.from(player));
|
||||
stack.set(DataComponents.CUSTOM_NAME, Component.literal(title));
|
||||
player.level().playSound(null, player.blockPosition(), SoundEvents.BOOK_PAGE_TURN, SoundSource.PLAYERS, 1.0F, 1.0F);
|
||||
player.displayClientMessage(Component.translatable("message.rivencraft.linking_book.bound", title), true);
|
||||
}
|
||||
|
||||
private static void useBook(UseLinkingBookPayload payload, IPayloadContext context) {
|
||||
if (!(context.player() instanceof ServerPlayer player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ItemStack stack = player.getItemInHand(hand(payload.offhand()));
|
||||
if (stack.is(ModItems.LINKING_BOOK.get()) && stack.has(ModDataComponents.LINK_TARGET.get())) {
|
||||
LinkingBookItem.useBoundBook(player, stack);
|
||||
}
|
||||
}
|
||||
|
||||
private static InteractionHand hand(boolean offhand) {
|
||||
return offhand ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND;
|
||||
}
|
||||
|
||||
private static String normalizeTitle(String title) {
|
||||
String normalized = title.strip();
|
||||
return normalized.length() <= MAX_BOOK_TITLE_LENGTH
|
||||
? normalized
|
||||
: normalized.substring(0, MAX_BOOK_TITLE_LENGTH).stripTrailing();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package net.dnorberg.rivencraft.network;
|
||||
|
||||
import net.dnorberg.rivencraft.Rivencraft;
|
||||
import net.minecraft.network.RegistryFriendlyByteBuf;
|
||||
import net.minecraft.network.codec.ByteBufCodecs;
|
||||
import net.minecraft.network.codec.StreamCodec;
|
||||
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
|
||||
public record UseLinkingBookPayload(boolean offhand) implements CustomPacketPayload {
|
||||
public static final Type<UseLinkingBookPayload> TYPE = new Type<>(
|
||||
ResourceLocation.fromNamespaceAndPath(Rivencraft.MOD_ID, "use_linking_book")
|
||||
);
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, UseLinkingBookPayload> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.BOOL,
|
||||
UseLinkingBookPayload::offhand,
|
||||
UseLinkingBookPayload::new
|
||||
);
|
||||
|
||||
@Override
|
||||
public Type<? extends CustomPacketPayload> type() {
|
||||
return TYPE;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,22 @@
|
||||
{
|
||||
"item.rivencraft.descriptive_book": "Descriptive Book",
|
||||
"item.rivencraft.descriptive_book.unwritten": "Unwritten",
|
||||
"item.rivencraft.descriptive_book.age": "Age %s",
|
||||
"item.rivencraft.descriptive_book.age": "%s",
|
||||
"item.rivencraft.linking_book": "Linking Book",
|
||||
"item.rivencraft.linking_book.unbound": "Unbound — sneak-use to bind",
|
||||
"item.rivencraft.linking_book.destination": "%s (%s, %s, %s)",
|
||||
"message.rivencraft.linking_book.bind_hint": "Sneak-use to bind this book to your current location",
|
||||
"message.rivencraft.linking_book.unbound": "This Linking Book is unbound",
|
||||
"message.rivencraft.linking_book.bound": "Linking Book bound",
|
||||
"message.rivencraft.linking_book.bound": "Linking Book bound as %s",
|
||||
"message.rivencraft.linking_book.linked": "Linked",
|
||||
"message.rivencraft.linking_book.missing_dimension": "That dimension is unavailable",
|
||||
"message.rivencraft.linking_book.unsafe": "No safe destination was found near the link",
|
||||
"screen.rivencraft.book.title": "Book title",
|
||||
"screen.rivencraft.book.title_hint": "Name this Linking Book",
|
||||
"screen.rivencraft.book.name_prompt": "Name the book before binding it to this location",
|
||||
"screen.rivencraft.book.bind": "Bind",
|
||||
"screen.rivencraft.book.link": "Link",
|
||||
"screen.rivencraft.book.unwritten": "This Descriptive Book is unwritten",
|
||||
"screen.rivencraft.book.preview_pending": "Ponder preview loading",
|
||||
"itemGroup.rivencraft": "Rivencraft"
|
||||
}
|
||||
@@ -86,6 +86,13 @@ A spiritual successor and modern port of Mystcraft for Minecraft 1.21.1 on NeoFo
|
||||
ordering="NONE"
|
||||
side="BOTH"
|
||||
|
||||
[[dependencies.${mod_id}]]
|
||||
modId="ponder"
|
||||
type="required"
|
||||
versionRange="[1.0.82,2.0.0)"
|
||||
ordering="AFTER"
|
||||
side="CLIENT"
|
||||
|
||||
# Features are specific properties of the game environment, that you may want to declare you require. This example declares
|
||||
# that your mod requires GL version 3.2 or higher. Other features will be added. They are side aware so declaring this won't
|
||||
# stop your mod loading on the server for example.
|
||||
|
||||
Reference in new issue
Block a user