summaryrefslogtreecommitdiff
path: root/src/main/java/lv/enes/mc/eris_alchemy/block/ChestLikeBlock.java
diff options
context:
space:
mode:
authorGravatar Uko Kokņevičs2024-01-10 02:05:34 +0100
committerGravatar Uko Kokņevičs2024-01-10 02:05:34 +0100
commitc27088bb3ba8e83d9fd4b5bd0d944be54c1482b2 (patch)
treed257f91576f8f4bc08c87a67ba44036b4d86cee1 /src/main/java/lv/enes/mc/eris_alchemy/block/ChestLikeBlock.java
parentSome refactoring (diff)
downloadmc-eris-alchemy-c27088bb3ba8e83d9fd4b5bd0d944be54c1482b2.tar.gz
mc-eris-alchemy-c27088bb3ba8e83d9fd4b5bd0d944be54c1482b2.tar.xz
mc-eris-alchemy-c27088bb3ba8e83d9fd4b5bd0d944be54c1482b2.zip
Move out common chest logic to separate files
Diffstat (limited to 'src/main/java/lv/enes/mc/eris_alchemy/block/ChestLikeBlock.java')
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/block/ChestLikeBlock.java213
1 files changed, 213 insertions, 0 deletions
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/block/ChestLikeBlock.java b/src/main/java/lv/enes/mc/eris_alchemy/block/ChestLikeBlock.java
new file mode 100644
index 0000000..e50563a
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/block/ChestLikeBlock.java
@@ -0,0 +1,213 @@
1package lv.enes.mc.eris_alchemy.block;
2
3import jakarta.annotation.Nonnull;
4import lv.enes.mc.eris_alchemy.block.entity.ChestLikeBlockEntity;
5import net.minecraft.core.BlockPos;
6import net.minecraft.core.Direction;
7import net.minecraft.network.chat.Component;
8import net.minecraft.world.*;
9import net.minecraft.world.entity.monster.piglin.PiglinAi;
10import net.minecraft.world.entity.player.Player;
11import net.minecraft.world.inventory.AbstractContainerMenu;
12import net.minecraft.world.item.context.BlockPlaceContext;
13import net.minecraft.world.level.BlockGetter;
14import net.minecraft.world.level.Level;
15import net.minecraft.world.level.LevelAccessor;
16import net.minecraft.world.level.block.*;
17import net.minecraft.world.level.block.DoubleBlockCombiner.NeighborCombineResult;
18import net.minecraft.world.level.block.entity.BlockEntity;
19import net.minecraft.world.level.block.entity.BlockEntityTicker;
20import net.minecraft.world.level.block.entity.BlockEntityType;
21import net.minecraft.world.level.block.entity.ChestBlockEntity;
22import net.minecraft.world.level.block.state.BlockState;
23import net.minecraft.world.level.block.state.StateDefinition;
24import net.minecraft.world.level.block.state.properties.BlockStateProperties;
25import net.minecraft.world.level.block.state.properties.BooleanProperty;
26import net.minecraft.world.level.block.state.properties.DirectionProperty;
27import net.minecraft.world.level.material.FluidState;
28import net.minecraft.world.level.material.Fluids;
29import net.minecraft.world.level.pathfinder.PathComputationType;
30import net.minecraft.world.phys.BlockHitResult;
31import net.minecraft.world.phys.shapes.CollisionContext;
32import net.minecraft.world.phys.shapes.VoxelShape;
33
34import java.util.function.Supplier;
35
36public abstract class ChestLikeBlock<E extends ChestLikeBlockEntity>
37 extends AbstractChestBlock<E>
38 implements SimpleWaterloggedBlock
39{
40 public static final DirectionProperty FACING = BlockStateProperties.HORIZONTAL_FACING;
41 public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED;
42
43 public static final VoxelShape SHAPE = Block.box(
44 1.0, 0.0, 1.0,
45 15.0, 14.0, 15.0
46 );
47
48 protected ChestLikeBlock(Properties settings, Supplier<BlockEntityType<? extends E>> blockEntityTypeSupplier) {
49 super(settings, blockEntityTypeSupplier);
50 registerDefaultState(getStateDefinition().any()
51 .setValue(FACING, Direction.NORTH)
52 .setValue(WATERLOGGED, false)
53 );
54 }
55
56 @Nonnull
57 protected abstract Component getContainerTitle();
58
59 @Nonnull
60 @Override
61 public NeighborCombineResult<? extends ChestBlockEntity> combine(
62 BlockState state,
63 Level world,
64 BlockPos pos,
65 boolean ignoreBlocked
66 ) {
67 return DoubleBlockCombiner.Combiner::acceptNone;
68 }
69
70 @SuppressWarnings("deprecation")
71 @Override
72 public int getAnalogOutputSignal(BlockState state, Level world, BlockPos pos) {
73 if (world.getBlockEntity(pos) instanceof Container container) {
74 return AbstractContainerMenu.getRedstoneSignalFromContainer(container);
75 }
76 return 0;
77 }
78
79 @SuppressWarnings("deprecation")
80 @Nonnull
81 @Override
82 public FluidState getFluidState(BlockState state) {
83 return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state);
84 }
85
86 @Override
87 public MenuProvider getMenuProvider(BlockState state, Level world, BlockPos pos) {
88 if (world.getBlockEntity(pos) instanceof ChestLikeBlockEntity entity) {
89 return new SimpleMenuProvider(entity, getContainerTitle());
90 }
91 return null;
92 }
93
94 @Nonnull
95 @Override
96 public RenderShape getRenderShape(BlockState state) {
97 return RenderShape.ENTITYBLOCK_ANIMATED;
98 }
99
100 @SuppressWarnings("deprecation")
101 @Nonnull
102 @Override
103 public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext ctx) {
104 return SHAPE;
105 }
106
107 @Override
108 public BlockState getStateForPlacement(BlockPlaceContext ctx) {
109 return defaultBlockState()
110 .setValue(FACING, ctx.getHorizontalDirection().getOpposite())
111 .setValue(WATERLOGGED, ctx.getLevel().getFluidState(ctx.getClickedPos()).is(Fluids.WATER));
112 }
113
114 @Override
115 public <T extends BlockEntity> BlockEntityTicker<T> getTicker(
116 Level ignoredWorld,
117 BlockState ignoredState,
118 BlockEntityType<T> type
119 ) {
120 return createTickerHelper(
121 type,
122 blockEntityType.get(),
123 (world, pos, state, entity) -> entity.tick(world, pos, state)
124 );
125 }
126
127 @SuppressWarnings("deprecation")
128 @Override
129 public boolean hasAnalogOutputSignal(BlockState state) {
130 return true;
131 }
132
133 @SuppressWarnings("deprecation")
134 @Override
135 public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) {
136 return false;
137 }
138
139 @SuppressWarnings("deprecation")
140 @Nonnull
141 @Override
142 public BlockState mirror(BlockState state, Mirror mirror) {
143 return state.rotate(mirror.getRotation(state.getValue(FACING)));
144 }
145
146 @SuppressWarnings("deprecation")
147 @Override
148 public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean moved) {
149 if (!state.is(newState.getBlock())) {
150 if (world.getBlockEntity(pos) instanceof Container container) {
151 Containers.dropContents(world, pos, container);
152 world.updateNeighbourForOutputSignal(pos, this);
153 }
154
155 super.onRemove(state, world, pos, newState, moved);
156 }
157 }
158
159 @SuppressWarnings("deprecation")
160 @Nonnull
161 @Override
162 public BlockState rotate(BlockState state, Rotation rotation) {
163 return state.setValue(FACING, rotation.rotate(state.getValue(FACING)));
164 }
165
166 @SuppressWarnings("deprecation")
167 @Nonnull
168 @Override
169 public BlockState updateShape(
170 BlockState state,
171 Direction direction,
172 BlockState neighborState,
173 LevelAccessor world,
174 BlockPos pos,
175 BlockPos neighborPos
176 ) {
177 if (state.getValue(WATERLOGGED)) {
178 world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world));
179 }
180
181 return super.updateShape(state, direction, neighborState, world, pos, neighborPos);
182 }
183
184 @SuppressWarnings("deprecation")
185 @Nonnull
186 @Override
187 public InteractionResult use(
188 BlockState state,
189 Level world,
190 BlockPos pos,
191 Player player,
192 InteractionHand hand,
193 BlockHitResult hit
194 ) {
195 if (world.isClientSide) {
196 return InteractionResult.SUCCESS;
197 }
198
199 var provider = getMenuProvider(state, world, pos);
200 if (provider != null) {
201 player.openMenu(provider);
202 // TODO: player.awardStat(getOpenChestStat);
203 PiglinAi.angerNearbyPiglins(player, true);
204 }
205
206 return InteractionResult.CONSUME;
207 }
208
209 @Override
210 protected void createBlockStateDefinition(StateDefinition.Builder<Block, BlockState> builder) {
211 builder.add(FACING, WATERLOGGED);
212 }
213}