mirror of
https://github.com/lukasabbe/bookshelf-inspector.git
synced 2026-04-30 10:40:53 +00:00
Add shelf inspection
This commit is contained in:
@@ -13,4 +13,5 @@ public class Constants {
|
||||
public static final ResourceLocation BOOK_SHELF_INVENTORY_PACKET_ID = ResourceLocation.fromNamespaceAndPath(MOD_ID,"book_shelf_inventory");
|
||||
public static final ResourceLocation MOD_CHECK_PACKET_ID = ResourceLocation.fromNamespaceAndPath(MOD_ID,"mod_check");
|
||||
public static final ResourceLocation LECTERN_INVENTORY_REQUEST_PACKET_ID = ResourceLocation.fromNamespaceAndPath(MOD_ID, "lectern_inventory_request");
|
||||
public static final ResourceLocation SHELF_INVENTORY_REQUEST_PACKET_ID = ResourceLocation.fromNamespaceAndPath(MOD_ID,"shelf_inventory_request");
|
||||
}
|
||||
@@ -14,6 +14,8 @@ import java.util.Map;
|
||||
|
||||
public class Config {
|
||||
public boolean lecternToggle = true;
|
||||
public boolean shelfToggle = true;
|
||||
public boolean shelfDisplayNormal = true;
|
||||
public int scale = 10;
|
||||
public boolean useRoman = false;
|
||||
|
||||
@@ -26,6 +28,12 @@ public class Config {
|
||||
if(configMap.containsKey("lectern-toggle")){
|
||||
lecternToggle = (boolean) configMap.get("lectern-toggle");
|
||||
}
|
||||
if(configMap.containsKey("shelf-toggle")){
|
||||
shelfToggle = (boolean) configMap.get("shelf-toggle");
|
||||
}
|
||||
if(configMap.containsKey("shelf-display-normal")){
|
||||
shelfDisplayNormal = (boolean) configMap.get("shelf-display-normal");
|
||||
}
|
||||
if(configMap.containsKey("scale")){
|
||||
scale = (int) configMap.get("scale");
|
||||
}
|
||||
@@ -55,6 +63,8 @@ public class Config {
|
||||
try{
|
||||
Map<String, Object> configMap = yaml.load(new FileReader(configPath.toFile()));
|
||||
configMap.put("lectern-toggle",lecternToggle);
|
||||
configMap.put("shelf-toggle",shelfToggle);
|
||||
configMap.put("shelf-display-normal",shelfDisplayNormal);
|
||||
configMap.put("scale",scale);
|
||||
configMap.put("roman", useRoman);
|
||||
FileWriter writer = new FileWriter(configPath.toString());
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.lukasabbe.bookshelfinspector.data;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
public class BookShelfData {
|
||||
public boolean isCurrentBookDataToggled = false;
|
||||
public BlockPos latestPos = null;
|
||||
public BlockState latestBlockState = null;
|
||||
public boolean requestSent = false;
|
||||
public int currentSlotInt = -1;
|
||||
}
|
||||
|
||||
@@ -8,4 +8,5 @@ import net.minecraft.world.level.block.Block;
|
||||
public class Tags {
|
||||
public static final TagKey<Block> CHISELED_BOOKSHELVES = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("c", "chiseled_bookshelves"));
|
||||
public static final TagKey<Block> LECTERNS = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("c", "lectern"));
|
||||
public static final TagKey<Block> SHELVES = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("c", "shelves"));
|
||||
}
|
||||
|
||||
@@ -4,18 +4,21 @@ import com.lukasabbe.bookshelfinspector.network.client.BookShelfInventoryHandler
|
||||
import com.lukasabbe.bookshelfinspector.network.client.ModServerPayloadHandler;
|
||||
import com.lukasabbe.bookshelfinspector.network.server.BookShelfInventoryRequestServerPayloadHandler;
|
||||
import com.lukasabbe.bookshelfinspector.network.server.LecternInventoryRequestServerPayloadHandler;
|
||||
import com.lukasabbe.bookshelfinspector.network.server.ShelfInventoryRequestServerPayloadHandler;
|
||||
|
||||
public class Handlers {
|
||||
public BookShelfInventoryHandlerServer bookShelfInventoryHandlerServer;
|
||||
public ModServerPayloadHandler modServerPayloadHandler;
|
||||
public BookShelfInventoryRequestServerPayloadHandler bookShelfInventoryRequestServerPayloadHandler;
|
||||
public LecternInventoryRequestServerPayloadHandler lecternInventoryRequestServerPayloadHandler;
|
||||
public ShelfInventoryRequestServerPayloadHandler shelfInventoryRequestServerPayloadHandler;
|
||||
|
||||
public Handlers(){
|
||||
bookShelfInventoryHandlerServer = new BookShelfInventoryHandlerServer();
|
||||
modServerPayloadHandler = new ModServerPayloadHandler();
|
||||
bookShelfInventoryRequestServerPayloadHandler = new BookShelfInventoryRequestServerPayloadHandler();
|
||||
lecternInventoryRequestServerPayloadHandler = new LecternInventoryRequestServerPayloadHandler();
|
||||
shelfInventoryRequestServerPayloadHandler = new ShelfInventoryRequestServerPayloadHandler();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
package com.lukasabbe.bookshelfinspector.network.packets;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.Constants;
|
||||
import net.minecraft.core.BlockPos;
|
||||
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 org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record ShelfInventoryRequestPayload(BlockPos pos, int slotNum) implements CustomPacketPayload {
|
||||
|
||||
public static final Type<ShelfInventoryRequestPayload> ID = new Type<>(Constants.SHELF_INVENTORY_REQUEST_PACKET_ID);
|
||||
|
||||
public static final StreamCodec<RegistryFriendlyByteBuf, ShelfInventoryRequestPayload> CODEC = StreamCodec.composite(
|
||||
BlockPos.STREAM_CODEC, ShelfInventoryRequestPayload::pos,
|
||||
ByteBufCodecs.INT, ShelfInventoryRequestPayload::slotNum,
|
||||
ShelfInventoryRequestPayload::new);
|
||||
|
||||
@Override
|
||||
public @NotNull Type<? extends CustomPacketPayload> type() { return ID; }
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package com.lukasabbe.bookshelfinspector.network.server;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.BookshelfInspector;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryPayload;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.ShelfInventoryRequestPayload;
|
||||
import com.lukasabbe.bookshelfinspector.platform.Services;
|
||||
import com.lukasabbe.bookshelfinspector.platform.handlers.ServerPayloadHandler;
|
||||
import com.lukasabbe.bookshelfinspector.util.BlockTools;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.Items;
|
||||
|
||||
public class ShelfInventoryRequestServerPayloadHandler implements ServerPayloadHandler<ShelfInventoryRequestPayload> {
|
||||
@Override
|
||||
public void receive(ShelfInventoryRequestPayload shelfInventoryRequestPayload, ServerPlayer player) {
|
||||
if(BookshelfInspector.serverInstance == null) return;
|
||||
|
||||
ItemStack stack = BlockTools.getItemInShelf(shelfInventoryRequestPayload.pos(),shelfInventoryRequestPayload.slotNum(), player.level());
|
||||
|
||||
if(stack == null){
|
||||
Services.NETWORK_HELPER.sendPacketFromServer(player, new BookShelfInventoryPayload(Items.AIR.getDefaultInstance(), shelfInventoryRequestPayload.pos(), shelfInventoryRequestPayload.slotNum()));
|
||||
return;
|
||||
}
|
||||
|
||||
Services.NETWORK_HELPER.sendPacketFromServer(player, new BookShelfInventoryPayload(stack, shelfInventoryRequestPayload.pos(), shelfInventoryRequestPayload.slotNum()));
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package com.lukasabbe.bookshelfinspector.renderer;
|
||||
|
||||
import com.lukasabbe.bookshelfinspector.BookshelfInspectorClient;
|
||||
import com.lukasabbe.bookshelfinspector.data.BookData;
|
||||
import com.lukasabbe.bookshelfinspector.data.Tags;
|
||||
import com.lukasabbe.bookshelfinspector.util.ItemTools;
|
||||
import com.lukasabbe.bookshelfinspector.util.RomanNumerals;
|
||||
import net.minecraft.ChatFormatting;
|
||||
import net.minecraft.client.Minecraft;
|
||||
@@ -14,7 +16,10 @@ import net.minecraft.network.chat.ComponentUtils;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
import net.minecraft.network.chat.Style;
|
||||
import net.minecraft.tags.EnchantmentTags;
|
||||
import net.minecraft.world.effect.MobEffectInstance;
|
||||
import net.minecraft.world.effect.MobEffectUtil;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.alchemy.PotionContents;
|
||||
import net.minecraft.world.item.enchantment.Enchantment;
|
||||
import net.minecraft.world.item.enchantment.ItemEnchantments;
|
||||
import org.joml.Matrix3x2fStack;
|
||||
@@ -41,14 +46,32 @@ public class HudRenderer {
|
||||
}
|
||||
|
||||
float scaleFactor = ((float) BookshelfInspectorClient.config.scale /10);
|
||||
drawScaledText(context, itemStack.getHoverName(), x,y+((int)(10*scaleFactor)), color, client.font);
|
||||
if(!BookshelfInspectorClient.bookShelfData.latestBlockState.is(Tags.SHELVES) || BookshelfInspectorClient.config.shelfDisplayNormal || !ItemTools.isNormalStack(itemStack)) {
|
||||
final MutableComponent itemName = itemStack.getHoverName().copy();
|
||||
|
||||
ItemEnchantments storedComponents = itemStack.getComponents().get(DataComponents.STORED_ENCHANTMENTS);
|
||||
if(storedComponents != null){
|
||||
drawScaledText(context, itemName, x,y+((int)(10*scaleFactor)), color, client.font);
|
||||
|
||||
// Render item count
|
||||
if (itemStack.isStackable()) {
|
||||
float rightEdge = x + (client.font.width(itemName) / 2f) * scaleFactor;
|
||||
float spacing = 9 * scaleFactor;
|
||||
int nextX = (int) (rightEdge + spacing);
|
||||
|
||||
final MutableComponent count = Component.empty();
|
||||
count.append(" (" + itemStack.getCount() + ")");
|
||||
|
||||
ComponentUtils.mergeStyles(count, Style.EMPTY.withColor(ChatFormatting.GRAY));
|
||||
drawScaledText(context, count, nextX,y+((int)(10*scaleFactor)), color, client.font);
|
||||
}
|
||||
}
|
||||
|
||||
// Render enchantments
|
||||
ItemEnchantments itemEnchantments = ItemTools.getItemEnchantments(itemStack);
|
||||
if(itemEnchantments != null){
|
||||
int i = ((int)(20*scaleFactor));
|
||||
for(Holder<Enchantment> enchantment : storedComponents.keySet()){
|
||||
for(Holder<Enchantment> enchantment : itemEnchantments.keySet()){
|
||||
String lvl = "";
|
||||
final int level = storedComponents.getLevel(enchantment);
|
||||
final int level = itemEnchantments.getLevel(enchantment);
|
||||
if(level != 1)
|
||||
lvl = String.valueOf(level);
|
||||
final MutableComponent enchantmentText;
|
||||
@@ -70,6 +93,29 @@ public class HudRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
// Render potion components
|
||||
PotionContents itemPotionContents = ItemTools.getPotionContents(itemStack);
|
||||
if (itemPotionContents != null) {
|
||||
int i = ((int)(20*scaleFactor));
|
||||
for (MobEffectInstance effect : itemPotionContents.getAllEffects()) {
|
||||
final MutableComponent potionText;
|
||||
|
||||
int amplifier = effect.getAmplifier();
|
||||
potionText = effect.getEffect().value().getDisplayName().copy();
|
||||
if (amplifier > 0)
|
||||
potionText.append(" " + RomanNumerals.toRoman(amplifier));
|
||||
potionText.append(" (" + MobEffectUtil.formatDuration(effect, 1, 20).getString() + ")");
|
||||
|
||||
if(!effect.getEffect().value().isBeneficial()) {
|
||||
ComponentUtils.mergeStyles(potionText, Style.EMPTY.withColor(ChatFormatting.RED));
|
||||
}else {
|
||||
ComponentUtils.mergeStyles(potionText, Style.EMPTY.withColor(ChatFormatting.GRAY));
|
||||
}
|
||||
drawScaledText(context, potionText, x, y + i, 0xFFFFFFFF, client.font);
|
||||
i += (int) (10 * scaleFactor);
|
||||
}
|
||||
}
|
||||
|
||||
var writtenBookContentComponent = itemStack.getComponents().get(DataComponents.WRITTEN_BOOK_CONTENT);
|
||||
|
||||
if(writtenBookContentComponent != null){
|
||||
|
||||
@@ -5,10 +5,12 @@ import com.lukasabbe.bookshelfinspector.data.BookData;
|
||||
import com.lukasabbe.bookshelfinspector.data.Tags;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryRequestPayload;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.LecternInventoryRequestPayload;
|
||||
import com.lukasabbe.bookshelfinspector.network.packets.ShelfInventoryRequestPayload;
|
||||
import com.lukasabbe.bookshelfinspector.platform.Services;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.block.ChiseledBookShelfBlock;
|
||||
import net.minecraft.world.level.block.ShelfBlock;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.phys.BlockHitResult;
|
||||
import net.minecraft.world.phys.HitResult;
|
||||
@@ -45,18 +47,28 @@ public class Inspector {
|
||||
}
|
||||
bookShelfData.latestPos = pos;
|
||||
|
||||
|
||||
if(client.player.level().getBlockState(pos).is(Tags.CHISELED_BOOKSHELVES)){
|
||||
BlockState blockState = client.player.level().getBlockState(pos);
|
||||
bookShelfData.latestBlockState = blockState;
|
||||
if(blockState.is(Tags.CHISELED_BOOKSHELVES)){
|
||||
bookShelfInspect(pos, blockHitResult, client);
|
||||
}else if(client.player.level().getBlockState(pos).is(Tags.LECTERNS) && config.lecternToggle){
|
||||
lecternInspect(pos);
|
||||
}else{
|
||||
|
||||
bookShelfData.requestSent = false; // Just for servers that don't have the latest version of mod
|
||||
|
||||
if(!bookShelfData.isCurrentBookDataToggled) return;
|
||||
resetBookShelfData();
|
||||
return;
|
||||
}
|
||||
|
||||
if(blockState.is(Tags.LECTERNS) && config.lecternToggle){
|
||||
lecternInspect(pos);
|
||||
return;
|
||||
}
|
||||
|
||||
if(blockState.is(Tags.SHELVES) && config.shelfToggle){
|
||||
shelfInspect(pos, blockHitResult, client);
|
||||
return;
|
||||
}
|
||||
|
||||
// No match
|
||||
bookShelfData.requestSent = false; // Just for servers that don't have the latest version of mod
|
||||
|
||||
if(!bookShelfData.isCurrentBookDataToggled) return;
|
||||
resetBookShelfData();
|
||||
}
|
||||
|
||||
|
||||
@@ -109,6 +121,38 @@ public class Inspector {
|
||||
}
|
||||
}
|
||||
|
||||
private void shelfInspect(BlockPos pos, BlockHitResult blockHitResult, Minecraft client){
|
||||
final BlockState blockState = client.player.level().getBlockState(pos);
|
||||
|
||||
ShelfBlock shelfBlock = (ShelfBlock) blockState.getBlock();
|
||||
OptionalInt optionalInt = shelfBlock.getHitSlot(blockHitResult, blockState.getValue(ShelfBlock.FACING));
|
||||
|
||||
// If the position is empty, return
|
||||
if (optionalInt.isEmpty()) {
|
||||
resetBookShelfData();
|
||||
return;
|
||||
}
|
||||
|
||||
final BookData currentBookData = BookshelfInspectorClient.currentBookData;
|
||||
|
||||
final int temp = bookShelfData.currentSlotInt;
|
||||
final int slotNum = optionalInt.getAsInt();
|
||||
bookShelfData.currentSlotInt = slotNum;
|
||||
|
||||
if (currentBookData.slotId != slotNum && !bookShelfData.requestSent) {
|
||||
bookShelfData.requestSent = true;
|
||||
Services.NETWORK_HELPER.sendPacketFromClient(new ShelfInventoryRequestPayload(pos, slotNum));
|
||||
}
|
||||
else {
|
||||
if(temp == slotNum)
|
||||
bookShelfData.isCurrentBookDataToggled = currentBookData.slotId != -2;
|
||||
else{
|
||||
bookShelfData.isCurrentBookDataToggled = false;
|
||||
BookshelfInspectorClient.currentBookData = BookData.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void resetBookShelfData(){
|
||||
if(!bookShelfData.isCurrentBookDataToggled) return;
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.entity.ChiseledBookShelfBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.LecternBlockEntity;
|
||||
import net.minecraft.world.level.block.entity.ShelfBlockEntity;
|
||||
|
||||
public class BlockTools {
|
||||
public static ItemStack getBookInChiseledBookShelf(BlockPos pos, int slotNum, Level world){
|
||||
@@ -23,4 +24,14 @@ public class BlockTools {
|
||||
if(blockEntity instanceof LecternBlockEntity lecternBlockEntity) return lecternBlockEntity.getBook();
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ItemStack getItemInShelf(BlockPos pos, int slotNum, Level world){
|
||||
final BlockEntity blockEntity = world.getBlockEntity(pos);
|
||||
if (blockEntity instanceof ShelfBlockEntity shelfBlock) {
|
||||
final ItemStack stack = shelfBlock.getItem(slotNum);
|
||||
if (stack.isEmpty()) return null;
|
||||
return stack;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.lukasabbe.bookshelfinspector.util;
|
||||
|
||||
import com.google.common.collect.Iterables;
|
||||
import net.minecraft.core.component.DataComponents;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.alchemy.PotionContents;
|
||||
import net.minecraft.world.item.enchantment.ItemEnchantments;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
public class ItemTools {
|
||||
public static ItemEnchantments getItemEnchantments(ItemStack itemStack) {
|
||||
return Optional
|
||||
.ofNullable(itemStack.getComponents().get(DataComponents.STORED_ENCHANTMENTS)) // STORED_ENCHANTMENTS is for books
|
||||
.orElse(itemStack.getComponents().get(DataComponents.ENCHANTMENTS));// ENCHANTMENTS is for items that apply the enchantment
|
||||
}
|
||||
|
||||
public static PotionContents getPotionContents(ItemStack itemStack) {
|
||||
return itemStack.getComponents().get(DataComponents.POTION_CONTENTS);
|
||||
}
|
||||
|
||||
public static boolean isNormalStack(ItemStack itemStack) {
|
||||
if (!itemStack.getHoverName().equals(itemStack.getItemName())) return false;
|
||||
|
||||
ItemEnchantments itemEnchantments = getItemEnchantments(itemStack);
|
||||
if (itemEnchantments != null && !itemEnchantments.isEmpty()) return false;
|
||||
|
||||
PotionContents itemPotionContents = getPotionContents(itemStack);
|
||||
return itemPotionContents == null || Iterables.size(itemPotionContents.getAllEffects()) == 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user