summaryrefslogtreecommitdiff
path: root/src/main/java/lv/enes/mc/eris_alchemy/block
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/lv/enes/mc/eris_alchemy/block')
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/block/AlchemicalChestBlock.java10
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/block/ChestLikeBlock.java6
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/block/EnergyCondenserBlock.java56
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/block/entity/AlchemicalChestEntity.java (renamed from src/main/java/lv/enes/mc/eris_alchemy/block/entity/AlchemicalChestBlockEntity.java)15
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/block/entity/ChestLikeEntity.java (renamed from src/main/java/lv/enes/mc/eris_alchemy/block/entity/ChestLikeBlockEntity.java)27
-rw-r--r--src/main/java/lv/enes/mc/eris_alchemy/block/entity/EnergyCondenserEntity.java143
6 files changed, 228 insertions, 29 deletions
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/block/AlchemicalChestBlock.java b/src/main/java/lv/enes/mc/eris_alchemy/block/AlchemicalChestBlock.java
index d50ee77..eb7cb6e 100644
--- a/src/main/java/lv/enes/mc/eris_alchemy/block/AlchemicalChestBlock.java
+++ b/src/main/java/lv/enes/mc/eris_alchemy/block/AlchemicalChestBlock.java
@@ -3,15 +3,15 @@ package lv.enes.mc.eris_alchemy.block;
3import jakarta.annotation.Nonnull; 3import jakarta.annotation.Nonnull;
4import jakarta.annotation.Nullable; 4import jakarta.annotation.Nullable;
5import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry; 5import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry;
6import lv.enes.mc.eris_alchemy.block.entity.AlchemicalChestBlockEntity; 6import lv.enes.mc.eris_alchemy.block.entity.AlchemicalChestEntity;
7import net.minecraft.core.BlockPos; 7import net.minecraft.core.BlockPos;
8import net.minecraft.network.chat.Component; 8import net.minecraft.network.chat.Component;
9import net.minecraft.world.level.block.entity.BlockEntity; 9import net.minecraft.world.level.block.entity.BlockEntity;
10import net.minecraft.world.level.block.state.BlockState; 10import net.minecraft.world.level.block.state.BlockState;
11 11
12public class AlchemicalChestBlock extends ChestLikeBlock<AlchemicalChestBlockEntity> 12public class AlchemicalChestBlock extends ChestLikeBlock<AlchemicalChestEntity> {
13{ 13 public static final Component CONTAINER_TITLE
14 public static final Component CONTAINER_TITLE = Component.translatable("container.eris_alchemy.alchemical_chest"); 14 = Component.translatable("container.eris_alchemy.alchemical_chest");
15 15
16 public AlchemicalChestBlock(Properties properties) { 16 public AlchemicalChestBlock(Properties properties) {
17 super(properties, () -> ErisAlchemyRegistry.BlockEntities.ALCHEMICAL_CHEST); 17 super(properties, () -> ErisAlchemyRegistry.BlockEntities.ALCHEMICAL_CHEST);
@@ -26,6 +26,6 @@ public class AlchemicalChestBlock extends ChestLikeBlock<AlchemicalChestBlockEnt
26 @Nullable 26 @Nullable
27 @Override 27 @Override
28 public BlockEntity newBlockEntity(BlockPos pos, BlockState state) { 28 public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
29 return new AlchemicalChestBlockEntity(pos, state); 29 return new AlchemicalChestEntity(pos, state);
30 } 30 }
31} 31}
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
index e50563a..ade24fb 100644
--- a/src/main/java/lv/enes/mc/eris_alchemy/block/ChestLikeBlock.java
+++ b/src/main/java/lv/enes/mc/eris_alchemy/block/ChestLikeBlock.java
@@ -1,7 +1,7 @@
1package lv.enes.mc.eris_alchemy.block; 1package lv.enes.mc.eris_alchemy.block;
2 2
3import jakarta.annotation.Nonnull; 3import jakarta.annotation.Nonnull;
4import lv.enes.mc.eris_alchemy.block.entity.ChestLikeBlockEntity; 4import lv.enes.mc.eris_alchemy.block.entity.ChestLikeEntity;
5import net.minecraft.core.BlockPos; 5import net.minecraft.core.BlockPos;
6import net.minecraft.core.Direction; 6import net.minecraft.core.Direction;
7import net.minecraft.network.chat.Component; 7import net.minecraft.network.chat.Component;
@@ -33,7 +33,7 @@ import net.minecraft.world.phys.shapes.VoxelShape;
33 33
34import java.util.function.Supplier; 34import java.util.function.Supplier;
35 35
36public abstract class ChestLikeBlock<E extends ChestLikeBlockEntity> 36public abstract class ChestLikeBlock<E extends ChestLikeEntity>
37 extends AbstractChestBlock<E> 37 extends AbstractChestBlock<E>
38 implements SimpleWaterloggedBlock 38 implements SimpleWaterloggedBlock
39{ 39{
@@ -85,7 +85,7 @@ public abstract class ChestLikeBlock<E extends ChestLikeBlockEntity>
85 85
86 @Override 86 @Override
87 public MenuProvider getMenuProvider(BlockState state, Level world, BlockPos pos) { 87 public MenuProvider getMenuProvider(BlockState state, Level world, BlockPos pos) {
88 if (world.getBlockEntity(pos) instanceof ChestLikeBlockEntity entity) { 88 if (world.getBlockEntity(pos) instanceof ChestLikeEntity entity) {
89 return new SimpleMenuProvider(entity, getContainerTitle()); 89 return new SimpleMenuProvider(entity, getContainerTitle());
90 } 90 }
91 return null; 91 return null;
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/block/EnergyCondenserBlock.java b/src/main/java/lv/enes/mc/eris_alchemy/block/EnergyCondenserBlock.java
new file mode 100644
index 0000000..86ac061
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/block/EnergyCondenserBlock.java
@@ -0,0 +1,56 @@
1package lv.enes.mc.eris_alchemy.block;
2
3import jakarta.annotation.Nonnull;
4import jakarta.annotation.Nullable;
5import lv.enes.mc.eris_alchemy.EMC;
6import lv.enes.mc.eris_alchemy.EmcStorage;
7import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry;
8import lv.enes.mc.eris_alchemy.block.entity.EnergyCondenserEntity;
9import net.minecraft.core.BlockPos;
10import net.minecraft.nbt.CompoundTag;
11import net.minecraft.network.chat.Component;
12import net.minecraft.world.item.ItemStack;
13import net.minecraft.world.item.TooltipFlag;
14import net.minecraft.world.level.BlockGetter;
15import net.minecraft.world.level.block.entity.BlockEntity;
16import net.minecraft.world.level.block.state.BlockState;
17
18import java.util.List;
19
20public class EnergyCondenserBlock extends ChestLikeBlock<EnergyCondenserEntity> implements EmcStorage {
21 public static final Component CONTAINER_TITLE
22 = Component.translatable("container.eris_alchemy.energy_condenser");
23
24 public EnergyCondenserBlock(Properties properties) {
25 super(properties, () -> ErisAlchemyRegistry.BlockEntities.ENERGY_CONDENSER);
26 }
27
28 @Override
29 public void appendHoverText(
30 ItemStack stack,
31 @Nullable BlockGetter world,
32 List<Component> tooltip,
33 TooltipFlag options
34 ) {
35 if (getStoredEmc(stack) >= 0.1) {
36 tooltip.add(Component.literal("Stored EMC: %s".formatted(EMC.formatEmc(getStoredEmc(stack)))));
37 }
38 }
39
40 @Override
41 @Nonnull
42 protected Component getContainerTitle() {
43 return CONTAINER_TITLE;
44 }
45
46 @Override
47 public double getStoredEmc(ItemStack stack, CompoundTag blockEntityData) {
48 return blockEntityData.getDouble("stored_emc");
49 }
50
51 @Nullable
52 @Override
53 public BlockEntity newBlockEntity(BlockPos pos, BlockState state) {
54 return new EnergyCondenserEntity(pos, state);
55 }
56}
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/AlchemicalChestEntity.java
index bac49b6..38ed902 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/AlchemicalChestEntity.java
@@ -3,37 +3,30 @@ 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 lv.enes.mc.eris_alchemy.menu.ChestLikeMenu;
7import net.minecraft.core.BlockPos; 7import net.minecraft.core.BlockPos;
8import net.minecraft.core.NonNullList; 8import net.minecraft.core.NonNullList;
9import net.minecraft.network.chat.Component;
10import net.minecraft.world.entity.player.Inventory; 9import net.minecraft.world.entity.player.Inventory;
11import net.minecraft.world.item.ItemStack; 10import net.minecraft.world.item.ItemStack;
12import net.minecraft.world.level.block.Block; 11import net.minecraft.world.level.block.Block;
13import net.minecraft.world.level.block.state.BlockState; 12import net.minecraft.world.level.block.state.BlockState;
14 13
15public class AlchemicalChestBlockEntity extends ChestLikeBlockEntity { 14public class AlchemicalChestEntity extends ChestLikeEntity {
16 private final static int WIDTH = 13; 15 private final static int WIDTH = 13;
17 private final static int HEIGHT = 8; 16 private final static int HEIGHT = 8;
18 17
19 private final NonNullList<ItemStack> items = NonNullList.withSize(WIDTH * HEIGHT, ItemStack.EMPTY); 18 private final NonNullList<ItemStack> items = NonNullList.withSize(WIDTH * HEIGHT, ItemStack.EMPTY);
20 19
21 public AlchemicalChestBlockEntity(BlockPos pos, BlockState state) { 20 public AlchemicalChestEntity(BlockPos pos, BlockState state) {
22 super(ErisAlchemyRegistry.BlockEntities.ALCHEMICAL_CHEST, pos, state); 21 super(ErisAlchemyRegistry.BlockEntities.ALCHEMICAL_CHEST, pos, state);
23 } 22 }
24 23
25 @Nonnull 24 @Nonnull
26 @Override 25 @Override
27 protected ChestLikeBlockMenu createMenu(int syncId, Inventory playerInventory) { 26 protected ChestLikeMenu createMenu(int syncId, Inventory playerInventory) {
28 return new AlchemicalChestMenu(syncId, playerInventory, this); 27 return new AlchemicalChestMenu(syncId, playerInventory, this);
29 } 28 }
30 29
31 @Nonnull
32 @Override
33 protected Component getDefaultName() {
34 return Component.translatable("container.eris_alchemy.alchemical_chest");
35 }
36
37 @Override 30 @Override
38 protected NonNullList<ItemStack> getItems() { 31 protected NonNullList<ItemStack> getItems() {
39 return items; 32 return items;
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/ChestLikeEntity.java
index 48b3ad7..362b054 100644
--- a/src/main/java/lv/enes/mc/eris_alchemy/block/entity/ChestLikeBlockEntity.java
+++ b/src/main/java/lv/enes/mc/eris_alchemy/block/entity/ChestLikeEntity.java
@@ -2,10 +2,11 @@ package lv.enes.mc.eris_alchemy.block.entity;
2 2
3import jakarta.annotation.Nonnull; 3import jakarta.annotation.Nonnull;
4import jakarta.annotation.Nullable; 4import jakarta.annotation.Nullable;
5import lv.enes.mc.eris_alchemy.menu.ChestLikeBlockMenu; 5import lv.enes.mc.eris_alchemy.menu.ChestLikeMenu;
6import net.minecraft.core.BlockPos; 6import net.minecraft.core.BlockPos;
7import net.minecraft.core.NonNullList; 7import net.minecraft.core.NonNullList;
8import net.minecraft.nbt.CompoundTag; 8import net.minecraft.nbt.CompoundTag;
9import net.minecraft.network.chat.Component;
9import net.minecraft.sounds.SoundEvents; 10import net.minecraft.sounds.SoundEvents;
10import net.minecraft.sounds.SoundSource; 11import net.minecraft.sounds.SoundSource;
11import net.minecraft.world.Container; 12import net.minecraft.world.Container;
@@ -17,19 +18,19 @@ import net.minecraft.world.level.block.Block;
17import net.minecraft.world.level.block.entity.*; 18import net.minecraft.world.level.block.entity.*;
18import net.minecraft.world.level.block.state.BlockState; 19import net.minecraft.world.level.block.state.BlockState;
19 20
20public abstract class ChestLikeBlockEntity extends BaseContainerBlockEntity implements LidBlockEntity { 21public abstract class ChestLikeEntity extends BaseContainerBlockEntity implements LidBlockEntity {
21 protected static final int EVENT_INTERACTED = 1; 22 protected static final int EVENT_INTERACTED = 1;
22 23
23 protected final ChestLidController lidController = new ChestLidController(); 24 protected final ChestLidController lidController = new ChestLidController();
24 protected final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() { 25 protected final ContainerOpenersCounter openersCounter = new ContainerOpenersCounter() {
25 @Override 26 @Override
26 protected void onOpen(Level world, BlockPos pos, BlockState state) { 27 protected void onOpen(Level world, BlockPos pos, BlockState state) {
27 ChestLikeBlockEntity.this.onOpen(world, pos); 28 ChestLikeEntity.this.onOpen(world, pos);
28 } 29 }
29 30
30 @Override 31 @Override
31 protected void onClose(Level world, BlockPos pos, BlockState state) { 32 protected void onClose(Level world, BlockPos pos, BlockState state) {
32 ChestLikeBlockEntity.this.onClose(world, pos); 33 ChestLikeEntity.this.onClose(world, pos);
33 } 34 }
34 35
35 @Override 36 @Override
@@ -39,15 +40,15 @@ public abstract class ChestLikeBlockEntity extends BaseContainerBlockEntity impl
39 40
40 @Override 41 @Override
41 protected boolean isOwnContainer(Player player) { 42 protected boolean isOwnContainer(Player player) {
42 if (player.containerMenu instanceof ChestLikeBlockMenu menu) { 43 if (player.containerMenu instanceof ChestLikeMenu menu) {
43 return menu.getContainer() == ChestLikeBlockEntity.this; 44 return menu.getContainer() == ChestLikeEntity.this;
44 } 45 }
45 return false; 46 return false;
46 } 47 }
47 }; 48 };
48 49
49 public ChestLikeBlockEntity( 50 public ChestLikeEntity(
50 BlockEntityType<? extends ChestLikeBlockEntity> type, 51 BlockEntityType<? extends ChestLikeEntity> type,
51 BlockPos pos, 52 BlockPos pos,
52 BlockState state 53 BlockState state
53 ) { 54 ) {
@@ -69,6 +70,12 @@ public abstract class ChestLikeBlockEntity extends BaseContainerBlockEntity impl
69 70
70 @Nonnull 71 @Nonnull
71 @Override 72 @Override
73 protected Component getDefaultName() {
74 return getBlockState().getBlock().getName();
75 }
76
77 @Nonnull
78 @Override
72 public ItemStack getItem(int slot) { 79 public ItemStack getItem(int slot) {
73 return getItems().get(slot); 80 return getItems().get(slot);
74 } 81 }
@@ -134,7 +141,7 @@ public abstract class ChestLikeBlockEntity extends BaseContainerBlockEntity impl
134 public ItemStack removeItem(int slot, int amount) { 141 public ItemStack removeItem(int slot, int amount) {
135 var stack = ContainerHelper.removeItem(getItems(), slot, amount); 142 var stack = ContainerHelper.removeItem(getItems(), slot, amount);
136 if (!stack.isEmpty()) { 143 if (!stack.isEmpty()) {
137 this.setChanged(); 144 setChanged();
138 } 145 }
139 return stack; 146 return stack;
140 } 147 }
@@ -157,7 +164,7 @@ public abstract class ChestLikeBlockEntity extends BaseContainerBlockEntity impl
157 if (stack.getCount() > getMaxStackSize()) { 164 if (stack.getCount() > getMaxStackSize()) {
158 stack.setCount(getMaxStackSize()); 165 stack.setCount(getMaxStackSize());
159 } 166 }
160 this.setChanged(); 167 setChanged();
161 } 168 }
162 169
163 @Override 170 @Override
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/block/entity/EnergyCondenserEntity.java b/src/main/java/lv/enes/mc/eris_alchemy/block/entity/EnergyCondenserEntity.java
new file mode 100644
index 0000000..dfe07a4
--- /dev/null
+++ b/src/main/java/lv/enes/mc/eris_alchemy/block/entity/EnergyCondenserEntity.java
@@ -0,0 +1,143 @@
1package lv.enes.mc.eris_alchemy.block.entity;
2
3import jakarta.annotation.Nonnull;
4import lv.enes.mc.eris_alchemy.EMC;
5import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry;
6import lv.enes.mc.eris_alchemy.menu.ChestLikeMenu;
7import lv.enes.mc.eris_alchemy.menu.EnergyCondenserMenu;
8import lv.enes.mc.eris_alchemy.utils.ContainerOpenersCounterUtil;
9import lv.enes.mc.eris_alchemy.utils.SyncedValue.SyncedDouble;
10import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory;
11import net.minecraft.core.BlockPos;
12import net.minecraft.core.NonNullList;
13import net.minecraft.nbt.CompoundTag;
14import net.minecraft.network.FriendlyByteBuf;
15import net.minecraft.server.level.ServerPlayer;
16import net.minecraft.world.entity.player.Inventory;
17import net.minecraft.world.item.ItemStack;
18import net.minecraft.world.level.Level;
19import net.minecraft.world.level.block.Block;
20import net.minecraft.world.level.block.state.BlockState;
21
22import java.util.stream.IntStream;
23
24public class EnergyCondenserEntity extends ChestLikeEntity implements ExtendedScreenHandlerFactory {
25 private final static int WIDTH = 13;
26 private final static int HEIGHT = 7;
27
28 private final NonNullList<ItemStack> items = NonNullList.withSize(WIDTH * HEIGHT + 1, ItemStack.EMPTY);
29
30 public final SyncedDouble storedEmc = new SyncedDouble(0);
31
32 public EnergyCondenserEntity(BlockPos pos, BlockState state) {
33 super(ErisAlchemyRegistry.BlockEntities.ENERGY_CONDENSER, pos, state);
34 }
35
36 @Nonnull
37 @Override
38 protected ChestLikeMenu createMenu(int syncId, Inventory playerInventory) {
39 return new EnergyCondenserMenu(syncId, playerInventory, this);
40 }
41
42 @Override
43 protected NonNullList<ItemStack> getItems() {
44 return items;
45 }
46
47 @Override
48 protected Block getParent() {
49 return ErisAlchemyRegistry.Blocks.ENERGY_CONDENSER;
50 }
51
52 public double getStoredEmc() {
53 return storedEmc.getValue();
54 }
55
56 public SyncedDouble getStoredEmcSyncer() {
57 return storedEmc;
58 }
59
60 @Override
61 public void load(CompoundTag nbt) {
62 super.load(nbt);
63 storedEmc.setValue(nbt.getDouble("stored_emc"));
64 }
65
66 @Override
67 protected void saveAdditional(CompoundTag nbt) {
68 super.saveAdditional(nbt);
69 nbt.putDouble("stored_emc", storedEmc.getValue());
70 }
71
72 public void setStoredEmc(double storedEmc) {
73 this.storedEmc.setValue(storedEmc);
74 setChanged();
75 }
76
77 @Override
78 public void tick(Level world, BlockPos pos, BlockState state) {
79 super.tick(world, pos, state);
80 EMC.getInstance(world).get(items.get(0)).ifPresent(cost -> {
81 tryConsumeEmc(world, cost);
82 tryCloneTemplate(cost);
83 });
84
85 this.storedEmc.syncIfChanged(ContainerOpenersCounterUtil.getOpeners(openersCounter));
86 }
87
88 @Override
89 public void writeScreenOpeningData(ServerPlayer player, FriendlyByteBuf buf) {
90 storedEmc.serialize(buf);
91 }
92
93 private void tryCloneTemplate(double cost) {
94 if (cost > getStoredEmc()) {
95 return;
96 }
97
98 var template = items.get(0);
99
100 items.stream()
101 .skip(1) // skip template
102 .filter(stack -> ItemStack.isSameItemSameTags(template, stack))
103 .filter(stack -> stack.getCount() < getMaxStackSize() && stack.getCount() < stack.getMaxStackSize())
104 .findFirst()
105 .ifPresentOrElse(
106 stack -> {
107 stack.setCount(stack.getCount() + 1);
108 setStoredEmc(getStoredEmc() - cost);
109 setChanged();
110 },
111 () -> IntStream.range(1, items.size())
112 .filter(i -> items.get(i).isEmpty())
113 .findFirst()
114 .ifPresent(emptySlot -> {
115 items.set(emptySlot, template.copyWithCount(1));
116 setStoredEmc(getStoredEmc() - cost);
117 setChanged();
118 })
119 );
120 }
121
122 private void tryConsumeEmc(Level world, double cost) {
123 if (cost <= getStoredEmc()) {
124 return;
125 }
126
127 var emc = EMC.getInstance(world);
128 var template = items.get(0);
129 var sacrifice = items.stream()
130 .skip(1) // skip the template
131 .filter(stack -> !ItemStack.isSameItemSameTags(template, stack))
132 .flatMap(stack -> emc.get(stack)
133 .stream()
134 .mapToObj(emcValue -> new StackEmcPair(stack, emcValue)))
135 .findFirst();
136 sacrifice.ifPresent(pair -> {
137 pair.stack.setCount(pair.stack.getCount() - 1);
138 setStoredEmc(getStoredEmc() + pair.emc());
139 });
140 }
141
142 private record StackEmcPair(ItemStack stack, double emc) {}
143}