summaryrefslogtreecommitdiff
path: root/src/main/java/lv/enes/mc/eris_alchemy/block/entity
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/entity
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/entity')
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/block/entity/AlchemicalChestBlockEntity.java174
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/block/entity/ChestLikeBlockEntity.java200
2 files changed, 208 insertions, 166 deletions
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/block/entity/AlchemicalChestBlockEntity.java b/src/main/java/lv/enes/mc/eris_alchemy/block/entity/AlchemicalChestBlockEntity.java
index 1e881f8..bac49b6 100644
--- a/src/main/java/lv/enes/mc/eris_alchemy/block/entity/AlchemicalChestBlockEntity.java
+++ b/src/main/java/lv/enes/mc/eris_alchemy/block/entity/AlchemicalChestBlockEntity.java
@@ -3,202 +3,44 @@ package lv.enes.mc.eris_alchemy.block.entity;
3import jakarta.annotation.Nonnull; 3import jakarta.annotation.Nonnull;
4import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry; 4import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry;
5import lv.enes.mc.eris_alchemy.menu.AlchemicalChestMenu; 5import lv.enes.mc.eris_alchemy.menu.AlchemicalChestMenu;
6import lv.enes.mc.eris_alchemy.menu.ChestLikeBlockMenu;
6import net.minecraft.core.BlockPos; 7import net.minecraft.core.BlockPos;
7import net.minecraft.core.NonNullList; 8import net.minecraft.core.NonNullList;
8import net.minecraft.nbt.CompoundTag;
9import net.minecraft.network.chat.Component; 9import net.minecraft.network.chat.Component;
10import net.minecraft.sounds.SoundEvents;
11import net.minecraft.sounds.SoundSource;
12import net.minecraft.world.Container;
13import net.minecraft.world.ContainerHelper;
14import net.minecraft.world.entity.player.Inventory; 10import net.minecraft.world.entity.player.Inventory;
15import net.minecraft.world.entity.player.Player;
16import net.minecraft.world.inventory.AbstractContainerMenu;
17import net.minecraft.world.item.ItemStack; 11import net.minecraft.world.item.ItemStack;
18import net.minecraft.world.level.Level; 12import net.minecraft.world.level.block.Block;
19import net.minecraft.world.level.block.entity.BaseContainerBlockEntity;
20import net.minecraft.world.level.block.entity.ChestLidController;
21import net.minecraft.world.level.block.entity.ContainerOpenersCounter;
22import net.minecraft.world.level.block.entity.LidBlockEntity;
23import net.minecraft.world.level.block.state.BlockState; 13import net.minecraft.world.level.block.state.BlockState;
24 14
25public class AlchemicalChestBlockEntity extends BaseContainerBlockEntity implements LidBlockEntity { 15public class AlchemicalChestBlockEntity extends ChestLikeBlockEntity {
26 private final static int WIDTH = 13; 16 private final static int WIDTH = 13;
27 private final static int HEIGHT = 8; 17 private final static int HEIGHT = 8;
28 18
29 private final static int EVENT = 1;
30
31 private final NonNullList<ItemStack> items = NonNullList.withSize(WIDTH * HEIGHT, ItemStack.EMPTY); 19 private final NonNullList<ItemStack> items = NonNullList.withSize(WIDTH * HEIGHT, ItemStack.EMPTY);
32 private final ChestLidController lidController = new ChestLidController();
33 private final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() {
34 @Override
35 protected void onOpen(Level world, BlockPos pos, BlockState state) {
36 // TODO: Sound effects?
37 world.playSound(
38 null,
39 pos.getX() + 0.5,
40 pos.getY() + 0.5,
41 pos.getZ() + 0.5,
42 SoundEvents.ENDER_CHEST_OPEN,
43 SoundSource.BLOCKS,
44 0.5f,
45 world.random.nextFloat() * 0.1f + 0.9f
46 );
47 }
48
49 @Override
50 protected void onClose(Level world, BlockPos pos, BlockState state) {
51 // TODO: Sound effects?
52 world.playSound(
53 null,
54 pos.getX() + 0.5,
55 pos.getY() + 0.5,
56 pos.getZ() + 0.5,
57 SoundEvents.ENDER_CHEST_CLOSE,
58 SoundSource.BLOCKS,
59 0.5f,
60 world.random.nextFloat() * 0.1f + 0.9f
61 );
62 }
63
64 @Override
65 protected void openerCountChanged(
66 Level world,
67 BlockPos pos,
68 BlockState state,
69 int oldViewerCount,
70 int newViewerCount
71 ) {
72 world.blockEvent(worldPosition, ErisAlchemyRegistry.Blocks.ALCHEMICAL_CHEST, EVENT, newViewerCount);
73 }
74
75 @Override
76 protected boolean isOwnContainer(Player player) {
77 if (player.containerMenu instanceof AlchemicalChestMenu menu) {
78 return menu.getContainer() == AlchemicalChestBlockEntity.this;
79 }
80 return false;
81 }
82 };
83 20
84 public AlchemicalChestBlockEntity(BlockPos pos, BlockState state) { 21 public AlchemicalChestBlockEntity(BlockPos pos, BlockState state) {
85 super(ErisAlchemyRegistry.BlockEntities.ALCHEMICAL_CHEST, pos, state); 22 super(ErisAlchemyRegistry.BlockEntities.ALCHEMICAL_CHEST, pos, state);
86 } 23 }
87 24
88 @Override
89 public void clearContent() {
90 items.clear();
91 }
92
93 @Nonnull 25 @Nonnull
94 @Override 26 @Override
95 protected AbstractContainerMenu createMenu(int syncId, Inventory playerInventory) { 27 protected ChestLikeBlockMenu createMenu(int syncId, Inventory playerInventory) {
96 return new AlchemicalChestMenu(syncId, playerInventory, this); 28 return new AlchemicalChestMenu(syncId, playerInventory, this);
97 } 29 }
98 30
99 @Override
100 public int getContainerSize() {
101 return items.size();
102 }
103
104 @Nonnull 31 @Nonnull
105 @Override 32 @Override
106 protected Component getDefaultName() { 33 protected Component getDefaultName() {
107 return Component.translatable("container.eris_alchemy.alchemical_chest"); 34 return Component.translatable("container.eris_alchemy.alchemical_chest");
108 } 35 }
109 36
110 @Nonnull
111 @Override
112 public ItemStack getItem(int slot) {
113 return items.get(slot);
114 }
115
116 @Override
117 public float getOpenNess(float tickDelta) {
118 return lidController.getOpenness(tickDelta);
119 }
120
121 @Override
122 public boolean isEmpty() {
123 return items.stream().allMatch(ItemStack::isEmpty);
124 }
125
126 @Override
127 public void load(CompoundTag nbt) {
128 super.load(nbt);
129 ContainerHelper.loadAllItems(nbt, items);
130 }
131
132 private void recheckOpen() {
133 if (!remove) {
134 openersCounter.recheckOpeners(getLevel(), getBlockPos(), getBlockState());
135 }
136 }
137
138 @Nonnull
139 @Override
140 public ItemStack removeItem(int slot, int amount) {
141 var stack = ContainerHelper.removeItem(items, slot, amount);
142 if (!stack.isEmpty()) {
143 this.setChanged();
144 }
145 return stack;
146 }
147
148 @Nonnull
149 @Override
150 public ItemStack removeItemNoUpdate(int slot) {
151 return ContainerHelper.takeItem(items, slot);
152 }
153
154 @Override
155 protected void saveAdditional(CompoundTag nbt) {
156 super.saveAdditional(nbt);
157 ContainerHelper.saveAllItems(nbt, items);
158 }
159
160 @Override 37 @Override
161 public void setItem(int slot, ItemStack stack) { 38 protected NonNullList<ItemStack> getItems() {
162 items.set(slot, stack); 39 return items;
163 if (stack.getCount() > getMaxStackSize()) {
164 stack.setCount(getMaxStackSize());
165 }
166 this.setChanged();
167 } 40 }
168 41
169 @Override 42 @Override
170 public void startOpen(Player player) { 43 protected Block getParent() {
171 if (!remove && !player.isSpectator()) { 44 return ErisAlchemyRegistry.Blocks.ALCHEMICAL_CHEST;
172 openersCounter.incrementOpeners(player, getLevel(), getBlockPos(), getBlockState());
173 }
174 }
175
176 @Override
177 public boolean stillValid(Player player) {
178 return Container.stillValidBlockEntity(this, player);
179 }
180
181 @Override
182 public void stopOpen(Player player) {
183 if (!remove && !player.isSpectator()) {
184 openersCounter.decrementOpeners(player, getLevel(), getBlockPos(), getBlockState());
185 }
186 }
187
188 public void tick(Level world, BlockPos ignoredPos, BlockState ignoredState) {
189 if (world.isClientSide) {
190 lidController.tickLid();
191 }
192 recheckOpen();
193 }
194
195 @Override
196 public boolean triggerEvent(int type, int data) {
197 if (type == EVENT) {
198 lidController.shouldBeOpen(data > 0);
199 return true;
200 }
201
202 return super.triggerEvent(type, data);
203 } 45 }
204} 46}
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/block/entity/ChestLikeBlockEntity.java b/src/main/java/lv/enes/mc/eris_alchemy/block/entity/ChestLikeBlockEntity.java
new file mode 100644
index 0000000..48b3ad7
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/block/entity/ChestLikeBlockEntity.java
@@ -0,0 +1,200 @@
1package lv.enes.mc.eris_alchemy.block.entity;
2
3import jakarta.annotation.Nonnull;
4import jakarta.annotation.Nullable;
5import lv.enes.mc.eris_alchemy.menu.ChestLikeBlockMenu;
6import net.minecraft.core.BlockPos;
7import net.minecraft.core.NonNullList;
8import net.minecraft.nbt.CompoundTag;
9import net.minecraft.sounds.SoundEvents;
10import net.minecraft.sounds.SoundSource;
11import net.minecraft.world.Container;
12import net.minecraft.world.ContainerHelper;
13import net.minecraft.world.entity.player.Player;
14import net.minecraft.world.item.ItemStack;
15import net.minecraft.world.level.Level;
16import net.minecraft.world.level.block.Block;
17import net.minecraft.world.level.block.entity.*;
18import net.minecraft.world.level.block.state.BlockState;
19
20public abstract class ChestLikeBlockEntity extends BaseContainerBlockEntity implements LidBlockEntity {
21 protected static final int EVENT_INTERACTED = 1;
22
23 protected final ChestLidController lidController = new ChestLidController();
24 protected final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() {
25 @Override
26 protected void onOpen(Level world, BlockPos pos, BlockState state) {
27 ChestLikeBlockEntity.this.onOpen(world, pos);
28 }
29
30 @Override
31 protected void onClose(Level world, BlockPos pos, BlockState state) {
32 ChestLikeBlockEntity.this.onClose(world, pos);
33 }
34
35 @Override
36 protected void openerCountChanged(Level world, BlockPos pos, BlockState state, int oldViewerCount, int newViewerCount) {
37 world.blockEvent(worldPosition, getParent(), EVENT_INTERACTED, newViewerCount);
38 }
39
40 @Override
41 protected boolean isOwnContainer(Player player) {
42 if (player.containerMenu instanceof ChestLikeBlockMenu menu) {
43 return menu.getContainer() == ChestLikeBlockEntity.this;
44 }
45 return false;
46 }
47 };
48
49 public ChestLikeBlockEntity(
50 BlockEntityType<? extends ChestLikeBlockEntity> type,
51 BlockPos pos,
52 BlockState state
53 ) {
54 super(type, pos, state);
55 }
56
57 protected abstract Block getParent();
58 protected abstract NonNullList<ItemStack> getItems();
59
60 @Override
61 public void clearContent() {
62 getItems().clear();
63 }
64
65 @Override
66 public int getContainerSize() {
67 return getItems().size();
68 }
69
70 @Nonnull
71 @Override
72 public ItemStack getItem(int slot) {
73 return getItems().get(slot);
74 }
75
76 @Override
77 public float getOpenNess(float tickDelta) {
78 return lidController.getOpenness(tickDelta);
79 }
80
81 @Override
82 public boolean isEmpty() {
83 return getItems().stream().allMatch(ItemStack::isEmpty);
84 }
85
86 @Override
87 public void load(CompoundTag nbt) {
88 super.load(nbt);
89 ContainerHelper.loadAllItems(nbt, getItems());
90 }
91
92 protected void onClose(@Nullable Level world, BlockPos pos) {
93 if (world == null) {
94 return;
95 }
96
97 world.playSound(
98 null,
99 pos.getX() + 0.5,
100 pos.getY() + 0.5,
101 pos.getZ() + 0.5,
102 SoundEvents.CHEST_OPEN,
103 SoundSource.BLOCKS,
104 0.5f,
105 world.random.nextFloat() * 0.1f + 0.9f
106 );
107 }
108
109 protected void onOpen(@Nullable Level world, BlockPos pos) {
110 if (world == null) {
111 return;
112 }
113
114 world.playSound(
115 null,
116 pos.getX() + 0.5,
117 pos.getY() + 0.5,
118 pos.getZ() + 0.5,
119 SoundEvents.CHEST_CLOSE,
120 SoundSource.BLOCKS,
121 0.5f,
122 world.random.nextFloat() * 0.1f + 0.9f
123 );
124 }
125
126 private void recheckOpen() {
127 if (!remove) {
128 openersCounter.recheckOpeners(getLevel(), getBlockPos(), getBlockState());
129 }
130 }
131
132 @Nonnull
133 @Override
134 public ItemStack removeItem(int slot, int amount) {
135 var stack = ContainerHelper.removeItem(getItems(), slot, amount);
136 if (!stack.isEmpty()) {
137 this.setChanged();
138 }
139 return stack;
140 }
141
142 @Nonnull
143 @Override
144 public ItemStack removeItemNoUpdate(int slot) {
145 return ContainerHelper.takeItem(getItems(), slot);
146 }
147
148 @Override
149 protected void saveAdditional(CompoundTag nbt) {
150 super.saveAdditional(nbt);
151 ContainerHelper.saveAllItems(nbt, getItems());
152 }
153
154 @Override
155 public void setItem(int slot, ItemStack stack) {
156 getItems().set(slot, stack);
157 if (stack.getCount() > getMaxStackSize()) {
158 stack.setCount(getMaxStackSize());
159 }
160 this.setChanged();
161 }
162
163 @Override
164 public void startOpen(Player player) {
165 if (!remove && !player.isSpectator()) {
166 openersCounter.incrementOpeners(player, getLevel(), getBlockPos(), getBlockState());
167 }
168 }
169
170 @Override
171 public boolean stillValid(Player player) {
172 return Container.stillValidBlockEntity(this, player);
173 }
174
175 @Override
176 public void stopOpen(Player player) {
177 if (!remove && !player.isSpectator()) {
178 openersCounter.decrementOpeners(player, getLevel(), getBlockPos(), getBlockState());
179 }
180 }
181
182 public void tick(Level world, BlockPos ignoredPos, BlockState ignoredState) {
183 if (world.isClientSide) {
184 lidController.tickLid();
185 }
186 recheckOpen();
187 }
188
189
190 @Override
191 public boolean triggerEvent(int type, int data) {
192 if (type == EVENT_INTERACTED) {
193 lidController.shouldBeOpen(data > 0);
194 return true;
195 }
196
197 return super.triggerEvent(type, data);
198 }
199}
200