diff options
| author | 2024-01-10 17:41:07 +0100 | |
|---|---|---|
| committer | 2024-01-10 17:41:07 +0100 | |
| commit | 000b84e87eaedb94fb87ccb11e376c51f99a1d07 (patch) | |
| tree | dd9519e7dadf613a71e01b04cac7be9c121a9f18 /src/main/java/lv | |
| parent | Move out common chest logic to separate files also in client code (diff) | |
| download | mc-eris-alchemy-000b84e87eaedb94fb87ccb11e376c51f99a1d07.tar.gz mc-eris-alchemy-000b84e87eaedb94fb87ccb11e376c51f99a1d07.tar.xz mc-eris-alchemy-000b84e87eaedb94fb87ccb11e376c51f99a1d07.zip | |
Added Energy Condenser
Diffstat (limited to 'src/main/java/lv')
21 files changed, 683 insertions, 71 deletions
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/EMC.java b/src/main/java/lv/enes/mc/eris_alchemy/EMC.java index e34d28f..3ff33ca 100644 --- a/src/main/java/lv/enes/mc/eris_alchemy/EMC.java +++ b/src/main/java/lv/enes/mc/eris_alchemy/EMC.java | |||
| @@ -16,6 +16,7 @@ import net.minecraft.world.level.Level; | |||
| 16 | import net.minecraft.world.level.block.Block; | 16 | import net.minecraft.world.level.block.Block; |
| 17 | import vazkii.patchouli.common.item.PatchouliItems; | 17 | import vazkii.patchouli.common.item.PatchouliItems; |
| 18 | 18 | ||
| 19 | import java.text.DecimalFormat; | ||
| 19 | import java.util.*; | 20 | import java.util.*; |
| 20 | import java.util.stream.Stream; | 21 | import java.util.stream.Stream; |
| 21 | 22 | ||
| @@ -62,6 +63,11 @@ public class EMC { | |||
| 62 | private static final EMC defaultInstance = new EMC(null); | 63 | private static final EMC defaultInstance = new EMC(null); |
| 63 | private static final Map<Level, EMC> instances = Collections.synchronizedMap(new WeakHashMap<>()); | 64 | private static final Map<Level, EMC> instances = Collections.synchronizedMap(new WeakHashMap<>()); |
| 64 | 65 | ||
| 66 | private static final DecimalFormat formatter = new DecimalFormat("0"); | ||
| 67 | static { | ||
| 68 | formatter.setMaximumFractionDigits(1); | ||
| 69 | } | ||
| 70 | |||
| 65 | public static EMC getInstance(Level world) { | 71 | public static EMC getInstance(Level world) { |
| 66 | if (world == null) { | 72 | if (world == null) { |
| 67 | return defaultInstance; | 73 | return defaultInstance; |
| @@ -76,6 +82,10 @@ public class EMC { | |||
| 76 | return instance; | 82 | return instance; |
| 77 | } | 83 | } |
| 78 | 84 | ||
| 85 | public static String formatEmc(double value) { | ||
| 86 | return formatter.format(value); | ||
| 87 | } | ||
| 88 | |||
| 79 | private final Map<Item, Double> data; | 89 | private final Map<Item, Double> data; |
| 80 | 90 | ||
| 81 | private EMC(@Nullable Level world) { | 91 | private EMC(@Nullable Level world) { |
| @@ -91,10 +101,9 @@ public class EMC { | |||
| 91 | .forEach(holder -> data.putIfAbsent(holder.value().asItem(), emcValue)) | 101 | .forEach(holder -> data.putIfAbsent(holder.value().asItem(), emcValue)) |
| 92 | ); | 102 | ); |
| 93 | 103 | ||
| 94 | ErisAlchemy.LOGGER.info("Getting recipes..."); | 104 | ErisAlchemy.LOGGER.info("Calculating EMC values..."); |
| 95 | var recipes = getRecipes(world); | 105 | var recipes = getRecipes(world); |
| 96 | var configured = new HashSet<>(data.keySet()); | 106 | var configured = new HashSet<>(data.keySet()); |
| 97 | ErisAlchemy.LOGGER.info("Calculating EMC values..."); | ||
| 98 | BuiltInRegistries.ITEM.forEach(item -> { | 107 | BuiltInRegistries.ITEM.forEach(item -> { |
| 99 | configEmc(recipes, configured, item); | 108 | configEmc(recipes, configured, item); |
| 100 | if (world != null && !data.containsKey(item)) { | 109 | if (world != null && !data.containsKey(item)) { |
| @@ -103,11 +112,30 @@ public class EMC { | |||
| 103 | }); | 112 | }); |
| 104 | } | 113 | } |
| 105 | 114 | ||
| 106 | public OptionalDouble get(Item item) { | 115 | public OptionalDouble get(ItemStack stack) { |
| 116 | if (stack.isEmpty()) { | ||
| 117 | return OptionalDouble.empty(); | ||
| 118 | } | ||
| 119 | |||
| 120 | var item = stack.getItem(); | ||
| 107 | var value = data.get(item); | 121 | var value = data.get(item); |
| 108 | if (value == null || value <= 0) { | 122 | if (value == null || value <= 0) { |
| 109 | return OptionalDouble.empty(); | 123 | return OptionalDouble.empty(); |
| 110 | } | 124 | } |
| 125 | |||
| 126 | EmcStorage storage = null; | ||
| 127 | if (item instanceof EmcStorage emcStorage) { | ||
| 128 | storage = emcStorage; | ||
| 129 | } else if (item instanceof BlockItem blockItem) { | ||
| 130 | if (blockItem.getBlock() instanceof EmcStorage emcStorage) { | ||
| 131 | storage = emcStorage; | ||
| 132 | } | ||
| 133 | } | ||
| 134 | |||
| 135 | if (storage != null) { | ||
| 136 | value += storage.getStoredEmc(stack); | ||
| 137 | } | ||
| 138 | |||
| 111 | return OptionalDouble.of(value); | 139 | return OptionalDouble.of(value); |
| 112 | } | 140 | } |
| 113 | 141 | ||
| @@ -134,7 +162,7 @@ public class EMC { | |||
| 134 | } | 162 | } |
| 135 | 163 | ||
| 136 | private OptionalDouble configEmc(List<SimplifiedRecipe> recipes, Set<Item> configured, Item item) { | 164 | private OptionalDouble configEmc(List<SimplifiedRecipe> recipes, Set<Item> configured, Item item) { |
| 137 | var res = get(item); | 165 | var res = get(item.getDefaultInstance()); |
| 138 | if (res.isPresent() || configured.contains(item)) { | 166 | if (res.isPresent() || configured.contains(item)) { |
| 139 | return res; | 167 | return res; |
| 140 | } | 168 | } |
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/EmcStorage.java b/src/main/java/lv/enes/mc/eris_alchemy/EmcStorage.java new file mode 100644 index 0000000..427a887 --- /dev/null +++ b/src/main/java/lv/enes/mc/eris_alchemy/EmcStorage.java | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy; | ||
| 2 | |||
| 3 | import net.minecraft.nbt.CompoundTag; | ||
| 4 | import net.minecraft.world.item.BlockItem; | ||
| 5 | import net.minecraft.world.item.ItemStack; | ||
| 6 | |||
| 7 | public interface EmcStorage { | ||
| 8 | double getStoredEmc(ItemStack stack, CompoundTag blockEntityData); | ||
| 9 | |||
| 10 | default double getStoredEmc(ItemStack stack) { | ||
| 11 | var blockEntityData = BlockItem.getBlockEntityData(stack); | ||
| 12 | if (blockEntityData == null) { | ||
| 13 | return 0; | ||
| 14 | } | ||
| 15 | return getStoredEmc(stack, blockEntityData); | ||
| 16 | } | ||
| 17 | } | ||
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/ErisAlchemyRegistry.java b/src/main/java/lv/enes/mc/eris_alchemy/ErisAlchemyRegistry.java index c02a1e6..592eb5e 100644 --- a/src/main/java/lv/enes/mc/eris_alchemy/ErisAlchemyRegistry.java +++ b/src/main/java/lv/enes/mc/eris_alchemy/ErisAlchemyRegistry.java | |||
| @@ -1,9 +1,13 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy; | 1 | package lv.enes.mc.eris_alchemy; |
| 2 | 2 | ||
| 3 | import lv.enes.mc.eris_alchemy.block.AlchemicalChestBlock; | 3 | import lv.enes.mc.eris_alchemy.block.AlchemicalChestBlock; |
| 4 | import lv.enes.mc.eris_alchemy.block.entity.AlchemicalChestBlockEntity; | 4 | import lv.enes.mc.eris_alchemy.block.EnergyCondenserBlock; |
| 5 | import lv.enes.mc.eris_alchemy.block.entity.AlchemicalChestEntity; | ||
| 6 | import lv.enes.mc.eris_alchemy.block.entity.EnergyCondenserEntity; | ||
| 5 | import lv.enes.mc.eris_alchemy.menu.AlchemicalChestMenu; | 7 | import lv.enes.mc.eris_alchemy.menu.AlchemicalChestMenu; |
| 8 | import lv.enes.mc.eris_alchemy.menu.EnergyCondenserMenu; | ||
| 6 | import lv.enes.mc.eris_alchemy.recipe.CovalenceRepair; | 9 | import lv.enes.mc.eris_alchemy.recipe.CovalenceRepair; |
| 10 | import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerType; | ||
| 7 | import net.minecraft.core.registries.BuiltInRegistries; | 11 | import net.minecraft.core.registries.BuiltInRegistries; |
| 8 | import net.minecraft.resources.ResourceLocation; | 12 | import net.minecraft.resources.ResourceLocation; |
| 9 | import net.minecraft.world.flag.FeatureFlags; | 13 | import net.minecraft.world.flag.FeatureFlags; |
| @@ -35,9 +39,15 @@ public final class ErisAlchemyRegistry { | |||
| 35 | 39 | ||
| 36 | private static final Map<ResourceLocation, BlockEntityType<?>> data = new LinkedHashMap<>(); | 40 | private static final Map<ResourceLocation, BlockEntityType<?>> data = new LinkedHashMap<>(); |
| 37 | 41 | ||
| 38 | public static final BlockEntityType<AlchemicalChestBlockEntity> ALCHEMICAL_CHEST = register( | 42 | public static final BlockEntityType<AlchemicalChestEntity> ALCHEMICAL_CHEST = register( |
| 39 | "alchemical_chest", | 43 | "alchemical_chest", |
| 40 | QuiltBlockEntityTypeBuilder.create(AlchemicalChestBlockEntity::new, Blocks.ALCHEMICAL_CHEST) | 44 | QuiltBlockEntityTypeBuilder.create(AlchemicalChestEntity::new, Blocks.ALCHEMICAL_CHEST) |
| 45 | .build() | ||
| 46 | ); | ||
| 47 | |||
| 48 | public static final BlockEntityType<EnergyCondenserEntity> ENERGY_CONDENSER = register( | ||
| 49 | "energy_condenser", | ||
| 50 | QuiltBlockEntityTypeBuilder.create(EnergyCondenserEntity::new, Blocks.ENERGY_CONDENSER) | ||
| 41 | .build() | 51 | .build() |
| 42 | ); | 52 | ); |
| 43 | 53 | ||
| @@ -61,6 +71,11 @@ public final class ErisAlchemyRegistry { | |||
| 61 | new AlchemicalChestBlock(QuiltBlockSettings.copy(ENDER_CHEST)) | 71 | new AlchemicalChestBlock(QuiltBlockSettings.copy(ENDER_CHEST)) |
| 62 | ); | 72 | ); |
| 63 | 73 | ||
| 74 | public static final EnergyCondenserBlock ENERGY_CONDENSER = register( | ||
| 75 | "energy_condenser", | ||
| 76 | new EnergyCondenserBlock(QuiltBlockSettings.copy(ENDER_CHEST)) | ||
| 77 | ); | ||
| 78 | |||
| 64 | public static void consume(BiConsumer<? super ResourceLocation, ? super Block> consumer) { | 79 | public static void consume(BiConsumer<? super ResourceLocation, ? super Block> consumer) { |
| 65 | data.forEach(consumer); | 80 | data.forEach(consumer); |
| 66 | } | 81 | } |
| @@ -78,6 +93,9 @@ public final class ErisAlchemyRegistry { | |||
| 78 | 93 | ||
| 79 | public static final Item ALCHEMICAL_CHEST = | 94 | public static final Item ALCHEMICAL_CHEST = |
| 80 | register(Blocks.ALCHEMICAL_CHEST, new QuiltItemSettings().rarity(Rarity.RARE)); | 95 | register(Blocks.ALCHEMICAL_CHEST, new QuiltItemSettings().rarity(Rarity.RARE)); |
| 96 | @SuppressWarnings("unused") | ||
| 97 | public static final Item ENERGY_CONDENSER = | ||
| 98 | register(Blocks.ENERGY_CONDENSER, new QuiltItemSettings().rarity(Rarity.EPIC)); | ||
| 81 | public static final Item LOW_COVALENCE_DUST = | 99 | public static final Item LOW_COVALENCE_DUST = |
| 82 | register("low_covalence_dust", new Item(new QuiltItemSettings().rarity(Rarity.COMMON))); | 100 | register("low_covalence_dust", new Item(new QuiltItemSettings().rarity(Rarity.COMMON))); |
| 83 | @SuppressWarnings("unused") | 101 | @SuppressWarnings("unused") |
| @@ -112,6 +130,8 @@ public final class ErisAlchemyRegistry { | |||
| 112 | 130 | ||
| 113 | public static final MenuType<AlchemicalChestMenu> ALCHEMICAL_CHEST = | 131 | public static final MenuType<AlchemicalChestMenu> ALCHEMICAL_CHEST = |
| 114 | register("alchemy_chest", AlchemicalChestMenu::new); | 132 | register("alchemy_chest", AlchemicalChestMenu::new); |
| 133 | public static final ExtendedScreenHandlerType<EnergyCondenserMenu> ENERGY_CONDENSER = | ||
| 134 | registerExt("energy_condenser", EnergyCondenserMenu::new); | ||
| 115 | 135 | ||
| 116 | public static void consume(BiConsumer<? super ResourceLocation, ? super MenuType<?>> consumer) { | 136 | public static void consume(BiConsumer<? super ResourceLocation, ? super MenuType<?>> consumer) { |
| 117 | data.forEach(consumer); | 137 | data.forEach(consumer); |
| @@ -121,12 +141,32 @@ public final class ErisAlchemyRegistry { | |||
| 121 | String id, | 141 | String id, |
| 122 | MenuType.MenuSupplier<T> supplier | 142 | MenuType.MenuSupplier<T> supplier |
| 123 | ) { | 143 | ) { |
| 124 | var menuType = new MenuType<>(supplier, FeatureFlags.VANILLA_SET); | 144 | return registerCommon(id, new MenuType<>(supplier, FeatureFlags.VANILLA_SET)); |
| 145 | } | ||
| 146 | |||
| 147 | private static <T extends AbstractContainerMenu> ExtendedScreenHandlerType<T> registerExt( | ||
| 148 | String id, | ||
| 149 | ExtendedScreenHandlerType.ExtendedFactory<T> supplier | ||
| 150 | ) { | ||
| 151 | return registerCommon(id, new ExtendedScreenHandlerType<>(supplier)); | ||
| 152 | } | ||
| 153 | |||
| 154 | private static <M extends AbstractContainerMenu, T extends MenuType<? extends M>> T registerCommon( | ||
| 155 | String id, | ||
| 156 | T menuType | ||
| 157 | ) { | ||
| 125 | data.put(new ResourceLocation(ErisAlchemy.ID, id), menuType); | 158 | data.put(new ResourceLocation(ErisAlchemy.ID, id), menuType); |
| 126 | return menuType; | 159 | return menuType; |
| 127 | } | 160 | } |
| 128 | } | 161 | } |
| 129 | 162 | ||
| 163 | public static final class NetworkingConstants { | ||
| 164 | private NetworkingConstants() {} | ||
| 165 | |||
| 166 | public static final ResourceLocation UPDATE_SYNCED_VALUE | ||
| 167 | = new ResourceLocation(ErisAlchemy.ID, "update_synced_value"); | ||
| 168 | } | ||
| 169 | |||
| 130 | public static final class RecipeSerializers { | 170 | public static final class RecipeSerializers { |
| 131 | private RecipeSerializers() {} | 171 | private RecipeSerializers() {} |
| 132 | 172 | ||
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; | |||
| 3 | import jakarta.annotation.Nonnull; | 3 | import jakarta.annotation.Nonnull; |
| 4 | import jakarta.annotation.Nullable; | 4 | import jakarta.annotation.Nullable; |
| 5 | import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry; | 5 | import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry; |
| 6 | import lv.enes.mc.eris_alchemy.block.entity.AlchemicalChestBlockEntity; | 6 | import lv.enes.mc.eris_alchemy.block.entity.AlchemicalChestEntity; |
| 7 | import net.minecraft.core.BlockPos; | 7 | import net.minecraft.core.BlockPos; |
| 8 | import net.minecraft.network.chat.Component; | 8 | import net.minecraft.network.chat.Component; |
| 9 | import net.minecraft.world.level.block.entity.BlockEntity; | 9 | import net.minecraft.world.level.block.entity.BlockEntity; |
| 10 | import net.minecraft.world.level.block.state.BlockState; | 10 | import net.minecraft.world.level.block.state.BlockState; |
| 11 | 11 | ||
| 12 | public class AlchemicalChestBlock extends ChestLikeBlock<AlchemicalChestBlockEntity> | 12 | public 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 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy.block; | 1 | package lv.enes.mc.eris_alchemy.block; |
| 2 | 2 | ||
| 3 | import jakarta.annotation.Nonnull; | 3 | import jakarta.annotation.Nonnull; |
| 4 | import lv.enes.mc.eris_alchemy.block.entity.ChestLikeBlockEntity; | 4 | import lv.enes.mc.eris_alchemy.block.entity.ChestLikeEntity; |
| 5 | import net.minecraft.core.BlockPos; | 5 | import net.minecraft.core.BlockPos; |
| 6 | import net.minecraft.core.Direction; | 6 | import net.minecraft.core.Direction; |
| 7 | import net.minecraft.network.chat.Component; | 7 | import net.minecraft.network.chat.Component; |
| @@ -33,7 +33,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; | |||
| 33 | 33 | ||
| 34 | import java.util.function.Supplier; | 34 | import java.util.function.Supplier; |
| 35 | 35 | ||
| 36 | public abstract class ChestLikeBlock<E extends ChestLikeBlockEntity> | 36 | public 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 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy.block; | ||
| 2 | |||
| 3 | import jakarta.annotation.Nonnull; | ||
| 4 | import jakarta.annotation.Nullable; | ||
| 5 | import lv.enes.mc.eris_alchemy.EMC; | ||
| 6 | import lv.enes.mc.eris_alchemy.EmcStorage; | ||
| 7 | import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry; | ||
| 8 | import lv.enes.mc.eris_alchemy.block.entity.EnergyCondenserEntity; | ||
| 9 | import net.minecraft.core.BlockPos; | ||
| 10 | import net.minecraft.nbt.CompoundTag; | ||
| 11 | import net.minecraft.network.chat.Component; | ||
| 12 | import net.minecraft.world.item.ItemStack; | ||
| 13 | import net.minecraft.world.item.TooltipFlag; | ||
| 14 | import net.minecraft.world.level.BlockGetter; | ||
| 15 | import net.minecraft.world.level.block.entity.BlockEntity; | ||
| 16 | import net.minecraft.world.level.block.state.BlockState; | ||
| 17 | |||
| 18 | import java.util.List; | ||
| 19 | |||
| 20 | public 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; | |||
| 3 | import jakarta.annotation.Nonnull; | 3 | import jakarta.annotation.Nonnull; |
| 4 | import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry; | 4 | import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry; |
| 5 | import lv.enes.mc.eris_alchemy.menu.AlchemicalChestMenu; | 5 | import lv.enes.mc.eris_alchemy.menu.AlchemicalChestMenu; |
| 6 | import lv.enes.mc.eris_alchemy.menu.ChestLikeBlockMenu; | 6 | import lv.enes.mc.eris_alchemy.menu.ChestLikeMenu; |
| 7 | import net.minecraft.core.BlockPos; | 7 | import net.minecraft.core.BlockPos; |
| 8 | import net.minecraft.core.NonNullList; | 8 | import net.minecraft.core.NonNullList; |
| 9 | import net.minecraft.network.chat.Component; | ||
| 10 | import net.minecraft.world.entity.player.Inventory; | 9 | import net.minecraft.world.entity.player.Inventory; |
| 11 | import net.minecraft.world.item.ItemStack; | 10 | import net.minecraft.world.item.ItemStack; |
| 12 | import net.minecraft.world.level.block.Block; | 11 | import net.minecraft.world.level.block.Block; |
| 13 | import net.minecraft.world.level.block.state.BlockState; | 12 | import net.minecraft.world.level.block.state.BlockState; |
| 14 | 13 | ||
| 15 | public class AlchemicalChestBlockEntity extends ChestLikeBlockEntity { | 14 | public 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 | ||
| 3 | import jakarta.annotation.Nonnull; | 3 | import jakarta.annotation.Nonnull; |
| 4 | import jakarta.annotation.Nullable; | 4 | import jakarta.annotation.Nullable; |
| 5 | import lv.enes.mc.eris_alchemy.menu.ChestLikeBlockMenu; | 5 | import lv.enes.mc.eris_alchemy.menu.ChestLikeMenu; |
| 6 | import net.minecraft.core.BlockPos; | 6 | import net.minecraft.core.BlockPos; |
| 7 | import net.minecraft.core.NonNullList; | 7 | import net.minecraft.core.NonNullList; |
| 8 | import net.minecraft.nbt.CompoundTag; | 8 | import net.minecraft.nbt.CompoundTag; |
| 9 | import net.minecraft.network.chat.Component; | ||
| 9 | import net.minecraft.sounds.SoundEvents; | 10 | import net.minecraft.sounds.SoundEvents; |
| 10 | import net.minecraft.sounds.SoundSource; | 11 | import net.minecraft.sounds.SoundSource; |
| 11 | import net.minecraft.world.Container; | 12 | import net.minecraft.world.Container; |
| @@ -17,19 +18,19 @@ import net.minecraft.world.level.block.Block; | |||
| 17 | import net.minecraft.world.level.block.entity.*; | 18 | import net.minecraft.world.level.block.entity.*; |
| 18 | import net.minecraft.world.level.block.state.BlockState; | 19 | import net.minecraft.world.level.block.state.BlockState; |
| 19 | 20 | ||
| 20 | public abstract class ChestLikeBlockEntity extends BaseContainerBlockEntity implements LidBlockEntity { | 21 | public 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 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy.block.entity; | ||
| 2 | |||
| 3 | import jakarta.annotation.Nonnull; | ||
| 4 | import lv.enes.mc.eris_alchemy.EMC; | ||
| 5 | import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry; | ||
| 6 | import lv.enes.mc.eris_alchemy.menu.ChestLikeMenu; | ||
| 7 | import lv.enes.mc.eris_alchemy.menu.EnergyCondenserMenu; | ||
| 8 | import lv.enes.mc.eris_alchemy.utils.ContainerOpenersCounterUtil; | ||
| 9 | import lv.enes.mc.eris_alchemy.utils.SyncedValue.SyncedDouble; | ||
| 10 | import net.fabricmc.fabric.api.screenhandler.v1.ExtendedScreenHandlerFactory; | ||
| 11 | import net.minecraft.core.BlockPos; | ||
| 12 | import net.minecraft.core.NonNullList; | ||
| 13 | import net.minecraft.nbt.CompoundTag; | ||
| 14 | import net.minecraft.network.FriendlyByteBuf; | ||
| 15 | import net.minecraft.server.level.ServerPlayer; | ||
| 16 | import net.minecraft.world.entity.player.Inventory; | ||
| 17 | import net.minecraft.world.item.ItemStack; | ||
| 18 | import net.minecraft.world.level.Level; | ||
| 19 | import net.minecraft.world.level.block.Block; | ||
| 20 | import net.minecraft.world.level.block.state.BlockState; | ||
| 21 | |||
| 22 | import java.util.stream.IntStream; | ||
| 23 | |||
| 24 | public 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 | } | ||
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/client/ChestLikeScreen.java b/src/main/java/lv/enes/mc/eris_alchemy/client/ChestLikeScreen.java index c98b356..b8967b1 100644 --- a/src/main/java/lv/enes/mc/eris_alchemy/client/ChestLikeScreen.java +++ b/src/main/java/lv/enes/mc/eris_alchemy/client/ChestLikeScreen.java | |||
| @@ -1,13 +1,13 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy.client; | 1 | package lv.enes.mc.eris_alchemy.client; |
| 2 | 2 | ||
| 3 | import lv.enes.mc.eris_alchemy.menu.ChestLikeBlockMenu; | 3 | import lv.enes.mc.eris_alchemy.menu.ChestLikeMenu; |
| 4 | import net.minecraft.client.gui.GuiGraphics; | 4 | import net.minecraft.client.gui.GuiGraphics; |
| 5 | import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; | 5 | import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; |
| 6 | import net.minecraft.network.chat.Component; | 6 | import net.minecraft.network.chat.Component; |
| 7 | import net.minecraft.resources.ResourceLocation; | 7 | import net.minecraft.resources.ResourceLocation; |
| 8 | import net.minecraft.world.entity.player.Inventory; | 8 | import net.minecraft.world.entity.player.Inventory; |
| 9 | 9 | ||
| 10 | public abstract class ChestLikeScreen<M extends ChestLikeBlockMenu> extends AbstractContainerScreen<M> { | 10 | public abstract class ChestLikeScreen<M extends ChestLikeMenu> extends AbstractContainerScreen<M> { |
| 11 | public ChestLikeScreen(M menu, Inventory inventory, Component title) { | 11 | public ChestLikeScreen(M menu, Inventory inventory, Component title) { |
| 12 | super(menu, inventory, title); | 12 | super(menu, inventory, title); |
| 13 | 13 | ||
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/client/EnergyCondenserScreen.java b/src/main/java/lv/enes/mc/eris_alchemy/client/EnergyCondenserScreen.java new file mode 100644 index 0000000..b6762c8 --- /dev/null +++ b/src/main/java/lv/enes/mc/eris_alchemy/client/EnergyCondenserScreen.java | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy.client; | ||
| 2 | |||
| 3 | import lv.enes.mc.eris_alchemy.EMC; | ||
| 4 | import lv.enes.mc.eris_alchemy.ErisAlchemy; | ||
| 5 | import lv.enes.mc.eris_alchemy.menu.EnergyCondenserMenu; | ||
| 6 | import net.minecraft.client.gui.GuiGraphics; | ||
| 7 | import net.minecraft.network.chat.Component; | ||
| 8 | import net.minecraft.resources.ResourceLocation; | ||
| 9 | import net.minecraft.world.entity.player.Inventory; | ||
| 10 | |||
| 11 | public class EnergyCondenserScreen extends ChestLikeScreen<EnergyCondenserMenu> { | ||
| 12 | public static final ResourceLocation TEXTURE = | ||
| 13 | new ResourceLocation(ErisAlchemy.ID, "textures/gui/container/energy_condenser.png"); | ||
| 14 | |||
| 15 | public static final int TEXTURE_WIDTH = 248; | ||
| 16 | public static final int TEXTURE_HEIGHT = 237; | ||
| 17 | |||
| 18 | public EnergyCondenserScreen(EnergyCondenserMenu menu, Inventory inventory, Component title) { | ||
| 19 | super(menu, inventory, title); | ||
| 20 | } | ||
| 21 | |||
| 22 | @Override | ||
| 23 | protected ResourceLocation getTexture() { | ||
| 24 | return TEXTURE; | ||
| 25 | } | ||
| 26 | |||
| 27 | @Override | ||
| 28 | protected int getTextureWidth() { | ||
| 29 | return TEXTURE_WIDTH; | ||
| 30 | } | ||
| 31 | |||
| 32 | @Override | ||
| 33 | protected int getTextureHeight() { | ||
| 34 | return TEXTURE_HEIGHT; | ||
| 35 | } | ||
| 36 | |||
| 37 | @Override | ||
| 38 | protected void renderLabels(GuiGraphics graphics, int mouseX, int mouseY) { | ||
| 39 | graphics.drawString(font, EMC.formatEmc(menu.getStoredEmc()), 28, 6, 0xFFFFFF); | ||
| 40 | } | ||
| 41 | |||
| 42 | @Override | ||
| 43 | protected boolean shouldRenderLabels() { | ||
| 44 | return false; | ||
| 45 | } | ||
| 46 | } | ||
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/client/ErisAlchemyClient.java b/src/main/java/lv/enes/mc/eris_alchemy/client/ErisAlchemyClient.java index 86cc467..a69d2e1 100644 --- a/src/main/java/lv/enes/mc/eris_alchemy/client/ErisAlchemyClient.java +++ b/src/main/java/lv/enes/mc/eris_alchemy/client/ErisAlchemyClient.java | |||
| @@ -9,8 +9,6 @@ import org.quiltmc.loader.api.ModContainer; | |||
| 9 | import org.quiltmc.qsl.base.api.entrypoint.client.ClientModInitializer; | 9 | import org.quiltmc.qsl.base.api.entrypoint.client.ClientModInitializer; |
| 10 | import org.quiltmc.qsl.tooltip.api.client.ItemTooltipCallback; | 10 | import org.quiltmc.qsl.tooltip.api.client.ItemTooltipCallback; |
| 11 | 11 | ||
| 12 | import java.text.DecimalFormat; | ||
| 13 | |||
| 14 | @SuppressWarnings("unused") | 12 | @SuppressWarnings("unused") |
| 15 | public class ErisAlchemyClient implements ClientModInitializer { | 13 | public class ErisAlchemyClient implements ClientModInitializer { |
| 16 | @Override | 14 | @Override |
| @@ -19,14 +17,10 @@ public class ErisAlchemyClient implements ClientModInitializer { | |||
| 19 | ErisAlchemyClientRegistry.ItemRenderers.consume(BuiltinItemRendererRegistry.INSTANCE::register); | 17 | ErisAlchemyClientRegistry.ItemRenderers.consume(BuiltinItemRendererRegistry.INSTANCE::register); |
| 20 | ErisAlchemyClientRegistry.MenuScreens.consume(MenuScreens::register); | 18 | ErisAlchemyClientRegistry.MenuScreens.consume(MenuScreens::register); |
| 21 | 19 | ||
| 22 | // MenuScreens.register(ErisAlchemyRegistry.Menus.ALCHEMICAL_CHEST, AlchemicalChestScreen::new); | ||
| 23 | |||
| 24 | var doubleFormat = new DecimalFormat("0"); | ||
| 25 | doubleFormat.setMaximumFractionDigits(1); | ||
| 26 | ItemTooltipCallback.EVENT.register((stack, player, context, tooltip) -> { | 20 | ItemTooltipCallback.EVENT.register((stack, player, context, tooltip) -> { |
| 27 | var world = player == null ? null : player.level(); | 21 | var world = player == null ? null : player.level(); |
| 28 | var emc = EMC.getInstance(world).get(stack.getItem()); | 22 | var emc = EMC.getInstance(world).get(stack); |
| 29 | emc.ifPresent(value -> tooltip.add(Component.literal("EMC %s".formatted(doubleFormat.format(value))))); | 23 | emc.ifPresent(value -> tooltip.add(Component.literal("EMC %s".formatted(EMC.formatEmc(value))))); |
| 30 | }); | 24 | }); |
| 31 | } | 25 | } |
| 32 | } | 26 | } |
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/client/ErisAlchemyClientRegistry.java b/src/main/java/lv/enes/mc/eris_alchemy/client/ErisAlchemyClientRegistry.java index 3680fd5..30c6690 100644 --- a/src/main/java/lv/enes/mc/eris_alchemy/client/ErisAlchemyClientRegistry.java +++ b/src/main/java/lv/enes/mc/eris_alchemy/client/ErisAlchemyClientRegistry.java | |||
| @@ -1,6 +1,7 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy.client; | 1 | package lv.enes.mc.eris_alchemy.client; |
| 2 | 2 | ||
| 3 | import lv.enes.mc.eris_alchemy.block.entity.AlchemicalChestBlockEntity; | 3 | import lv.enes.mc.eris_alchemy.block.entity.AlchemicalChestEntity; |
| 4 | import lv.enes.mc.eris_alchemy.block.entity.EnergyCondenserEntity; | ||
| 4 | import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry.DynamicItemRenderer; | 5 | import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry.DynamicItemRenderer; |
| 5 | import net.minecraft.client.gui.screens.MenuScreens.ScreenConstructor; | 6 | import net.minecraft.client.gui.screens.MenuScreens.ScreenConstructor; |
| 6 | import net.minecraft.client.gui.screens.Screen; | 7 | import net.minecraft.client.gui.screens.Screen; |
| @@ -54,6 +55,7 @@ public final class ErisAlchemyClientRegistry { | |||
| 54 | 55 | ||
| 55 | static { | 56 | static { |
| 56 | register(BlockEntities.ALCHEMICAL_CHEST, ChestRenderer::new); | 57 | register(BlockEntities.ALCHEMICAL_CHEST, ChestRenderer::new); |
| 58 | register(BlockEntities.ENERGY_CONDENSER, ChestRenderer::new); | ||
| 57 | } | 59 | } |
| 58 | } | 60 | } |
| 59 | 61 | ||
| @@ -73,7 +75,11 @@ public final class ErisAlchemyClientRegistry { | |||
| 73 | static { | 75 | static { |
| 74 | register( | 76 | register( |
| 75 | Items.ALCHEMICAL_CHEST, | 77 | Items.ALCHEMICAL_CHEST, |
| 76 | new ChestItemRenderer<>(Blocks.ALCHEMICAL_CHEST, AlchemicalChestBlockEntity::new)::renderByItem | 78 | new ChestItemRenderer<>(Blocks.ALCHEMICAL_CHEST, AlchemicalChestEntity::new)::renderByItem |
| 79 | ); | ||
| 80 | register( | ||
| 81 | Items.ENERGY_CONDENSER, | ||
| 82 | new ChestItemRenderer<>(Blocks.ENERGY_CONDENSER, EnergyCondenserEntity::new)::renderByItem | ||
| 77 | ); | 83 | ); |
| 78 | } | 84 | } |
| 79 | } | 85 | } |
| @@ -111,6 +117,7 @@ public final class ErisAlchemyClientRegistry { | |||
| 111 | 117 | ||
| 112 | static { | 118 | static { |
| 113 | register(Menus.ALCHEMICAL_CHEST, AlchemicalChestScreen::new); | 119 | register(Menus.ALCHEMICAL_CHEST, AlchemicalChestScreen::new); |
| 120 | register(Menus.ENERGY_CONDENSER, EnergyCondenserScreen::new); | ||
| 114 | } | 121 | } |
| 115 | } | 122 | } |
| 116 | } | 123 | } |
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/client/ErisAlchemyMaterials.java b/src/main/java/lv/enes/mc/eris_alchemy/client/ErisAlchemyMaterials.java index 15d9209..686d83f 100644 --- a/src/main/java/lv/enes/mc/eris_alchemy/client/ErisAlchemyMaterials.java +++ b/src/main/java/lv/enes/mc/eris_alchemy/client/ErisAlchemyMaterials.java | |||
| @@ -11,5 +11,10 @@ public final class ErisAlchemyMaterials { | |||
| 11 | new ResourceLocation(ErisAlchemy.ID, "entity/chest/alchemical_chest") | 11 | new ResourceLocation(ErisAlchemy.ID, "entity/chest/alchemical_chest") |
| 12 | ); | 12 | ); |
| 13 | 13 | ||
| 14 | public static final Material ENERGY_CONDENSER = new Material( | ||
| 15 | Sheets.CHEST_SHEET, | ||
| 16 | new ResourceLocation(ErisAlchemy.ID, "entity/chest/energy_condenser") | ||
| 17 | ); | ||
| 18 | |||
| 14 | private ErisAlchemyMaterials() {} | 19 | private ErisAlchemyMaterials() {} |
| 15 | } | 20 | } |
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/menu/AlchemicalChestMenu.java b/src/main/java/lv/enes/mc/eris_alchemy/menu/AlchemicalChestMenu.java index 1dc3364..35db476 100644 --- a/src/main/java/lv/enes/mc/eris_alchemy/menu/AlchemicalChestMenu.java +++ b/src/main/java/lv/enes/mc/eris_alchemy/menu/AlchemicalChestMenu.java | |||
| @@ -6,7 +6,7 @@ import net.minecraft.world.SimpleContainer; | |||
| 6 | import net.minecraft.world.entity.player.Inventory; | 6 | import net.minecraft.world.entity.player.Inventory; |
| 7 | import net.minecraft.world.inventory.Slot; | 7 | import net.minecraft.world.inventory.Slot; |
| 8 | 8 | ||
| 9 | public class AlchemicalChestMenu extends ChestLikeBlockMenu { | 9 | public class AlchemicalChestMenu extends ChestLikeMenu { |
| 10 | private static final int WIDTH = 13; | 10 | private static final int WIDTH = 13; |
| 11 | private static final int HEIGHT = 8; | 11 | private static final int HEIGHT = 8; |
| 12 | 12 | ||
| @@ -24,25 +24,13 @@ public class AlchemicalChestMenu extends ChestLikeBlockMenu { | |||
| 24 | var y_off = 8; | 24 | var y_off = 8; |
| 25 | 25 | ||
| 26 | for (var y = 0; y < HEIGHT; y++) { | 26 | for (var y = 0; y < HEIGHT; y++) { |
| 27 | for (var x = 0; x < WIDTH; x++ ) { | 27 | for (var x = 0; x < WIDTH; x++) { |
| 28 | addSlot(new Slot(container, y * WIDTH + x, x_off + x * 18, y_off + y * 18)); | 28 | addSlot(new Slot(container, y * WIDTH + x, x_off + x * 18, y_off + y * 18)); |
| 29 | } | 29 | } |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | x_off = 44; | 32 | addPlayerInventorySlots(playerInventory, 44, 155); |
| 33 | y_off = 155; | 33 | addPlayerHotbarSlots(playerInventory, 44, 213); |
| 34 | |||
| 35 | for (var y = 0; y < 3; y++) { | ||
| 36 | for (var x = 0; x < 9; x++) { | ||
| 37 | addSlot(new Slot(playerInventory, y * 9 + x + 9, x_off + x * 18, y_off + y * 18)); | ||
| 38 | } | ||
| 39 | } | ||
| 40 | |||
| 41 | y_off = 213; | ||
| 42 | |||
| 43 | for (var x = 0; x < 9; x++) { | ||
| 44 | addSlot(new Slot(playerInventory, x, x_off + x * 18, y_off)); | ||
| 45 | } | ||
| 46 | } | 34 | } |
| 47 | 35 | ||
| 48 | @Override | 36 | @Override |
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/menu/ChestLikeBlockMenu.java b/src/main/java/lv/enes/mc/eris_alchemy/menu/ChestLikeMenu.java index 897abe9..e561f0d 100644 --- a/src/main/java/lv/enes/mc/eris_alchemy/menu/ChestLikeBlockMenu.java +++ b/src/main/java/lv/enes/mc/eris_alchemy/menu/ChestLikeMenu.java | |||
| @@ -6,13 +6,14 @@ import net.minecraft.world.entity.player.Inventory; | |||
| 6 | import net.minecraft.world.entity.player.Player; | 6 | import net.minecraft.world.entity.player.Player; |
| 7 | import net.minecraft.world.inventory.AbstractContainerMenu; | 7 | import net.minecraft.world.inventory.AbstractContainerMenu; |
| 8 | import net.minecraft.world.inventory.MenuType; | 8 | import net.minecraft.world.inventory.MenuType; |
| 9 | import net.minecraft.world.inventory.Slot; | ||
| 9 | import net.minecraft.world.item.ItemStack; | 10 | import net.minecraft.world.item.ItemStack; |
| 10 | 11 | ||
| 11 | public abstract class ChestLikeBlockMenu extends AbstractContainerMenu { | 12 | public abstract class ChestLikeMenu extends AbstractContainerMenu { |
| 12 | protected final Container container; | 13 | protected final Container container; |
| 13 | 14 | ||
| 14 | public ChestLikeBlockMenu( | 15 | public ChestLikeMenu( |
| 15 | MenuType<? extends ChestLikeBlockMenu> type, | 16 | MenuType<? extends ChestLikeMenu> type, |
| 16 | int syncId, | 17 | int syncId, |
| 17 | Inventory playerInventory, | 18 | Inventory playerInventory, |
| 18 | Container container | 19 | Container container |
| @@ -27,10 +28,42 @@ public abstract class ChestLikeBlockMenu extends AbstractContainerMenu { | |||
| 27 | protected abstract void addSlots(Inventory playerInventory); | 28 | protected abstract void addSlots(Inventory playerInventory); |
| 28 | protected abstract int getRequiredSize(); | 29 | protected abstract int getRequiredSize(); |
| 29 | 30 | ||
| 31 | protected void addPlayerInventorySlots(Inventory playerInventory, int xOff, int yOff) { | ||
| 32 | for (var y = 0; y < 3; y++) { | ||
| 33 | for (var x = 0; x < 9; x++) { | ||
| 34 | addSlot(new Slot(playerInventory, y * 9 + x + 9, xOff + x * 18, yOff + y * 18)); | ||
| 35 | } | ||
| 36 | } | ||
| 37 | } | ||
| 38 | |||
| 39 | protected void addPlayerHotbarSlots(Inventory playerInventory, int xOff, int yOff) { | ||
| 40 | for (var x = 0; x < 9; x++) { | ||
| 41 | addSlot(new Slot(playerInventory, x, xOff + x * 18, yOff)); | ||
| 42 | } | ||
| 43 | } | ||
| 44 | |||
| 30 | public Container getContainer() { | 45 | public Container getContainer() { |
| 31 | return container; | 46 | return container; |
| 32 | } | 47 | } |
| 33 | 48 | ||
| 49 | protected int getQuickMoveStart() { | ||
| 50 | return 0; | ||
| 51 | } | ||
| 52 | |||
| 53 | protected int getQuickMoveEnd() { | ||
| 54 | return container.getContainerSize(); | ||
| 55 | } | ||
| 56 | |||
| 57 | @Override | ||
| 58 | public void broadcastChanges() { | ||
| 59 | super.broadcastChanges(); | ||
| 60 | } | ||
| 61 | |||
| 62 | @Override | ||
| 63 | public void broadcastFullState() { | ||
| 64 | super.broadcastFullState(); | ||
| 65 | } | ||
| 66 | |||
| 34 | @Nonnull | 67 | @Nonnull |
| 35 | @Override | 68 | @Override |
| 36 | public ItemStack quickMoveStack(Player player, int fromIndex) { | 69 | public ItemStack quickMoveStack(Player player, int fromIndex) { |
| @@ -44,10 +77,11 @@ public abstract class ChestLikeBlockMenu extends AbstractContainerMenu { | |||
| 44 | newStack = originalStack.copy(); | 77 | newStack = originalStack.copy(); |
| 45 | 78 | ||
| 46 | if (fromIndex < container.getContainerSize()) { | 79 | if (fromIndex < container.getContainerSize()) { |
| 80 | // In container, else player inv | ||
| 47 | if (!moveItemStackTo(originalStack, container.getContainerSize(), slots.size(), true)) { | 81 | if (!moveItemStackTo(originalStack, container.getContainerSize(), slots.size(), true)) { |
| 48 | return ItemStack.EMPTY; | 82 | return ItemStack.EMPTY; |
| 49 | } | 83 | } |
| 50 | } else if (!moveItemStackTo(originalStack, 0, container.getContainerSize(), false)) { | 84 | } else if (!moveItemStackTo(originalStack, getQuickMoveStart(), getQuickMoveEnd(), false)) { |
| 51 | return ItemStack.EMPTY; | 85 | return ItemStack.EMPTY; |
| 52 | } | 86 | } |
| 53 | 87 | ||
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/menu/EnergyCondenserMenu.java b/src/main/java/lv/enes/mc/eris_alchemy/menu/EnergyCondenserMenu.java new file mode 100644 index 0000000..bdba77b --- /dev/null +++ b/src/main/java/lv/enes/mc/eris_alchemy/menu/EnergyCondenserMenu.java | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy.menu; | ||
| 2 | |||
| 3 | import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry; | ||
| 4 | import lv.enes.mc.eris_alchemy.block.entity.EnergyCondenserEntity; | ||
| 5 | import lv.enes.mc.eris_alchemy.utils.SyncedValue.SyncedDouble; | ||
| 6 | import net.minecraft.network.FriendlyByteBuf; | ||
| 7 | import net.minecraft.world.Container; | ||
| 8 | import net.minecraft.world.SimpleContainer; | ||
| 9 | import net.minecraft.world.entity.player.Inventory; | ||
| 10 | import net.minecraft.world.inventory.Slot; | ||
| 11 | |||
| 12 | public class EnergyCondenserMenu extends ChestLikeMenu { | ||
| 13 | private static final int WIDTH = 13; | ||
| 14 | private static final int HEIGHT = 7; | ||
| 15 | |||
| 16 | private final SyncedDouble storedEmc; | ||
| 17 | |||
| 18 | public EnergyCondenserMenu(int syncId, Inventory playerInventory, FriendlyByteBuf buf) { | ||
| 19 | this(syncId, playerInventory, new SimpleContainer(WIDTH * HEIGHT + 1), SyncedDouble.deserialize(buf)); | ||
| 20 | } | ||
| 21 | |||
| 22 | public EnergyCondenserMenu(int syncId, Inventory playerInventory, EnergyCondenserEntity entity) { | ||
| 23 | this(syncId, playerInventory, entity, entity.getStoredEmcSyncer()); | ||
| 24 | } | ||
| 25 | |||
| 26 | public EnergyCondenserMenu(int syncId, Inventory playerInventory, Container container, SyncedDouble storedEmc) { | ||
| 27 | super(ErisAlchemyRegistry.Menus.ENERGY_CONDENSER, syncId, playerInventory, container); | ||
| 28 | this.storedEmc = storedEmc; | ||
| 29 | } | ||
| 30 | |||
| 31 | @Override | ||
| 32 | protected void addSlots(Inventory playerInventory) { | ||
| 33 | addSlot(new Slot(container, 0, 8, 7)); | ||
| 34 | |||
| 35 | var xOff = 8; | ||
| 36 | var yOff = 28; | ||
| 37 | for (var y = 0; y < HEIGHT; y++) { | ||
| 38 | for (var x = 0; x < WIDTH; x++) { | ||
| 39 | addSlot(new Slot(container, y * WIDTH + x + 1, xOff + x * 18, yOff + y * 18)); | ||
| 40 | } | ||
| 41 | } | ||
| 42 | |||
| 43 | addPlayerInventorySlots(playerInventory, 44, 157); | ||
| 44 | addPlayerHotbarSlots(playerInventory, 44, 213); | ||
| 45 | } | ||
| 46 | |||
| 47 | @Override | ||
| 48 | protected int getQuickMoveStart() { | ||
| 49 | return 1; | ||
| 50 | } | ||
| 51 | |||
| 52 | @Override | ||
| 53 | protected int getRequiredSize() { | ||
| 54 | return WIDTH * HEIGHT + 1; | ||
| 55 | } | ||
| 56 | |||
| 57 | public double getStoredEmc() { | ||
| 58 | return storedEmc.getValue(); | ||
| 59 | } | ||
| 60 | } | ||
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/mixin/ContainerOpenersCounterMixin.java b/src/main/java/lv/enes/mc/eris_alchemy/mixin/ContainerOpenersCounterMixin.java new file mode 100644 index 0000000..13b8669 --- /dev/null +++ b/src/main/java/lv/enes/mc/eris_alchemy/mixin/ContainerOpenersCounterMixin.java | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy.mixin; | ||
| 2 | |||
| 3 | import jakarta.annotation.Nonnull; | ||
| 4 | import lv.enes.mc.eris_alchemy.utils.ContainerOpenersCounterUtil; | ||
| 5 | import net.minecraft.core.BlockPos; | ||
| 6 | import net.minecraft.server.level.ServerPlayer; | ||
| 7 | import net.minecraft.world.entity.player.Player; | ||
| 8 | import net.minecraft.world.level.Level; | ||
| 9 | import net.minecraft.world.level.block.entity.ContainerOpenersCounter; | ||
| 10 | import net.minecraft.world.level.block.state.BlockState; | ||
| 11 | import net.minecraft.world.level.entity.EntityTypeTest; | ||
| 12 | import net.minecraft.world.phys.AABB; | ||
| 13 | import org.spongepowered.asm.mixin.Mixin; | ||
| 14 | import org.spongepowered.asm.mixin.Shadow; | ||
| 15 | import org.spongepowered.asm.mixin.Unique; | ||
| 16 | import org.spongepowered.asm.mixin.injection.At; | ||
| 17 | import org.spongepowered.asm.mixin.injection.Inject; | ||
| 18 | import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; | ||
| 19 | |||
| 20 | import java.util.List; | ||
| 21 | import java.util.Map; | ||
| 22 | import java.util.WeakHashMap; | ||
| 23 | |||
| 24 | @Mixin(ContainerOpenersCounter.class) | ||
| 25 | public abstract class ContainerOpenersCounterMixin | ||
| 26 | implements ContainerOpenersCounterUtil.ContainerOpenersCounterSuper { | ||
| 27 | @Shadow protected abstract boolean isOwnContainer(Player player); | ||
| 28 | |||
| 29 | @Unique | ||
| 30 | private final static Map<ContainerOpenersCounterMixin, List<ServerPlayer>> openers = new WeakHashMap<>(); | ||
| 31 | |||
| 32 | @Inject(method = "recheckOpeners", at = @At("RETURN")) | ||
| 33 | public void onRecheckOpeners(Level world, BlockPos pos, BlockState state, CallbackInfo ci) { | ||
| 34 | int x = pos.getX(); | ||
| 35 | int y = pos.getY(); | ||
| 36 | int z = pos.getZ(); | ||
| 37 | var boundingBox = new AABB( | ||
| 38 | x - 5.0, y - 5.0, z - 5.0, | ||
| 39 | x + 5.0, y + 5.0, z + 5.0 | ||
| 40 | ); | ||
| 41 | var players = world.getEntities(EntityTypeTest.forClass(ServerPlayer.class), boundingBox, this::isOwnContainer); | ||
| 42 | if (openers.containsKey(this)) { | ||
| 43 | var list = openers.get(this); | ||
| 44 | list.clear(); | ||
| 45 | list.addAll(players); | ||
| 46 | } else { | ||
| 47 | openers.put(this, players); | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | @Nonnull | ||
| 52 | @Override | ||
| 53 | public List<ServerPlayer> lv_enes_mc$getOpeners() { | ||
| 54 | return openers.getOrDefault(this, List.of()); | ||
| 55 | } | ||
| 56 | } | ||
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/mixin/client/SheetsMixin.java b/src/main/java/lv/enes/mc/eris_alchemy/mixin/client/SheetsMixin.java index 46f7720..145a68c 100644 --- a/src/main/java/lv/enes/mc/eris_alchemy/mixin/client/SheetsMixin.java +++ b/src/main/java/lv/enes/mc/eris_alchemy/mixin/client/SheetsMixin.java | |||
| @@ -1,7 +1,8 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy.mixin.client; | 1 | package lv.enes.mc.eris_alchemy.mixin.client; |
| 2 | 2 | ||
| 3 | import lv.enes.mc.eris_alchemy.block.entity.EnergyCondenserEntity; | ||
| 3 | import lv.enes.mc.eris_alchemy.client.ErisAlchemyMaterials; | 4 | import lv.enes.mc.eris_alchemy.client.ErisAlchemyMaterials; |
| 4 | import lv.enes.mc.eris_alchemy.block.entity.AlchemicalChestBlockEntity; | 5 | import lv.enes.mc.eris_alchemy.block.entity.AlchemicalChestEntity; |
| 5 | import net.minecraft.client.renderer.Sheets; | 6 | import net.minecraft.client.renderer.Sheets; |
| 6 | import net.minecraft.client.resources.model.Material; | 7 | import net.minecraft.client.resources.model.Material; |
| 7 | import net.minecraft.world.level.block.entity.BlockEntity; | 8 | import net.minecraft.world.level.block.entity.BlockEntity; |
| @@ -24,8 +25,10 @@ public abstract class SheetsMixin { | |||
| 24 | boolean christmas, | 25 | boolean christmas, |
| 25 | CallbackInfoReturnable<Material> cir | 26 | CallbackInfoReturnable<Material> cir |
| 26 | ) { | 27 | ) { |
| 27 | if (entity instanceof AlchemicalChestBlockEntity) { | 28 | if (entity instanceof AlchemicalChestEntity) { |
| 28 | cir.setReturnValue(ErisAlchemyMaterials.ALCHEMICAL_CHEST); | 29 | cir.setReturnValue(ErisAlchemyMaterials.ALCHEMICAL_CHEST); |
| 30 | } else if (entity instanceof EnergyCondenserEntity) { | ||
| 31 | cir.setReturnValue(ErisAlchemyMaterials.ENERGY_CONDENSER); | ||
| 29 | } | 32 | } |
| 30 | } | 33 | } |
| 31 | } | 34 | } |
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/utils/ContainerOpenersCounterUtil.java b/src/main/java/lv/enes/mc/eris_alchemy/utils/ContainerOpenersCounterUtil.java new file mode 100644 index 0000000..abedce7 --- /dev/null +++ b/src/main/java/lv/enes/mc/eris_alchemy/utils/ContainerOpenersCounterUtil.java | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy.utils; | ||
| 2 | |||
| 3 | import jakarta.annotation.Nonnull; | ||
| 4 | import net.minecraft.server.level.ServerPlayer; | ||
| 5 | import net.minecraft.world.level.block.entity.ContainerOpenersCounter; | ||
| 6 | |||
| 7 | import java.util.List; | ||
| 8 | |||
| 9 | public final class ContainerOpenersCounterUtil { | ||
| 10 | private ContainerOpenersCounterUtil() {} | ||
| 11 | |||
| 12 | /** @see lv.enes.mc.eris_alchemy.mixin.ContainerOpenersCounterMixin */ | ||
| 13 | public interface ContainerOpenersCounterSuper { | ||
| 14 | @Nonnull List<ServerPlayer> lv_enes_mc$getOpeners(); | ||
| 15 | } | ||
| 16 | |||
| 17 | public static List<ServerPlayer> getOpeners(ContainerOpenersCounter cop) { | ||
| 18 | return ((ContainerOpenersCounterSuper)cop).lv_enes_mc$getOpeners(); | ||
| 19 | } | ||
| 20 | } | ||
diff --git a/src/main/java/lv/enes/mc/eris_alchemy/utils/SyncedValue.java b/src/main/java/lv/enes/mc/eris_alchemy/utils/SyncedValue.java new file mode 100644 index 0000000..c7e52bf --- /dev/null +++ b/src/main/java/lv/enes/mc/eris_alchemy/utils/SyncedValue.java | |||
| @@ -0,0 +1,115 @@ | |||
| 1 | package lv.enes.mc.eris_alchemy.utils; | ||
| 2 | |||
| 3 | import jakarta.annotation.Nonnull; | ||
| 4 | import lv.enes.mc.eris_alchemy.ErisAlchemyRegistry; | ||
| 5 | import net.fabricmc.api.EnvType; | ||
| 6 | import net.minecraft.network.FriendlyByteBuf; | ||
| 7 | import net.minecraft.server.level.ServerPlayer; | ||
| 8 | import org.quiltmc.loader.api.minecraft.MinecraftQuiltLoader; | ||
| 9 | import org.quiltmc.qsl.networking.api.PacketByteBufs; | ||
| 10 | import org.quiltmc.qsl.networking.api.ServerPlayNetworking; | ||
| 11 | import org.quiltmc.qsl.networking.api.client.ClientPlayNetworking; | ||
| 12 | |||
| 13 | import java.lang.ref.WeakReference; | ||
| 14 | import java.util.Collection; | ||
| 15 | import java.util.HashMap; | ||
| 16 | import java.util.Map; | ||
| 17 | |||
| 18 | public sealed abstract class SyncedValue<E> { | ||
| 19 | private final static Map<Long, WeakReference<SyncedValue<?>>> values = new HashMap<>(); | ||
| 20 | |||
| 21 | private final long id; | ||
| 22 | private boolean changed = true; | ||
| 23 | private E value; | ||
| 24 | |||
| 25 | public SyncedValue(E value) { | ||
| 26 | this(genId(), value); | ||
| 27 | } | ||
| 28 | |||
| 29 | public SyncedValue(long id, E value) { | ||
| 30 | this.id = id; | ||
| 31 | this.value = value; | ||
| 32 | |||
| 33 | values.put(this.id, new WeakReference<>(this)); | ||
| 34 | } | ||
| 35 | |||
| 36 | protected abstract @Nonnull E read(FriendlyByteBuf buf); | ||
| 37 | protected abstract void write(FriendlyByteBuf buf, @Nonnull E value); | ||
| 38 | |||
| 39 | public void serialize(FriendlyByteBuf buf) { | ||
| 40 | buf.writeLongLE(id); | ||
| 41 | write(buf, value); | ||
| 42 | } | ||
| 43 | |||
| 44 | public E getValue() { | ||
| 45 | return value; | ||
| 46 | } | ||
| 47 | |||
| 48 | public void setValue(E value) { | ||
| 49 | this.value = value; | ||
| 50 | this.changed = true; | ||
| 51 | } | ||
| 52 | |||
| 53 | public void syncIfChanged(Collection<ServerPlayer> players) { | ||
| 54 | if (!changed) { | ||
| 55 | return; | ||
| 56 | } | ||
| 57 | var buf = PacketByteBufs.create(); | ||
| 58 | serialize(buf); | ||
| 59 | ServerPlayNetworking.send(players, ErisAlchemyRegistry.NetworkingConstants.UPDATE_SYNCED_VALUE, buf); | ||
| 60 | changed = false; | ||
| 61 | } | ||
| 62 | |||
| 63 | private void readData(FriendlyByteBuf buf) { | ||
| 64 | this.changed = false; | ||
| 65 | this.value = read(buf); | ||
| 66 | } | ||
| 67 | |||
| 68 | private static long nextId = 0; | ||
| 69 | private static long genId() { | ||
| 70 | return nextId++; | ||
| 71 | } | ||
| 72 | |||
| 73 | static { | ||
| 74 | if (MinecraftQuiltLoader.getEnvironmentType() == EnvType.CLIENT) { | ||
| 75 | ClientPlayNetworking.registerGlobalReceiver( | ||
| 76 | ErisAlchemyRegistry.NetworkingConstants.UPDATE_SYNCED_VALUE, | ||
| 77 | (client, handler, buf, responseSender) -> { | ||
| 78 | var id = buf.readLongLE(); | ||
| 79 | var ref = values.get(id); | ||
| 80 | var holder = ref == null ? null : ref.get(); | ||
| 81 | if (holder != null) { | ||
| 82 | holder.readData(buf); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | ); | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | public static final class SyncedDouble extends SyncedValue<Double> { | ||
| 90 | public SyncedDouble(double value) { | ||
| 91 | super(value); | ||
| 92 | } | ||
| 93 | |||
| 94 | public SyncedDouble(long id, double value) { | ||
| 95 | super(id, value); | ||
| 96 | } | ||
| 97 | |||
| 98 | public static SyncedDouble deserialize(FriendlyByteBuf buf) { | ||
| 99 | var id = buf.readLongLE(); | ||
| 100 | var value = buf.readDoubleLE(); | ||
| 101 | return new SyncedDouble(id, value); | ||
| 102 | } | ||
| 103 | |||
| 104 | @Nonnull | ||
| 105 | @Override | ||
| 106 | protected Double read(FriendlyByteBuf buf) { | ||
| 107 | return buf.readDoubleLE(); | ||
| 108 | } | ||
| 109 | |||
| 110 | @Override | ||
| 111 | protected void write(FriendlyByteBuf buf, @Nonnull Double value) { | ||
| 112 | buf.writeDoubleLE(value); | ||
| 113 | } | ||
| 114 | } | ||
| 115 | } | ||