diff --git a/src/main/java/fr/sushi/charmsnfabrics/client/CnFClient.java b/src/main/java/fr/sushi/charmsnfabrics/client/CnFClient.java index d8fe670..af76923 100644 --- a/src/main/java/fr/sushi/charmsnfabrics/client/CnFClient.java +++ b/src/main/java/fr/sushi/charmsnfabrics/client/CnFClient.java @@ -5,6 +5,7 @@ import fr.sushi.charmsnfabrics.client.datagen.CnFModelProvider; import fr.sushi.charmsnfabrics.client.model.FlowerCrownModel; import fr.sushi.charmsnfabrics.client.renderer.FloralWorkbenchRenderer; import fr.sushi.charmsnfabrics.client.renderer.FlowerCrownRenderer; +import fr.sushi.charmsnfabrics.client.screen.FloralWorkbenchScreen; import fr.sushi.charmsnfabrics.common.CnFRegistries; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; @@ -12,7 +13,9 @@ import net.neoforged.fml.ModContainer; import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.Mod; import net.neoforged.fml.event.lifecycle.FMLClientSetupEvent; +import net.neoforged.neoforge.client.event.ContainerScreenEvent; import net.neoforged.neoforge.client.event.EntityRenderersEvent; +import net.neoforged.neoforge.client.event.RegisterMenuScreensEvent; import net.neoforged.neoforge.client.gui.ConfigurationScreen; import net.neoforged.neoforge.client.gui.IConfigScreenFactory; import net.neoforged.neoforge.data.event.GatherDataEvent; @@ -57,4 +60,10 @@ public class CnFClient { event.createProvider(CnFModelProvider::new); } + + @SubscribeEvent + private static void onScreenAttach(RegisterMenuScreensEvent event) { + event.register(CnFRegistries.MenuTypes.FLORAL_WB_MENU.get(), + FloralWorkbenchScreen::new); + } } diff --git a/src/main/java/fr/sushi/charmsnfabrics/client/screen/FloralWorkbenchScreen.java b/src/main/java/fr/sushi/charmsnfabrics/client/screen/FloralWorkbenchScreen.java new file mode 100644 index 0000000..f1b031a --- /dev/null +++ b/src/main/java/fr/sushi/charmsnfabrics/client/screen/FloralWorkbenchScreen.java @@ -0,0 +1,41 @@ +package fr.sushi.charmsnfabrics.client.screen; + +import fr.sushi.charmsnfabrics.CharmsAndFabrics; +import fr.sushi.charmsnfabrics.common.inventory.FloralWorkbenchMenu; +import net.minecraft.client.gui.GuiGraphics; +import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.network.chat.Component; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.player.Inventory; + +public class FloralWorkbenchScreen extends AbstractContainerScreen +{ + private static final ResourceLocation FLORAL_WB_MENU_LOCATION = + ResourceLocation.fromNamespaceAndPath(CharmsAndFabrics.MODID, + "textures/gui/container/floral_workbench.png"); + + public FloralWorkbenchScreen(FloralWorkbenchMenu menu, + Inventory playerInventory, Component title) + { + super(menu, playerInventory, title); + } + + @Override + protected void renderBg(GuiGraphics guiGraphics, float partialTick, + int mouseX, int mouseY) + { + int halfWidth = (this.width - this.imageWidth) / 2; + int halfHeight = (this.height - this.imageHeight) / 2; + + guiGraphics.blit(RenderType::guiTextured, FLORAL_WB_MENU_LOCATION, + halfWidth, halfHeight, 0.0F, 0.0F, this.imageWidth, + this.imageHeight, 256, 256); + + // if (this.menu.getSlot(0).hasItem() && !this.menu.getSlot(2).hasItem()) + // { + // guiGraphics.blitSprite(RenderType::guiTextured, ERROR_SPRITE, + // i + 92, j + 31, 28, 21); + // } + } +} diff --git a/src/main/java/fr/sushi/charmsnfabrics/common/CnFRegistries.java b/src/main/java/fr/sushi/charmsnfabrics/common/CnFRegistries.java index 78c865c..227cad9 100644 --- a/src/main/java/fr/sushi/charmsnfabrics/common/CnFRegistries.java +++ b/src/main/java/fr/sushi/charmsnfabrics/common/CnFRegistries.java @@ -3,10 +3,14 @@ package fr.sushi.charmsnfabrics.common; import fr.sushi.charmsnfabrics.CharmsAndFabrics; import fr.sushi.charmsnfabrics.common.block.FloralWorkbench; import fr.sushi.charmsnfabrics.common.entities.block.FloralWorkbenchBlockEntity; +import fr.sushi.charmsnfabrics.common.inventory.FloralWorkbenchMenu; import fr.sushi.charmsnfabrics.common.item.FlowerCrown; +import net.minecraft.client.gui.screens.Screen; import net.minecraft.core.registries.Registries; import net.minecraft.network.chat.Component; import net.minecraft.resources.ResourceKey; +import net.minecraft.world.flag.FeatureFlags; +import net.minecraft.world.inventory.MenuType; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.CreativeModeTab; import net.minecraft.world.item.CreativeModeTabs; @@ -15,10 +19,9 @@ import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntityType; import net.minecraft.world.level.block.state.BlockBehaviour; import net.neoforged.bus.api.IEventBus; -import net.neoforged.neoforge.registries.DeferredBlock; -import net.neoforged.neoforge.registries.DeferredHolder; -import net.neoforged.neoforge.registries.DeferredItem; -import net.neoforged.neoforge.registries.DeferredRegister; +import net.neoforged.neoforge.attachment.AttachmentType; +import net.neoforged.neoforge.items.ItemStackHandler; +import net.neoforged.neoforge.registries.*; import java.util.Set; import java.util.function.Supplier; @@ -93,11 +96,40 @@ public class CnFRegistries Set.of(Blocks.FLORAL_WORKBENCH.get()))); } + public static class AttachmentTypes + { + public static final DeferredRegister> + ATTACHMENT_TYPES = + DeferredRegister.create(NeoForgeRegistries.ATTACHMENT_TYPES, + CharmsAndFabrics.MODID); + + public static final Supplier> + FLORAL_WORKBENCH_DATA = + ATTACHMENT_TYPES.register("floral_workbench_data", + () -> AttachmentType + .serializable(() -> new ItemStackHandler(1)) + .build()); + } + + public static class MenuTypes + { + public static final DeferredRegister> MENU_TYPES = + DeferredRegister.create(Registries.MENU, + CharmsAndFabrics.MODID); + + public static final Supplier> + FLORAL_WB_MENU = MENU_TYPES.register("floral_wb_menu", + () -> new MenuType<>(FloralWorkbenchMenu::new, + FeatureFlags.DEFAULT_FLAGS)); + } + public static void register(IEventBus bus) { Items.ITEMS.register(bus); Blocks.BLOCKS.register(bus); - Entities.BLOCK_ENTITY_TYPES.register(bus); Tabs.CREATIVE_MODE_TABS.register(bus); + Entities.BLOCK_ENTITY_TYPES.register(bus); + MenuTypes.MENU_TYPES.register(bus); + AttachmentTypes.ATTACHMENT_TYPES.register(bus); } } diff --git a/src/main/java/fr/sushi/charmsnfabrics/common/block/FloralWorkbench.java b/src/main/java/fr/sushi/charmsnfabrics/common/block/FloralWorkbench.java index f712c3b..c13c874 100644 --- a/src/main/java/fr/sushi/charmsnfabrics/common/block/FloralWorkbench.java +++ b/src/main/java/fr/sushi/charmsnfabrics/common/block/FloralWorkbench.java @@ -1,12 +1,23 @@ package fr.sushi.charmsnfabrics.common.block; +import com.mojang.serialization.MapCodec; import fr.sushi.charmsnfabrics.common.entities.block.FloralWorkbenchBlockEntity; +import fr.sushi.charmsnfabrics.common.inventory.FloralWorkbenchMenu; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.network.chat.Component; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.MenuProvider; +import net.minecraft.world.SimpleMenuProvider; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BaseEntityBlock; import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.HorizontalDirectionalBlock; import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.block.entity.BlockEntity; @@ -14,6 +25,7 @@ import net.minecraft.world.level.block.state.BlockBehaviour; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.StateDefinition; import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.shapes.CollisionContext; import net.minecraft.world.phys.shapes.Shapes; import net.minecraft.world.phys.shapes.VoxelShape; @@ -21,8 +33,11 @@ import org.jetbrains.annotations.Nullable; import java.util.Map; -public class FloralWorkbench extends Block implements EntityBlock +public class FloralWorkbench extends BaseEntityBlock { + public static final MapCodec CODEC = + simpleCodec(FloralWorkbench::new); + public static final EnumProperty FACING = HorizontalDirectionalBlock.FACING; @@ -36,6 +51,9 @@ public class FloralWorkbench extends Block implements EntityBlock private static final Map SHAPES = Shapes.rotateHorizontalAxis(Shapes.or(LEGS, TABLE, SUPPORT)); + public static final Component FLORAL_WB_TITLE = + Component.translatable("container.floral_workbench.title"); + public FloralWorkbench(BlockBehaviour.Properties properties) { super(properties); @@ -43,6 +61,12 @@ public class FloralWorkbench extends Block implements EntityBlock this.stateDefinition.any().setValue(FACING, Direction.NORTH)); } + @Override + protected MapCodec codec() + { + return CODEC; + } + @Override protected void createBlockStateDefinition( StateDefinition.Builder builder) @@ -75,4 +99,35 @@ public class FloralWorkbench extends Block implements EntityBlock { return new FloralWorkbenchBlockEntity(pos, state); } + + @Override + protected InteractionResult useItemOn(ItemStack stack, BlockState state, + Level level, BlockPos pos, Player player, InteractionHand hand, + BlockHitResult hitResult) + { + if (!level.isClientSide()) + { + if (level.getBlockEntity( + pos) instanceof FloralWorkbenchBlockEntity blockentity) + { + player.openMenu(blockentity); + // award stat : "Flowers !" + } + } + else + { + player.displayClientMessage(Component.literal("pos:" + pos), false); + } + return InteractionResult.SUCCESS; + } + + @Override + protected @Nullable MenuProvider getMenuProvider(BlockState state, + Level level, BlockPos pos) + { + return new SimpleMenuProvider( + (id, inv, player) -> new FloralWorkbenchMenu(id, inv, + ContainerLevelAccess.create(level, pos)), + FLORAL_WB_TITLE); + } } diff --git a/src/main/java/fr/sushi/charmsnfabrics/common/entities/block/FloralWorkbenchBlockEntity.java b/src/main/java/fr/sushi/charmsnfabrics/common/entities/block/FloralWorkbenchBlockEntity.java index 0aca4f0..2444948 100644 --- a/src/main/java/fr/sushi/charmsnfabrics/common/entities/block/FloralWorkbenchBlockEntity.java +++ b/src/main/java/fr/sushi/charmsnfabrics/common/entities/block/FloralWorkbenchBlockEntity.java @@ -1,16 +1,62 @@ package fr.sushi.charmsnfabrics.common.entities.block; import fr.sushi.charmsnfabrics.common.CnFRegistries; +import fr.sushi.charmsnfabrics.common.inventory.FloralWorkbenchMenu; import net.minecraft.core.BlockPos; +import net.minecraft.core.HolderLookup; +import net.minecraft.core.NonNullList; +import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.entity.BaseContainerBlockEntity; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import org.jetbrains.annotations.Nullable; -public class FloralWorkbenchBlockEntity extends BlockEntity +import java.util.List; + +public class FloralWorkbenchBlockEntity extends BaseContainerBlockEntity { + ItemStack crown; + public FloralWorkbenchBlockEntity(BlockPos pos, BlockState blockState) { super(CnFRegistries.Entities.FLORAL_WORKBENCH_BLOCKENTITY.get(), pos, blockState); } + @Override + protected Component getDefaultName() + { + return Component.translatable("container.floral_workbench"); + } + + @Override + protected NonNullList getItems() + { + return NonNullList.of(this.crown); + } + + @Override + protected void setItems(NonNullList items) + { + this.crown = items.getFirst(); + } + + @Override + protected AbstractContainerMenu createMenu(int containerId, + Inventory inventory) + { + return new FloralWorkbenchMenu(containerId, inventory); + } + + @Override + public int getContainerSize() + { + return 1; + } } diff --git a/src/main/java/fr/sushi/charmsnfabrics/common/inventory/FloralWorkbenchMenu.java b/src/main/java/fr/sushi/charmsnfabrics/common/inventory/FloralWorkbenchMenu.java new file mode 100644 index 0000000..1a33a12 --- /dev/null +++ b/src/main/java/fr/sushi/charmsnfabrics/common/inventory/FloralWorkbenchMenu.java @@ -0,0 +1,76 @@ +package fr.sushi.charmsnfabrics.common.inventory; + +import fr.sushi.charmsnfabrics.common.CnFRegistries; +import net.minecraft.world.entity.player.Inventory; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.inventory.AbstractContainerMenu; +import net.minecraft.world.inventory.ContainerLevelAccess; +import net.minecraft.world.inventory.Slot; +import net.minecraft.world.item.ItemStack; +import net.neoforged.neoforge.items.IItemHandler; +import net.neoforged.neoforge.items.ItemStackHandler; +import net.neoforged.neoforge.items.SlotItemHandler; + +public class FloralWorkbenchMenu extends AbstractContainerMenu +{ + private final ContainerLevelAccess access; + private final IItemHandler crownContainer = new ItemStackHandler(1) + { + @Override + public boolean isItemValid(int slot, ItemStack stack) + { + return stack.is(CnFRegistries.Items.FLOWER_CROWN.asItem()); + } + };; + + public FloralWorkbenchMenu(int containerId, Inventory playerInv) + { + this(containerId, playerInv, ContainerLevelAccess.NULL); + } + + public FloralWorkbenchMenu(int containerId, Inventory playerInv, + final ContainerLevelAccess access) + { + super(CnFRegistries.MenuTypes.FLORAL_WB_MENU.get(), containerId); + + this.access = access; + this.addSlot(new SlotItemHandler(this.crownContainer, 0, 80, 35)); + this.addStandardInventorySlots(playerInv, 8, 84); + } + + @Override + public ItemStack quickMoveStack(Player player, int index) + { + Slot slot = this.slots.get(index); + if (!slot.hasItem()) + { + return ItemStack.EMPTY; + } + + ItemStack stack = slot.getItem(); + if (index == 0) + { + /* From CONTAINER to INV */ + if (!this.moveItemStackTo(stack, 1, 37, false)) + { + return ItemStack.EMPTY; + } + } + else + { + /* From INV to CONTAINER */ + if (!this.moveItemStackTo(stack, 0, 1, false)) + { + return ItemStack.EMPTY; + } + } + return stack.copy(); + } + + @Override + public boolean stillValid(Player player) + { + return stillValid(this.access, player, + CnFRegistries.Blocks.FLORAL_WORKBENCH.get()); + } +} diff --git a/src/main/resources/assets/charmsnfabrics/lang/en_us.json b/src/main/resources/assets/charmsnfabrics/lang/en_us.json index 8872566..1f3a24b 100644 --- a/src/main/resources/assets/charmsnfabrics/lang/en_us.json +++ b/src/main/resources/assets/charmsnfabrics/lang/en_us.json @@ -2,6 +2,8 @@ "itemGroup.charmsnfabrics": "Charms & Fabrics", "item.charmsnfabrics.flower_crown": "Flower Crown", "item.charmsnfabrics.floral_workbench": "Floral Workbench", + "container.floral_workbench": "Floral Workbench", + "container.floral_workbench.title": "Floral Workbench", "charmsnfabrics.configuration.title": "Charms & Fabrics Configs", "charmsnfabrics.configuration.section.charmsnfabrics.common.toml": "Charms & Fabrics Configs", diff --git a/src/main/resources/assets/charmsnfabrics/textures/gui/container/FloralWBScreen.aseprite b/src/main/resources/assets/charmsnfabrics/textures/gui/container/FloralWBScreen.aseprite new file mode 100644 index 0000000..8e797cb Binary files /dev/null and b/src/main/resources/assets/charmsnfabrics/textures/gui/container/FloralWBScreen.aseprite differ diff --git a/src/main/resources/assets/charmsnfabrics/textures/gui/container/floral_workbench.png b/src/main/resources/assets/charmsnfabrics/textures/gui/container/floral_workbench.png new file mode 100644 index 0000000..de8290c Binary files /dev/null and b/src/main/resources/assets/charmsnfabrics/textures/gui/container/floral_workbench.png differ diff --git a/src/main/resources/assets/charmsnfabrics/textures/item/flower_crown.png b/src/main/resources/assets/charmsnfabrics/textures/item/flower_crown.png index d3be2ec..7912290 100644 Binary files a/src/main/resources/assets/charmsnfabrics/textures/item/flower_crown.png and b/src/main/resources/assets/charmsnfabrics/textures/item/flower_crown.png differ