Skip to content

Commit 4af272d

Browse files
KaupenjoeKaupenjoe
authored andcommitted
basic block entity
1 parent 2b2af57 commit 4af272d

11 files changed

Lines changed: 396 additions & 0 deletions

File tree

src/main/java/net/kaupenjoe/tutorialmod/TutorialMod.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package net.kaupenjoe.tutorialmod;
22

33
import net.kaupenjoe.tutorialmod.block.ModBlocks;
4+
import net.kaupenjoe.tutorialmod.block.entity.ModBlockEntities;
45
import net.kaupenjoe.tutorialmod.component.ModDataComponents;
56
import net.kaupenjoe.tutorialmod.effect.ModEffects;
67
import net.kaupenjoe.tutorialmod.enchantment.ModEnchantmentEffects;
@@ -72,6 +73,7 @@ public TutorialMod(IEventBus modEventBus, ModContainer modContainer) {
7273
ModParticles.register(modEventBus);
7374

7475
ModLootModifiers.register(modEventBus);
76+
ModBlockEntities.register(modEventBus);
7577

7678
// Register the item to a creative tab
7779
modEventBus.addListener(this::addCreative);

src/main/java/net/kaupenjoe/tutorialmod/block/ModBlocks.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,9 @@ public int getFireSpreadSpeed(BlockState state, BlockGetter level, BlockPos pos,
133133
public static final DeferredBlock<Block> CHAIR = registerBlock("chair",
134134
() -> new ChairBlock(BlockBehaviour.Properties.of().noOcclusion()));
135135

136+
public static final DeferredBlock<Block> PEDESTAL = registerBlock("pedestal",
137+
() -> new PedestalBlock(BlockBehaviour.Properties.of().noOcclusion()));
138+
136139

137140
private static <T extends Block> DeferredBlock<T> registerBlock(String name, Supplier<T> block) {
138141
DeferredBlock<T> toReturn = BLOCKS.register(name, block);
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package net.kaupenjoe.tutorialmod.block.custom;
2+
3+
import com.mojang.serialization.MapCodec;
4+
import net.kaupenjoe.tutorialmod.block.entity.PedestalBlockEntity;
5+
import net.minecraft.core.BlockPos;
6+
import net.minecraft.sounds.SoundEvent;
7+
import net.minecraft.sounds.SoundEvents;
8+
import net.minecraft.sounds.SoundSource;
9+
import net.minecraft.world.InteractionHand;
10+
import net.minecraft.world.ItemInteractionResult;
11+
import net.minecraft.world.entity.player.Player;
12+
import net.minecraft.world.item.ItemStack;
13+
import net.minecraft.world.level.BlockGetter;
14+
import net.minecraft.world.level.Level;
15+
import net.minecraft.world.level.block.BaseEntityBlock;
16+
import net.minecraft.world.level.block.Block;
17+
import net.minecraft.world.level.block.RenderShape;
18+
import net.minecraft.world.level.block.entity.BlockEntity;
19+
import net.minecraft.world.level.block.state.BlockState;
20+
import net.minecraft.world.phys.BlockHitResult;
21+
import net.minecraft.world.phys.shapes.CollisionContext;
22+
import net.minecraft.world.phys.shapes.VoxelShape;
23+
import org.jetbrains.annotations.Nullable;
24+
25+
public class PedestalBlock extends BaseEntityBlock {
26+
public static final VoxelShape SHAPE = Block.box(2, 0, 2, 14, 13, 14);
27+
public static final MapCodec<PedestalBlock> CODEC = simpleCodec(PedestalBlock::new);
28+
29+
public PedestalBlock(Properties properties) {
30+
super(properties);
31+
}
32+
33+
@Override
34+
protected VoxelShape getShape(BlockState state, BlockGetter level, BlockPos pos, CollisionContext context) {
35+
return SHAPE;
36+
}
37+
38+
@Override
39+
protected MapCodec<? extends BaseEntityBlock> codec() {
40+
return CODEC;
41+
}
42+
43+
/* BLOCK ENTITY */
44+
45+
@Override
46+
protected RenderShape getRenderShape(BlockState state) {
47+
return RenderShape.MODEL;
48+
}
49+
50+
@Nullable
51+
@Override
52+
public BlockEntity newBlockEntity(BlockPos blockPos, BlockState blockState) {
53+
return new PedestalBlockEntity(blockPos, blockState);
54+
}
55+
56+
@Override
57+
protected void onRemove(BlockState state, Level level, BlockPos pos, BlockState newState, boolean movedByPiston) {
58+
if(state.getBlock() != newState.getBlock()) {
59+
if(level.getBlockEntity(pos) instanceof PedestalBlockEntity pedestalBlockEntity) {
60+
pedestalBlockEntity.drops();
61+
level.updateNeighbourForOutputSignal(pos, this);
62+
}
63+
}
64+
super.onRemove(state, level, pos, newState, movedByPiston);
65+
}
66+
67+
@Override
68+
protected ItemInteractionResult useItemOn(ItemStack stack, BlockState state, Level level, BlockPos pos,
69+
Player player, InteractionHand hand, BlockHitResult hitResult) {
70+
if(level.getBlockEntity(pos) instanceof PedestalBlockEntity pedestalBlockEntity) {
71+
if(pedestalBlockEntity.inventory.getStackInSlot(0).isEmpty() && !stack.isEmpty()) {
72+
pedestalBlockEntity.inventory.insertItem(0, stack.copy(), false);
73+
stack.shrink(1);
74+
level.playSound(player, pos, SoundEvents.ITEM_PICKUP, SoundSource.BLOCKS, 1f, 2f);
75+
} else if(stack.isEmpty()) {
76+
ItemStack stackOnPedestal = pedestalBlockEntity.inventory.extractItem(0, 1, false);
77+
player.setItemInHand(InteractionHand.MAIN_HAND, stackOnPedestal);
78+
pedestalBlockEntity.clearContents();
79+
level.playSound(player, pos, SoundEvents.ITEM_PICKUP, SoundSource.BLOCKS, 1f, 1f);
80+
}
81+
}
82+
83+
return ItemInteractionResult.SUCCESS;
84+
}
85+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package net.kaupenjoe.tutorialmod.block.entity;
2+
3+
import net.kaupenjoe.tutorialmod.TutorialMod;
4+
import net.kaupenjoe.tutorialmod.block.ModBlocks;
5+
import net.minecraft.core.registries.BuiltInRegistries;
6+
import net.minecraft.world.level.block.entity.BlockEntityType;
7+
import net.neoforged.bus.api.IEventBus;
8+
import net.neoforged.neoforge.registries.DeferredRegister;
9+
10+
import java.util.function.Supplier;
11+
12+
public class ModBlockEntities {
13+
public static final DeferredRegister<BlockEntityType<?>> BLOCK_ENTITIES =
14+
DeferredRegister.create(BuiltInRegistries.BLOCK_ENTITY_TYPE, TutorialMod.MOD_ID);
15+
16+
public static final Supplier<BlockEntityType<PedestalBlockEntity>> PEDESTAL_BE =
17+
BLOCK_ENTITIES.register("pedestal_be", () -> BlockEntityType.Builder.of(
18+
PedestalBlockEntity::new, ModBlocks.PEDESTAL.get()).build(null));
19+
20+
public static void register(IEventBus eventBus) {
21+
BLOCK_ENTITIES.register(eventBus);
22+
}
23+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package net.kaupenjoe.tutorialmod.block.entity;
2+
3+
import net.minecraft.core.BlockPos;
4+
import net.minecraft.core.HolderLookup;
5+
import net.minecraft.nbt.CompoundTag;
6+
import net.minecraft.network.protocol.Packet;
7+
import net.minecraft.network.protocol.game.ClientGamePacketListener;
8+
import net.minecraft.network.protocol.game.ClientboundBlockEntityDataPacket;
9+
import net.minecraft.world.Containers;
10+
import net.minecraft.world.SimpleContainer;
11+
import net.minecraft.world.item.ItemStack;
12+
import net.minecraft.world.level.block.entity.BlockEntity;
13+
import net.minecraft.world.level.block.state.BlockState;
14+
import net.neoforged.neoforge.items.ItemStackHandler;
15+
import org.jetbrains.annotations.Nullable;
16+
17+
public class PedestalBlockEntity extends BlockEntity {
18+
public final ItemStackHandler inventory = new ItemStackHandler(1) {
19+
@Override
20+
protected int getStackLimit(int slot, ItemStack stack) {
21+
return 1;
22+
}
23+
24+
@Override
25+
protected void onContentsChanged(int slot) {
26+
setChanged();
27+
if(!level.isClientSide()) {
28+
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
29+
}
30+
}
31+
};
32+
33+
public PedestalBlockEntity(BlockPos pos, BlockState blockState) {
34+
super(ModBlockEntities.PEDESTAL_BE.get(), pos, blockState);
35+
}
36+
37+
public void clearContents() {
38+
inventory.setStackInSlot(0, ItemStack.EMPTY);
39+
}
40+
41+
public void drops() {
42+
SimpleContainer inv = new SimpleContainer(inventory.getSlots());
43+
for(int i = 0; i < inventory.getSlots(); i++) {
44+
inv.setItem(i, inventory.getStackInSlot(i));
45+
}
46+
47+
Containers.dropContents(this.level, this.worldPosition, inv);
48+
}
49+
50+
@Override
51+
protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) {
52+
super.saveAdditional(tag, registries);
53+
tag.put("inventory", inventory.serializeNBT(registries));
54+
}
55+
56+
@Override
57+
protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) {
58+
super.loadAdditional(tag, registries);
59+
inventory.deserializeNBT(registries, tag.getCompound("inventory"));
60+
}
61+
62+
@Nullable
63+
@Override
64+
public Packet<ClientGamePacketListener> getUpdatePacket() {
65+
return ClientboundBlockEntityDataPacket.create(this);
66+
}
67+
68+
@Override
69+
public CompoundTag getUpdateTag(HolderLookup.Provider pRegistries) {
70+
return saveWithoutMetadata(pRegistries);
71+
}
72+
}

src/main/java/net/kaupenjoe/tutorialmod/item/ModCreativeModeTabs.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ public class ModCreativeModeTabs {
9696
output.accept(ModBlocks.BLOODWOOD_LEAVES.get());
9797

9898
output.accept(ModBlocks.CHAIR.get());
99+
output.accept(ModBlocks.PEDESTAL.get());
99100

100101
}).build());
101102

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"variants": {
3+
"": {
4+
"model": "tutorialmod:block/pedestal"
5+
}
6+
}
7+
}

src/main/resources/assets/tutorialmod/lang/en_us.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777

7878
"block.tutorialmod.bloodwood_sapling": "Bloodwood Sapling",
7979
"block.tutorialmod.chair": "Chair",
80+
"block.tutorialmod.pedestal": "Pedestal",
8081

8182

8283
"entity.minecraft.villager.tutorialmod.kaupenger": "Kaupenger",

0 commit comments

Comments
 (0)