Skip to content

Commit 8505a5f

Browse files
authored
Merge pull request #27 from img00/main
Add inspection for shelves
2 parents 61decc1 + 2a99ea0 commit 8505a5f

18 files changed

Lines changed: 260 additions & 13 deletions

File tree

common/src/main/java/com/lukasabbe/bookshelfinspector/Constants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ public class Constants {
1313
public static final ResourceLocation BOOK_SHELF_INVENTORY_PACKET_ID = ResourceLocation.fromNamespaceAndPath(MOD_ID,"book_shelf_inventory");
1414
public static final ResourceLocation MOD_CHECK_PACKET_ID = ResourceLocation.fromNamespaceAndPath(MOD_ID,"mod_check");
1515
public static final ResourceLocation LECTERN_INVENTORY_REQUEST_PACKET_ID = ResourceLocation.fromNamespaceAndPath(MOD_ID, "lectern_inventory_request");
16+
public static final ResourceLocation SHELF_INVENTORY_REQUEST_PACKET_ID = ResourceLocation.fromNamespaceAndPath(MOD_ID,"shelf_inventory_request");
1617
}

common/src/main/java/com/lukasabbe/bookshelfinspector/config/Config.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
public class Config {
1616
public boolean lecternToggle = true;
17+
public boolean shelfToggle = true;
18+
public boolean shelfDisplayNormal = true;
1719
public int scale = 10;
1820
public boolean useRoman = false;
1921

@@ -26,6 +28,12 @@ public void loadConfig(){
2628
if(configMap.containsKey("lectern-toggle")){
2729
lecternToggle = (boolean) configMap.get("lectern-toggle");
2830
}
31+
if(configMap.containsKey("shelf-toggle")){
32+
shelfToggle = (boolean) configMap.get("shelf-toggle");
33+
}
34+
if(configMap.containsKey("shelf-display-normal")){
35+
shelfDisplayNormal = (boolean) configMap.get("shelf-display-normal");
36+
}
2937
if(configMap.containsKey("scale")){
3038
scale = (int) configMap.get("scale");
3139
}
@@ -55,6 +63,8 @@ public void saveConfig(){
5563
try{
5664
Map<String, Object> configMap = yaml.load(new FileReader(configPath.toFile()));
5765
configMap.put("lectern-toggle",lecternToggle);
66+
configMap.put("shelf-toggle",shelfToggle);
67+
configMap.put("shelf-display-normal",shelfDisplayNormal);
5868
configMap.put("scale",scale);
5969
configMap.put("roman", useRoman);
6070
FileWriter writer = new FileWriter(configPath.toString());
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package com.lukasabbe.bookshelfinspector.data;
22

33
import net.minecraft.core.BlockPos;
4+
import net.minecraft.world.level.block.state.BlockState;
45

56
public class BookShelfData {
67
public boolean isCurrentBookDataToggled = false;
78
public BlockPos latestPos = null;
9+
public BlockState latestBlockState = null;
810
public boolean requestSent = false;
911
public int currentSlotInt = -1;
1012
}

common/src/main/java/com/lukasabbe/bookshelfinspector/data/Tags.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@
88
public class Tags {
99
public static final TagKey<Block> CHISELED_BOOKSHELVES = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("c", "chiseled_bookshelves"));
1010
public static final TagKey<Block> LECTERNS = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("c", "lectern"));
11+
public static final TagKey<Block> SHELVES = TagKey.create(Registries.BLOCK, ResourceLocation.fromNamespaceAndPath("c", "shelves"));
1112
}

common/src/main/java/com/lukasabbe/bookshelfinspector/network/Handlers.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,21 @@
44
import com.lukasabbe.bookshelfinspector.network.client.ModServerPayloadHandler;
55
import com.lukasabbe.bookshelfinspector.network.server.BookShelfInventoryRequestServerPayloadHandler;
66
import com.lukasabbe.bookshelfinspector.network.server.LecternInventoryRequestServerPayloadHandler;
7+
import com.lukasabbe.bookshelfinspector.network.server.ShelfInventoryRequestServerPayloadHandler;
78

89
public class Handlers {
910
public BookShelfInventoryHandlerServer bookShelfInventoryHandlerServer;
1011
public ModServerPayloadHandler modServerPayloadHandler;
1112
public BookShelfInventoryRequestServerPayloadHandler bookShelfInventoryRequestServerPayloadHandler;
1213
public LecternInventoryRequestServerPayloadHandler lecternInventoryRequestServerPayloadHandler;
14+
public ShelfInventoryRequestServerPayloadHandler shelfInventoryRequestServerPayloadHandler;
1315

1416
public Handlers(){
1517
bookShelfInventoryHandlerServer = new BookShelfInventoryHandlerServer();
1618
modServerPayloadHandler = new ModServerPayloadHandler();
1719
bookShelfInventoryRequestServerPayloadHandler = new BookShelfInventoryRequestServerPayloadHandler();
1820
lecternInventoryRequestServerPayloadHandler = new LecternInventoryRequestServerPayloadHandler();
21+
shelfInventoryRequestServerPayloadHandler = new ShelfInventoryRequestServerPayloadHandler();
1922
}
2023

2124
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.lukasabbe.bookshelfinspector.network.packets;
2+
3+
import com.lukasabbe.bookshelfinspector.Constants;
4+
import net.minecraft.core.BlockPos;
5+
import net.minecraft.network.RegistryFriendlyByteBuf;
6+
import net.minecraft.network.codec.ByteBufCodecs;
7+
import net.minecraft.network.codec.StreamCodec;
8+
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
9+
import org.jetbrains.annotations.NotNull;
10+
11+
public record ShelfInventoryRequestPayload(BlockPos pos, int slotNum) implements CustomPacketPayload {
12+
13+
public static final Type<ShelfInventoryRequestPayload> ID = new Type<>(Constants.SHELF_INVENTORY_REQUEST_PACKET_ID);
14+
15+
public static final StreamCodec<RegistryFriendlyByteBuf, ShelfInventoryRequestPayload> CODEC = StreamCodec.composite(
16+
BlockPos.STREAM_CODEC, ShelfInventoryRequestPayload::pos,
17+
ByteBufCodecs.INT, ShelfInventoryRequestPayload::slotNum,
18+
ShelfInventoryRequestPayload::new);
19+
20+
@Override
21+
public @NotNull Type<? extends CustomPacketPayload> type() { return ID; }
22+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.lukasabbe.bookshelfinspector.network.server;
2+
3+
import com.lukasabbe.bookshelfinspector.BookshelfInspector;
4+
import com.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryPayload;
5+
import com.lukasabbe.bookshelfinspector.network.packets.ShelfInventoryRequestPayload;
6+
import com.lukasabbe.bookshelfinspector.platform.Services;
7+
import com.lukasabbe.bookshelfinspector.platform.handlers.ServerPayloadHandler;
8+
import com.lukasabbe.bookshelfinspector.util.BlockTools;
9+
import net.minecraft.server.level.ServerPlayer;
10+
import net.minecraft.world.item.ItemStack;
11+
import net.minecraft.world.item.Items;
12+
13+
public class ShelfInventoryRequestServerPayloadHandler implements ServerPayloadHandler<ShelfInventoryRequestPayload> {
14+
@Override
15+
public void receive(ShelfInventoryRequestPayload shelfInventoryRequestPayload, ServerPlayer player) {
16+
if(BookshelfInspector.serverInstance == null) return;
17+
18+
ItemStack stack = BlockTools.getItemInShelf(shelfInventoryRequestPayload.pos(),shelfInventoryRequestPayload.slotNum(), player.level());
19+
20+
if(stack == null){
21+
Services.NETWORK_HELPER.sendPacketFromServer(player, new BookShelfInventoryPayload(Items.AIR.getDefaultInstance(), shelfInventoryRequestPayload.pos(), shelfInventoryRequestPayload.slotNum()));
22+
return;
23+
}
24+
25+
Services.NETWORK_HELPER.sendPacketFromServer(player, new BookShelfInventoryPayload(stack, shelfInventoryRequestPayload.pos(), shelfInventoryRequestPayload.slotNum()));
26+
}
27+
}

common/src/main/java/com/lukasabbe/bookshelfinspector/renderer/HudRenderer.java

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import com.lukasabbe.bookshelfinspector.BookshelfInspectorClient;
44
import com.lukasabbe.bookshelfinspector.data.BookData;
5+
import com.lukasabbe.bookshelfinspector.data.Tags;
6+
import com.lukasabbe.bookshelfinspector.util.ItemTools;
57
import com.lukasabbe.bookshelfinspector.util.RomanNumerals;
68
import net.minecraft.ChatFormatting;
79
import net.minecraft.client.Minecraft;
@@ -14,7 +16,10 @@
1416
import net.minecraft.network.chat.MutableComponent;
1517
import net.minecraft.network.chat.Style;
1618
import net.minecraft.tags.EnchantmentTags;
19+
import net.minecraft.world.effect.MobEffectInstance;
20+
import net.minecraft.world.effect.MobEffectUtil;
1721
import net.minecraft.world.item.ItemStack;
22+
import net.minecraft.world.item.alchemy.PotionContents;
1823
import net.minecraft.world.item.enchantment.Enchantment;
1924
import net.minecraft.world.item.enchantment.ItemEnchantments;
2025
import org.joml.Matrix3x2fStack;
@@ -32,6 +37,9 @@ public static void hudRender(GuiGraphics context, Minecraft client){
3237
final int y = screenHeight / 2;
3338
final ItemStack itemStack = currentBookData.itemStack;
3439

40+
// If item is normal (no enchantments/potion effects/custom names), do not continue if "Display normal items" option is turned off
41+
if(BookshelfInspectorClient.bookShelfData.latestBlockState.is(Tags.SHELVES) && ItemTools.isNormalStack(itemStack) && !BookshelfInspectorClient.config.shelfDisplayNormal) return;
42+
3543
int color = 0xFFFFFFFF;
3644

3745
final Integer colorValue = itemStack.getRarity().color().getColor();
@@ -40,15 +48,32 @@ public static void hudRender(GuiGraphics context, Minecraft client){
4048
color = colorValue + 0xFF000000;
4149
}
4250

51+
// Item name
4352
float scaleFactor = ((float) BookshelfInspectorClient.config.scale /10);
44-
drawScaledText(context, itemStack.getHoverName(), x,y+((int)(10*scaleFactor)), color, client.font);
53+
final MutableComponent itemName = itemStack.getHoverName().copy();
54+
55+
drawScaledText(context, itemName, x,y+((int)(10*scaleFactor)), color, client.font);
56+
57+
// Item count
58+
if (itemStack.isStackable()) {
59+
float rightEdge = x + (client.font.width(itemName) / 2f) * scaleFactor;
60+
float spacing = 9 * scaleFactor;
61+
int nextX = (int) (rightEdge + spacing);
62+
63+
final MutableComponent count = Component.empty();
64+
count.append(" (" + itemStack.getCount() + ")");
4565

46-
ItemEnchantments storedComponents = itemStack.getComponents().get(DataComponents.STORED_ENCHANTMENTS);
47-
if(storedComponents != null){
66+
ComponentUtils.mergeStyles(count, Style.EMPTY.withColor(ChatFormatting.GRAY));
67+
drawScaledText(context, count, nextX,y+((int)(10*scaleFactor)), color, client.font);
68+
}
69+
70+
// Enchantments
71+
ItemEnchantments itemEnchantments = ItemTools.getItemEnchantments(itemStack);
72+
if(itemEnchantments != null){
4873
int i = ((int)(20*scaleFactor));
49-
for(Holder<Enchantment> enchantment : storedComponents.keySet()){
74+
for(Holder<Enchantment> enchantment : itemEnchantments.keySet()){
5075
String lvl = "";
51-
final int level = storedComponents.getLevel(enchantment);
76+
final int level = itemEnchantments.getLevel(enchantment);
5277
if(level != 1)
5378
lvl = String.valueOf(level);
5479
final MutableComponent enchantmentText;
@@ -70,12 +95,39 @@ else if (level != 1)
7095
}
7196
}
7297

98+
// Potion components
99+
PotionContents itemPotionContents = ItemTools.getPotionContents(itemStack);
100+
if (itemPotionContents != null) {
101+
int i = ((int)(20*scaleFactor));
102+
for (MobEffectInstance effect : itemPotionContents.getAllEffects()) {
103+
final MutableComponent potionText;
104+
105+
int amplifier = effect.getAmplifier();
106+
potionText = effect.getEffect().value().getDisplayName().copy();
107+
if (amplifier > 0) {
108+
String amplifierNumeral = BookshelfInspectorClient.config.useRoman ? RomanNumerals.toRoman(amplifier) : String.valueOf(amplifier);
109+
potionText.append(" " + amplifierNumeral);
110+
}
111+
potionText.append(" (" + MobEffectUtil.formatDuration(effect, 1, client.level.tickRateManager().tickrate()).getString() + ")");
112+
113+
if (!effect.getEffect().value().isBeneficial()) {
114+
ComponentUtils.mergeStyles(potionText, Style.EMPTY.withColor(ChatFormatting.RED));
115+
} else {
116+
ComponentUtils.mergeStyles(potionText, Style.EMPTY.withColor(ChatFormatting.GRAY));
117+
}
118+
drawScaledText(context, potionText, x, y + i, 0xFFFFFFFF, client.font);
119+
i += (int) (10 * scaleFactor);
120+
}
121+
}
122+
123+
// Written book author
73124
var writtenBookContentComponent = itemStack.getComponents().get(DataComponents.WRITTEN_BOOK_CONTENT);
74125

75126
if(writtenBookContentComponent != null){
76127
drawScaledText(context, Component.translatable("book.byAuthor",writtenBookContentComponent.author()), x,y+(int)(20*scaleFactor), 0xFFFFFFFF, client.font);
77128
}
78129
}
130+
79131
private static void drawScaledText(GuiGraphics context, Component text, int centerX, int y, int color, Font textRenderer){
80132
Matrix3x2fStack stack = context.pose();
81133
stack.pushMatrix();

common/src/main/java/com/lukasabbe/bookshelfinspector/renderer/Inspector.java

Lines changed: 52 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
import com.lukasabbe.bookshelfinspector.data.Tags;
66
import com.lukasabbe.bookshelfinspector.network.packets.BookShelfInventoryRequestPayload;
77
import com.lukasabbe.bookshelfinspector.network.packets.LecternInventoryRequestPayload;
8+
import com.lukasabbe.bookshelfinspector.network.packets.ShelfInventoryRequestPayload;
89
import com.lukasabbe.bookshelfinspector.platform.Services;
910
import net.minecraft.client.Minecraft;
1011
import net.minecraft.core.BlockPos;
1112
import net.minecraft.world.level.block.ChiseledBookShelfBlock;
13+
import net.minecraft.world.level.block.ShelfBlock;
1214
import net.minecraft.world.level.block.state.BlockState;
1315
import net.minecraft.world.phys.BlockHitResult;
1416
import net.minecraft.world.phys.HitResult;
@@ -45,18 +47,28 @@ public void inspect(Minecraft client){
4547
}
4648
bookShelfData.latestPos = pos;
4749

48-
49-
if(client.player.level().getBlockState(pos).is(Tags.CHISELED_BOOKSHELVES)){
50+
BlockState blockState = client.player.level().getBlockState(pos);
51+
bookShelfData.latestBlockState = blockState;
52+
if(blockState.is(Tags.CHISELED_BOOKSHELVES)){
5053
bookShelfInspect(pos, blockHitResult, client);
51-
}else if(client.player.level().getBlockState(pos).is(Tags.LECTERNS) && config.lecternToggle){
52-
lecternInspect(pos);
53-
}else{
54+
return;
55+
}
5456

55-
bookShelfData.requestSent = false; // Just for servers that don't have the latest version of mod
57+
if(blockState.is(Tags.LECTERNS) && config.lecternToggle){
58+
lecternInspect(pos);
59+
return;
60+
}
5661

57-
if(!bookShelfData.isCurrentBookDataToggled) return;
58-
resetBookShelfData();
62+
if(blockState.is(Tags.SHELVES) && config.shelfToggle){
63+
shelfInspect(pos, blockHitResult, client);
64+
return;
5965
}
66+
67+
// No match
68+
bookShelfData.requestSent = false; // Just for servers that don't have the latest version of mod
69+
70+
if(!bookShelfData.isCurrentBookDataToggled) return;
71+
resetBookShelfData();
6072
}
6173

6274

@@ -109,6 +121,38 @@ private void bookShelfInspect(BlockPos pos, BlockHitResult blockHitResult, Minec
109121
}
110122
}
111123

124+
private void shelfInspect(BlockPos pos, BlockHitResult blockHitResult, Minecraft client){
125+
final BlockState blockState = client.player.level().getBlockState(pos);
126+
127+
ShelfBlock shelfBlock = (ShelfBlock) blockState.getBlock();
128+
OptionalInt optionalInt = shelfBlock.getHitSlot(blockHitResult, blockState.getValue(ShelfBlock.FACING));
129+
130+
// If the position is empty, return
131+
if (optionalInt.isEmpty()) {
132+
resetBookShelfData();
133+
return;
134+
}
135+
136+
final BookData currentBookData = BookshelfInspectorClient.currentBookData;
137+
138+
final int temp = bookShelfData.currentSlotInt;
139+
final int slotNum = optionalInt.getAsInt();
140+
bookShelfData.currentSlotInt = slotNum;
141+
142+
if (currentBookData.slotId != slotNum && !bookShelfData.requestSent) {
143+
bookShelfData.requestSent = true;
144+
Services.NETWORK_HELPER.sendPacketFromClient(new ShelfInventoryRequestPayload(pos, slotNum));
145+
}
146+
else {
147+
if(temp == slotNum)
148+
bookShelfData.isCurrentBookDataToggled = currentBookData.slotId != -2;
149+
else{
150+
bookShelfData.isCurrentBookDataToggled = false;
151+
BookshelfInspectorClient.currentBookData = BookData.empty();
152+
}
153+
}
154+
}
155+
112156
private void resetBookShelfData(){
113157
if(!bookShelfData.isCurrentBookDataToggled) return;
114158

common/src/main/java/com/lukasabbe/bookshelfinspector/util/BlockTools.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import net.minecraft.world.level.block.entity.BlockEntity;
77
import net.minecraft.world.level.block.entity.ChiseledBookShelfBlockEntity;
88
import net.minecraft.world.level.block.entity.LecternBlockEntity;
9+
import net.minecraft.world.level.block.entity.ShelfBlockEntity;
910

1011
public class BlockTools {
1112
public static ItemStack getBookInChiseledBookShelf(BlockPos pos, int slotNum, Level world){
@@ -23,4 +24,14 @@ public static ItemStack getBookInLectern(BlockPos pos, Level world){
2324
if(blockEntity instanceof LecternBlockEntity lecternBlockEntity) return lecternBlockEntity.getBook();
2425
return null;
2526
}
27+
28+
public static ItemStack getItemInShelf(BlockPos pos, int slotNum, Level world){
29+
final BlockEntity blockEntity = world.getBlockEntity(pos);
30+
if (blockEntity instanceof ShelfBlockEntity shelfBlock) {
31+
final ItemStack stack = shelfBlock.getItem(slotNum);
32+
if (stack.isEmpty()) return null;
33+
return stack;
34+
}
35+
return null;
36+
}
2637
}

0 commit comments

Comments
 (0)