diff --git a/src/main/java/com/github/minecraftschurlimods/bibliocraft/block/BCBlock.java b/src/main/java/com/github/minecraftschurlimods/bibliocraft/block/BCBlock.java index d690d0d2..4bb87790 100644 --- a/src/main/java/com/github/minecraftschurlimods/bibliocraft/block/BCBlock.java +++ b/src/main/java/com/github/minecraftschurlimods/bibliocraft/block/BCBlock.java @@ -20,6 +20,8 @@ import net.minecraft.world.level.block.state.properties.BlockStateProperties; import net.minecraft.world.level.block.state.properties.BooleanProperty; import net.minecraft.world.level.block.state.properties.DirectionProperty; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; import net.minecraft.world.level.material.PushReaction; import net.minecraft.world.phys.BlockHitResult; import net.neoforged.neoforge.network.NetworkHooks; @@ -55,6 +57,11 @@ public BlockState getStateForPlacement(BlockPlaceContext p_52501_) { return this.defaultBlockState().setValue(FACING, p_52501_.getHorizontalDirection().getOpposite()); } + @Override + public FluidState getFluidState(BlockState state) { + return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); + } + @Override public RenderShape getRenderShape(BlockState p_49232_) { return RenderShape.MODEL; diff --git a/src/main/java/com/github/minecraftschurlimods/bibliocraft/block/BCBlockEntity.java b/src/main/java/com/github/minecraftschurlimods/bibliocraft/block/BCBlockEntity.java index 0105f131..1b04bb40 100644 --- a/src/main/java/com/github/minecraftschurlimods/bibliocraft/block/BCBlockEntity.java +++ b/src/main/java/com/github/minecraftschurlimods/bibliocraft/block/BCBlockEntity.java @@ -3,15 +3,21 @@ import com.github.minecraftschurlimods.bibliocraft.Bibliocraft; import net.minecraft.core.BlockPos; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.Connection; import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket; import net.minecraft.world.Container; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.Vec3; import net.neoforged.neoforge.items.ItemStackHandler; +import org.jetbrains.annotations.Nullable; public abstract class BCBlockEntity extends BlockEntity implements Container { private static final String ITEMS_TAG = "items"; @@ -19,7 +25,14 @@ public abstract class BCBlockEntity extends BlockEntity implements Container { public BCBlockEntity(BlockEntityType type, int containerSize, BlockPos pos, BlockState state) { super(type, pos, state); - items = new ItemStackHandler(containerSize); + items = new ItemStackHandler(containerSize) { + @Override + protected void onContentsChanged(int slot) { + super.onContentsChanged(slot); + setChanged(); + level.sendBlockUpdated(worldPosition, getBlockState(), getBlockState(), Block.UPDATE_ALL); + } + }; } public static Component title(String name) { @@ -69,7 +82,7 @@ public void setItem(int slot, ItemStack stack) { @Override public boolean stillValid(Player player) { BlockPos pos = getBlockPos(); - return player.level().getBlockEntity(pos) == this && player.distanceToSqr(Vec3.atCenterOf(pos)) <= 64; + return level.getBlockEntity(pos) == this && player.distanceToSqr(Vec3.atCenterOf(pos)) <= 64; } @Override @@ -82,14 +95,50 @@ public void clearContent() { @Override public void load(CompoundTag tag) { super.load(tag); - if (tag.contains(ITEMS_TAG)) { - items.deserializeNBT(tag.getCompound(ITEMS_TAG)); - } + loadTag(tag); } @Override protected void saveAdditional(CompoundTag tag) { super.saveAdditional(tag); + saveTag(tag); + } + + @Override + public void handleUpdateTag(CompoundTag tag) { + super.handleUpdateTag(tag); + loadTag(tag); + } + + @Override + public CompoundTag getUpdateTag() { + CompoundTag tag = super.getUpdateTag(); + saveTag(tag); + return tag; + } + + @Nullable + @Override + public Packet getUpdatePacket() { + return ClientboundBlockEntityDataPacket.create(this); + } + + @Override + public void onDataPacket(Connection net, ClientboundBlockEntityDataPacket pkt) { + CompoundTag tag = pkt.getTag(); + if (tag != null) { + handleUpdateTag(tag); + } + } + + protected void loadTag(CompoundTag tag) { + if (tag.contains(ITEMS_TAG)) { + items.deserializeNBT(tag.getCompound(ITEMS_TAG)); + } + requestModelDataUpdate(); + } + + protected void saveTag(CompoundTag tag) { tag.put(ITEMS_TAG, items.serializeNBT()); } } diff --git a/src/main/java/com/github/minecraftschurlimods/bibliocraft/block/bookcase/BookcaseBlockEntity.java b/src/main/java/com/github/minecraftschurlimods/bibliocraft/block/bookcase/BookcaseBlockEntity.java index ec443d21..0257821a 100644 --- a/src/main/java/com/github/minecraftschurlimods/bibliocraft/block/bookcase/BookcaseBlockEntity.java +++ b/src/main/java/com/github/minecraftschurlimods/bibliocraft/block/bookcase/BookcaseBlockEntity.java @@ -2,6 +2,7 @@ import com.github.minecraftschurlimods.bibliocraft.block.BCBlockEntity; import com.github.minecraftschurlimods.bibliocraft.init.BCBlockEntities; +import net.minecraft.Util; import net.minecraft.core.BlockPos; import net.minecraft.network.chat.Component; import net.minecraft.world.MenuProvider; @@ -9,9 +10,20 @@ import net.minecraft.world.entity.player.Player; import net.minecraft.world.inventory.AbstractContainerMenu; import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.client.model.data.ModelData; +import net.neoforged.neoforge.client.model.data.ModelProperty; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; + public class BookcaseBlockEntity extends BCBlockEntity implements MenuProvider { + public static final List> MODEL_PROPERTIES = Util.make(new ArrayList<>(), list -> { + for (int i = 0; i < 16; i++) { + list.add(new ModelProperty<>()); + } + }); private static final Component TITLE = title("bookcase"); public BookcaseBlockEntity(BlockPos pos, BlockState state) { @@ -28,4 +40,13 @@ public Component getDisplayName() { public AbstractContainerMenu createMenu(int id, Inventory inventory, Player player) { return new BookcaseMenu(id, inventory, this); } + + @Override + public ModelData getModelData() { + ModelData.Builder builder = ModelData.builder(); + for (int i = 0; i < MODEL_PROPERTIES.size(); i++) { + builder.with(MODEL_PROPERTIES.get(i), !items.getStackInSlot(i).isEmpty()); + } + return builder.build(); + } } diff --git a/src/main/java/com/github/minecraftschurlimods/bibliocraft/client/ClientHandler.java b/src/main/java/com/github/minecraftschurlimods/bibliocraft/client/ClientHandler.java index 74986e50..2c23b170 100644 --- a/src/main/java/com/github/minecraftschurlimods/bibliocraft/client/ClientHandler.java +++ b/src/main/java/com/github/minecraftschurlimods/bibliocraft/client/ClientHandler.java @@ -1,12 +1,25 @@ package com.github.minecraftschurlimods.bibliocraft.client; import com.github.minecraftschurlimods.bibliocraft.Bibliocraft; +import com.github.minecraftschurlimods.bibliocraft.block.BCBlock; +import com.github.minecraftschurlimods.bibliocraft.block.bookcase.BookcaseBlock; +import com.github.minecraftschurlimods.bibliocraft.client.model.BookcaseModel; import com.github.minecraftschurlimods.bibliocraft.client.screen.BookcaseScreen; +import com.github.minecraftschurlimods.bibliocraft.init.BCBlocks; import com.github.minecraftschurlimods.bibliocraft.init.BCMenuTypes; import net.minecraft.client.gui.screens.MenuScreens; +import net.minecraft.client.renderer.block.BlockModelShaper; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.state.BlockState; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.Mod; import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.neoforge.client.event.ModelEvent; +import net.neoforged.neoforge.client.model.BakedModelWrapper; + +import java.util.Map; +import java.util.function.Function; public final class ClientHandler { @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD, modid = Bibliocraft.MOD_ID) @@ -15,6 +28,27 @@ public static final class ModBus { static void clientSetup(FMLClientSetupEvent event) { MenuScreens.register(BCMenuTypes.BOOKCASE.get(), BookcaseScreen::new); } + + @SubscribeEvent + static void modifyBakingResult(ModelEvent.ModifyBakingResult event) { + Map models = event.getModels(); + for (BookcaseBlock block : BCBlocks.BOOKCASE.values()) { + bakeBCBlock(models, block, BookcaseModel::new); + } + } + + @SubscribeEvent + static void registerAdditional(ModelEvent.RegisterAdditional event) { + for (int i = 0; i < 16; i++) { + event.register(new ResourceLocation(Bibliocraft.MOD_ID, "block/bookcase/book_" + i)); + } + } + + private static void bakeBCBlock(Map models, BCBlock block, Function> modelFactory) { + for (BlockState state : block.getStateDefinition().getPossibleStates()) { + models.computeIfPresent(BlockModelShaper.stateToModelLocation(state), ($, model) -> modelFactory.apply(model)); + } + } } /* @Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.FORGE, modid = Bibliocraft.MOD_ID) diff --git a/src/main/java/com/github/minecraftschurlimods/bibliocraft/client/model/BookcaseModel.java b/src/main/java/com/github/minecraftschurlimods/bibliocraft/client/model/BookcaseModel.java new file mode 100644 index 00000000..ff5aaf50 --- /dev/null +++ b/src/main/java/com/github/minecraftschurlimods/bibliocraft/client/model/BookcaseModel.java @@ -0,0 +1,46 @@ +package com.github.minecraftschurlimods.bibliocraft.client.model; + +import com.github.minecraftschurlimods.bibliocraft.Bibliocraft; +import com.github.minecraftschurlimods.bibliocraft.block.bookcase.BookcaseBlockEntity; +import net.minecraft.Util; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.block.BlockRenderDispatcher; +import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelManager; +import net.minecraft.core.Direction; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.RandomSource; +import net.minecraft.world.level.block.state.BlockState; +import net.neoforged.neoforge.client.model.BakedModelWrapper; +import net.neoforged.neoforge.client.model.data.ModelData; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +public class BookcaseModel extends BakedModelWrapper { + private static final List BOOKS = Util.make(new ArrayList<>(), list -> { + for (int i = 0; i < BookcaseBlockEntity.MODEL_PROPERTIES.size(); i++) { + list.add(new ResourceLocation(Bibliocraft.MOD_ID, "block/bookcase/book_" + i)); + } + }); + + public BookcaseModel(BakedModel originalModel) { + super(originalModel); + } + + @SuppressWarnings("DataFlowIssue") + @Override + public List getQuads(@Nullable BlockState state, @Nullable Direction side, RandomSource rand, ModelData extraData, @Nullable RenderType renderType) { + List list = new ArrayList<>(super.getQuads(state, side, rand, extraData, renderType)); + ModelManager models = Minecraft.getInstance().getModelManager(); + for (int i = 0; i < BookcaseBlockEntity.MODEL_PROPERTIES.size(); i++) { + if (extraData.has(BookcaseBlockEntity.MODEL_PROPERTIES.get(i)) && extraData.get(BookcaseBlockEntity.MODEL_PROPERTIES.get(i))) { + list.addAll(models.getModel(BOOKS.get(i)).getQuads(state, side, rand, ModelData.EMPTY, renderType)); + } + } + return list; + } +} diff --git a/src/main/java/com/github/minecraftschurlimods/bibliocraft/client/model/package-info.java b/src/main/java/com/github/minecraftschurlimods/bibliocraft/client/model/package-info.java new file mode 100644 index 00000000..f7504346 --- /dev/null +++ b/src/main/java/com/github/minecraftschurlimods/bibliocraft/client/model/package-info.java @@ -0,0 +1,7 @@ +@MethodsReturnNonnullByDefault +@ParametersAreNonnullByDefault +package com.github.minecraftschurlimods.bibliocraft.client.model; + +import net.minecraft.MethodsReturnNonnullByDefault; + +import javax.annotation.ParametersAreNonnullByDefault;