diff --git a/src/main/java/dev/zontreck/libzontreck/blocks/RedstoneBlock.java b/src/main/java/dev/zontreck/libzontreck/blocks/RedstoneBlock.java index 6b498b6..dd4f548 100644 --- a/src/main/java/dev/zontreck/libzontreck/blocks/RedstoneBlock.java +++ b/src/main/java/dev/zontreck/libzontreck/blocks/RedstoneBlock.java @@ -2,6 +2,7 @@ package dev.zontreck.libzontreck.blocks; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.item.context.BlockPlaceContext; import net.minecraft.world.level.BlockGetter; import net.minecraft.world.level.Level; @@ -45,7 +46,8 @@ public abstract class RedstoneBlock extends RotatableBlock private boolean redstoneIsActivated(LevelReader level, BlockPos pos) { - if(level.hasNeighborSignal(pos)) + ServerLevel srv = (ServerLevel)level; + if(srv.hasNeighborSignal(pos)) return true; else return false; } diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/Auxiliaries.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/Auxiliaries.java deleted file mode 100644 index eb57f30..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/Auxiliaries.java +++ /dev/null @@ -1,590 +0,0 @@ -/* - * @file Auxiliaries.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * General commonly used functionality. - */ -package dev.zontreck.libzontreck.edlibmc; - -import com.mojang.blaze3d.platform.InputConstants; -import net.minecraft.ChatFormatting; -import net.minecraft.SharedConstants; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.Registry; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; -import net.minecraft.network.chat.ComponentUtils; -import net.minecraft.network.chat.MutableComponent; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.shapes.BooleanOp; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.fml.ModList; -import net.minecraftforge.registries.ForgeRegistries; -import org.slf4j.Logger; -import org.lwjgl.glfw.GLFW; - -import javax.annotation.Nullable; -import java.io.BufferedReader; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.function.Function; -import java.util.function.Supplier; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; - - -public class Auxiliaries { - private static String modid; - private static Logger logger; - private static Supplier server_config_supplier = CompoundTag::new; - - public static void init(String modid, Logger logger, Supplier server_config_supplier) { - Auxiliaries.modid = modid; - Auxiliaries.logger = logger; - Auxiliaries.server_config_supplier = server_config_supplier; - } - - // ------------------------------------------------------------------------------------------------------------------- - // Mod specific exports - // ------------------------------------------------------------------------------------------------------------------- - - public static String modid() { - return modid; - } - - public static Logger logger() { - return logger; - } - - // ------------------------------------------------------------------------------------------------------------------- - // Sidedness, system/environment, tagging interfaces - // ------------------------------------------------------------------------------------------------------------------- - - public interface IExperimentalFeature { - } - - public static boolean isModLoaded(final String registry_name) { - return ModList.get().isLoaded(registry_name); - } - - public static boolean isDevelopmentMode() { - return SharedConstants.IS_RUNNING_IN_IDE; - } - - @OnlyIn(Dist.CLIENT) - public static boolean isShiftDown() { - return (InputConstants.isKeyDown(SidedProxy.mc().getWindow().getWindow(), GLFW.GLFW_KEY_LEFT_SHIFT) || - InputConstants.isKeyDown(SidedProxy.mc().getWindow().getWindow(), GLFW.GLFW_KEY_RIGHT_SHIFT)); - } - - @OnlyIn(Dist.CLIENT) - public static boolean isCtrlDown() { - return (InputConstants.isKeyDown(SidedProxy.mc().getWindow().getWindow(), GLFW.GLFW_KEY_LEFT_CONTROL) || - InputConstants.isKeyDown(SidedProxy.mc().getWindow().getWindow(), GLFW.GLFW_KEY_RIGHT_CONTROL)); - } - - // ------------------------------------------------------------------------------------------------------------------- - // Logging - // ------------------------------------------------------------------------------------------------------------------- - - public static void logInfo(final String msg) { - logger.info(msg); - } - - public static void logWarn(final String msg) { - logger.warn(msg); - } - - public static void logError(final String msg) { - logger.error(msg); - } - - public static void logDebug(final String msg) { /*logger.debug(msg);*/ } - - // ------------------------------------------------------------------------------------------------------------------- - // Localization, text formatting - // ------------------------------------------------------------------------------------------------------------------- - - /** - * Text localization wrapper, implicitly prepends `MODID` to the - * translation keys. Forces formatting argument, nullable if no special formatting shall be applied.. - */ - public static MutableComponent localizable(String modtrkey, Object... args) { - return Component.translatable((modtrkey.startsWith("block.") || (modtrkey.startsWith("item."))) ? (modtrkey) : (modid + "." + modtrkey), args); - } - - public static MutableComponent localizable(String modtrkey, @Nullable ChatFormatting color, Object... args) { - final MutableComponent tr = Component.translatable(modid + "." + modtrkey, args); - if (color != null) tr.getStyle().applyFormat(color); - return tr; - } - - public static Component localizable(String modtrkey) { - return localizable(modtrkey, new Object[]{}); - } - - public static Component localizable_block_key(String blocksubkey) { - return Component.translatable("block." + modid + "." + blocksubkey); - } - - @OnlyIn(Dist.CLIENT) - public static String localize(String translationKey, Object... args) { - Component tr = Component.translatable(translationKey, args); - tr.getStyle().applyFormat(ChatFormatting.RESET); - final String ft = tr.getString(); - if (ft.contains("${")) { - // Non-recursive, non-argument lang file entry cross referencing. - Pattern pt = Pattern.compile("\\$\\{([^}]+)\\}"); - Matcher mt = pt.matcher(ft); - StringBuffer sb = new StringBuffer(); - while (mt.find()) { - String m = mt.group(1); - if (m.contains("?")) { - String[] kv = m.split("\\?", 2); - String key = kv[0].trim(); - boolean not = key.startsWith("!"); - if (not) key = key.replaceFirst("!", ""); - m = kv[1].trim(); - if (!server_config_supplier.get().contains(key)) { - m = ""; - } else { - boolean r = server_config_supplier.get().getBoolean(key); - if (not) r = !r; - if (!r) m = ""; - } - } - mt.appendReplacement(sb, Matcher.quoteReplacement((Component.translatable(m)).getString().trim())); - } - mt.appendTail(sb); - return sb.toString(); - } else { - return ft; - } - } - - /** - * Returns true if a given key is translated for the current language. - */ - @OnlyIn(Dist.CLIENT) - public static boolean hasTranslation(String key) { - return net.minecraft.client.resources.language.I18n.exists(key); - } - - public static MutableComponent join(Collection components, String separator) { - return ComponentUtils.formatList(components, Component.literal(separator), Function.identity()); - } - - public static MutableComponent join(Component... components) { - final MutableComponent tc = Component.empty(); - for (Component c : components) { - tc.append(c); - } - return tc; - } - - public static boolean isEmpty(Component component) { - return component.getSiblings().isEmpty() && component.getString().isEmpty(); - } - - public static final class Tooltip { - @OnlyIn(Dist.CLIENT) - public static boolean extendedTipCondition() { - return isShiftDown(); - } - - @OnlyIn(Dist.CLIENT) - public static boolean helpCondition() { - return isShiftDown() && isCtrlDown(); - } - - /** - * Adds an extended tooltip or help tooltip depending on the key states of CTRL and SHIFT. - * Returns true if the localisable help/tip was added, false if not (either not CTL/SHIFT or - * no translation found). - */ - @OnlyIn(Dist.CLIENT) - public static boolean addInformation(@Nullable String advancedTooltipTranslationKey, @Nullable String helpTranslationKey, List tooltip, TooltipFlag flag, boolean addAdvancedTooltipHints) { - // Note: intentionally not using keybinding here, this must be `control` or `shift`. - final boolean help_available = (helpTranslationKey != null) && Auxiliaries.hasTranslation(helpTranslationKey + ".help"); - final boolean tip_available = (advancedTooltipTranslationKey != null) && Auxiliaries.hasTranslation(helpTranslationKey + ".tip"); - if ((!help_available) && (!tip_available)) return false; - String tip_text = ""; - if (helpCondition()) { - if (help_available) tip_text = localize(helpTranslationKey + ".help"); - } else if (extendedTipCondition()) { - if (tip_available) tip_text = localize(advancedTooltipTranslationKey + ".tip"); - } else if (addAdvancedTooltipHints) { - if (tip_available) tip_text += localize(modid + ".tooltip.hint.extended") + (help_available ? " " : ""); - if (help_available) tip_text += localize(modid + ".tooltip.hint.help"); - } - if (tip_text.isEmpty()) return false; - String[] tip_list = tip_text.split("\\r?\\n"); - for (String tip : tip_list) { - tooltip.add(Component.literal(tip.replaceAll("\\s+$", "").replaceAll("^\\s+", "")).withStyle(ChatFormatting.GRAY)); - } - return true; - } - - /** - * Adds an extended tooltip or help tooltip for a given stack depending on the key states of CTRL and SHIFT. - * Format in the lang file is (e.g. for items): "item.MODID.REGISTRYNAME.tip" and "item.MODID.REGISTRYNAME.help". - * Return value see method pattern above. - */ - @OnlyIn(Dist.CLIENT) - public static boolean addInformation(ItemStack stack, @Nullable BlockGetter world, List tooltip, TooltipFlag flag, boolean addAdvancedTooltipHints) { - return addInformation(stack.getDescriptionId(), stack.getDescriptionId(), tooltip, flag, addAdvancedTooltipHints); - } - - @OnlyIn(Dist.CLIENT) - public static boolean addInformation(String translation_key, List tooltip) { - if (!Auxiliaries.hasTranslation(translation_key)) return false; - tooltip.add(Component.literal(localize(translation_key).replaceAll("\\s+$", "").replaceAll("^\\s+", "")).withStyle(ChatFormatting.GRAY)); - return true; - } - - } - - @SuppressWarnings("unused") - public static void playerChatMessage(final Player player, final String message) { - player.displayClientMessage(Component.translatable(message.trim()), true); - } - - public static @Nullable Component unserializeTextComponent(String serialized) { - return Component.Serializer.fromJson(serialized); - } - - public static String serializeTextComponent(Component tc) { - return (tc == null) ? ("") : (Component.Serializer.toJson(tc)); - } - - // ------------------------------------------------------------------------------------------------------------------- - // Tag Handling - // ------------------------------------------------------------------------------------------------------------------- - - @SuppressWarnings("deprecation") - public static boolean isInItemTag(Item item, ResourceLocation tag) { - return ForgeRegistries.ITEMS.tags().stream().filter(tg -> tg.getKey().location().equals(tag)).anyMatch(tk -> tk.contains(item)); - } - - @SuppressWarnings("deprecation") - public static boolean isInBlockTag(Block block, ResourceLocation tag) { - return ForgeRegistries.BLOCKS.tags().stream().filter(tg -> tg.getKey().location().equals(tag)).anyMatch(tk -> tk.contains(block)); - } - - @SuppressWarnings("deprecation") - public static ResourceLocation getResourceLocation(Item item) { - return ForgeRegistries.ITEMS.getKey(item); - } - - @SuppressWarnings("deprecation") - public static ResourceLocation getResourceLocation(Block block) { - return ForgeRegistries.BLOCKS.getKey(block); - } - - @SuppressWarnings("deprecation") - public static ResourceLocation getResourceLocation(net.minecraft.world.inventory.MenuType menu) { - return ForgeRegistries.MENU_TYPES.getKey(menu); - } - - @SuppressWarnings("deprecation") - public static ResourceLocation getResourceLocation(net.minecraft.world.level.material.Fluid fluid) { - return ForgeRegistries.FLUIDS.getKey(fluid); - } - - // ------------------------------------------------------------------------------------------------------------------- - // Item NBT data - // ------------------------------------------------------------------------------------------------------------------- - - /** - * Equivalent to getDisplayName(), returns null if no custom name is set. - */ - public static @Nullable Component getItemLabel(ItemStack stack) { - CompoundTag nbt = stack.getTagElement("display"); - if (nbt != null && nbt.contains("Name", 8)) { - try { - Component tc = unserializeTextComponent(nbt.getString("Name")); - if (tc != null) return tc; - nbt.remove("Name"); - } catch (Exception e) { - nbt.remove("Name"); - } - } - return null; - } - - public static ItemStack setItemLabel(ItemStack stack, @Nullable Component name) { - if (name != null) { - CompoundTag nbt = stack.getOrCreateTagElement("display"); - nbt.putString("Name", serializeTextComponent(name)); - } else { - if (stack.hasTag()) stack.removeTagKey("display"); - } - return stack; - } - - // ------------------------------------------------------------------------------------------------------------------- - // Block handling - // ------------------------------------------------------------------------------------------------------------------- - - public static boolean isWaterLogged(BlockState state) { - return state.hasProperty(BlockStateProperties.WATERLOGGED) && state.getValue(BlockStateProperties.WATERLOGGED); - } - - public static AABB getPixeledAABB(double x0, double y0, double z0, double x1, double y1, double z1) { - return new AABB(x0 / 16.0, y0 / 16.0, z0 / 16.0, x1 / 16.0, y1 / 16.0, z1 / 16.0); - } - - public static AABB getRotatedAABB(AABB bb, Direction new_facing) { - return getRotatedAABB(bb, new_facing, false); - } - - public static AABB[] getRotatedAABB(AABB[] bb, Direction new_facing) { - return getRotatedAABB(bb, new_facing, false); - } - - public static AABB getRotatedAABB(AABB bb, Direction new_facing, boolean horizontal_rotation) { - if (!horizontal_rotation) { - switch (new_facing.get3DDataValue()) { - case 0: - return new AABB(1 - bb.maxX, bb.minZ, bb.minY, 1 - bb.minX, bb.maxZ, bb.maxY); // D - case 1: - return new AABB(1 - bb.maxX, 1 - bb.maxZ, 1 - bb.maxY, 1 - bb.minX, 1 - bb.minZ, 1 - bb.minY); // U - case 2: - return new AABB(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ); // N --> bb - case 3: - return new AABB(1 - bb.maxX, bb.minY, 1 - bb.maxZ, 1 - bb.minX, bb.maxY, 1 - bb.minZ); // S - case 4: - return new AABB(bb.minZ, bb.minY, 1 - bb.maxX, bb.maxZ, bb.maxY, 1 - bb.minX); // W - case 5: - return new AABB(1 - bb.maxZ, bb.minY, bb.minX, 1 - bb.minZ, bb.maxY, bb.maxX); // E - } - } else { - switch (new_facing.get3DDataValue()) { - case 0: - return new AABB(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ); // D --> bb - case 1: - return new AABB(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ); // U --> bb - case 2: - return new AABB(bb.minX, bb.minY, bb.minZ, bb.maxX, bb.maxY, bb.maxZ); // N --> bb - case 3: - return new AABB(1 - bb.maxX, bb.minY, 1 - bb.maxZ, 1 - bb.minX, bb.maxY, 1 - bb.minZ); // S - case 4: - return new AABB(bb.minZ, bb.minY, 1 - bb.maxX, bb.maxZ, bb.maxY, 1 - bb.minX); // W - case 5: - return new AABB(1 - bb.maxZ, bb.minY, bb.minX, 1 - bb.minZ, bb.maxY, bb.maxX); // E - } - } - return bb; - } - - public static AABB[] getRotatedAABB(AABB[] bbs, Direction new_facing, boolean horizontal_rotation) { - final AABB[] transformed = new AABB[bbs.length]; - for (int i = 0; i < bbs.length; ++i) transformed[i] = getRotatedAABB(bbs[i], new_facing, horizontal_rotation); - return transformed; - } - - public static AABB getYRotatedAABB(AABB bb, int clockwise_90deg_steps) { - final Direction[] direction_map = new Direction[]{Direction.NORTH, Direction.EAST, Direction.SOUTH, Direction.WEST}; - return getRotatedAABB(bb, direction_map[(clockwise_90deg_steps + 4096) & 0x03], true); - } - - public static AABB[] getYRotatedAABB(AABB[] bbs, int clockwise_90deg_steps) { - final AABB[] transformed = new AABB[bbs.length]; - for (int i = 0; i < bbs.length; ++i) transformed[i] = getYRotatedAABB(bbs[i], clockwise_90deg_steps); - return transformed; - } - - public static AABB getMirroredAABB(AABB bb, Direction.Axis axis) { - return switch (axis) { - case X -> new AABB(1 - bb.maxX, bb.minY, bb.minZ, 1 - bb.minX, bb.maxY, bb.maxZ); - case Y -> new AABB(bb.minX, 1 - bb.maxY, bb.minZ, bb.maxX, 1 - bb.minY, bb.maxZ); - case Z -> new AABB(bb.minX, bb.minY, 1 - bb.maxZ, bb.maxX, bb.maxY, 1 - bb.minZ); - }; - } - - public static AABB[] getMirroredAABB(AABB[] bbs, Direction.Axis axis) { - final AABB[] transformed = new AABB[bbs.length]; - for (int i = 0; i < bbs.length; ++i) transformed[i] = getMirroredAABB(bbs[i], axis); - return transformed; - } - - public static VoxelShape getUnionShape(AABB... aabbs) { - VoxelShape shape = Shapes.empty(); - for (AABB aabb : aabbs) shape = Shapes.joinUnoptimized(shape, Shapes.create(aabb), BooleanOp.OR); - return shape; - } - - public static VoxelShape getUnionShape(AABB[]... aabb_list) { - VoxelShape shape = Shapes.empty(); - for (AABB[] aabbs : aabb_list) { - for (AABB aabb : aabbs) shape = Shapes.joinUnoptimized(shape, Shapes.create(aabb), BooleanOp.OR); - } - return shape; - } - - public static AABB[] getMappedAABB(AABB[] bbs, Function mapper) { - final AABB[] transformed = new AABB[bbs.length]; - for (int i = 0; i < bbs.length; ++i) transformed[i] = mapper.apply(bbs[i]); - return transformed; - } - - public static final class BlockPosRange implements Iterable { - private final int x0, x1, y0, y1, z0, z1; - - public BlockPosRange(int x0, int y0, int z0, int x1, int y1, int z1) { - this.x0 = Math.min(x0, x1); - this.x1 = Math.max(x0, x1); - this.y0 = Math.min(y0, y1); - this.y1 = Math.max(y0, y1); - this.z0 = Math.min(z0, z1); - this.z1 = Math.max(z0, z1); - } - - public static BlockPosRange of(AABB range) { - return new BlockPosRange( - (int) Math.floor(range.minX), - (int) Math.floor(range.minY), - (int) Math.floor(range.minZ), - (int) Math.floor(range.maxX - .0625), - (int) Math.floor(range.maxY - .0625), - (int) Math.floor(range.maxZ - .0625) - ); - } - - public int getXSize() { - return x1 - x0 + 1; - } - - public int getYSize() { - return y1 - y0 + 1; - } - - public int getZSize() { - return z1 - z0 + 1; - } - - public int getArea() { - return getXSize() * getZSize(); - } - - public int getHeight() { - return getYSize(); - } - - public int getVolume() { - return getXSize() * getYSize() * getZSize(); - } - - public BlockPos byXZYIndex(int xyz_index) { - final int xsz = getXSize(), ysz = getYSize(), zsz = getZSize(); - xyz_index = xyz_index % (xsz * ysz * zsz); - final int y = xyz_index / (xsz * zsz); - xyz_index -= y * (xsz * zsz); - final int z = xyz_index / xsz; - xyz_index -= z * xsz; - final int x = xyz_index; - return new BlockPos(x0 + x, y0 + y, z0 + z); - } - - public BlockPos byXZIndex(int xz_index, int y_offset) { - final int xsz = getXSize(), zsz = getZSize(); - xz_index = xz_index % (xsz * zsz); - final int z = xz_index / xsz; - xz_index -= z * xsz; - final int x = xz_index; - return new BlockPos(x0 + x, y0 + y_offset, z0 + z); - } - - public static final class BlockRangeIterator implements Iterator { - private final BlockPosRange range_; - private int x, y, z; - - public BlockRangeIterator(BlockPosRange range) { - range_ = range; - x = range.x0; - y = range.y0; - z = range.z0; - } - - @Override - public boolean hasNext() { - return (z <= range_.z1); - } - - @Override - public BlockPos next() { - if (!hasNext()) throw new NoSuchElementException(); - final BlockPos pos = new BlockPos(x, y, z); - ++x; - if (x > range_.x1) { - x = range_.x0; - ++y; - if (y > range_.y1) { - y = range_.y0; - ++z; - } - } - return pos; - } - } - - @Override - public BlockRangeIterator iterator() { - return new BlockRangeIterator(this); - } - - public Stream stream() { - return java.util.stream.StreamSupport.stream(spliterator(), false); - } - } - - // ------------------------------------------------------------------------------------------------------------------- - // JAR resource related - // ------------------------------------------------------------------------------------------------------------------- - - public static String loadResourceText(InputStream is) { - try { - if (is == null) return ""; - BufferedReader br = new BufferedReader(new InputStreamReader(is, StandardCharsets.UTF_8)); - return br.lines().collect(Collectors.joining("\n")); - } catch (Throwable e) { - return ""; - } - } - - public static String loadResourceText(String path) { - return loadResourceText(Auxiliaries.class.getResourceAsStream(path)); - } - - public static void logGitVersion(String mod_name) { - try { - // Done during construction to have an exact version in case of a crash while registering. - String version = Auxiliaries.loadResourceText("/.gitversion-" + modid).trim(); - logInfo(mod_name + ((version.isEmpty()) ? (" (dev build)") : (" GIT id #" + version)) + "."); - } catch (Throwable e) { - // (void)e; well, then not. Priority is not to get unneeded crashes because of version logging. - } - } -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/Containers.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/Containers.java deleted file mode 100644 index 37a1814..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/Containers.java +++ /dev/null @@ -1,138 +0,0 @@ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.util.Mth; -import net.minecraft.world.Container; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.Slot; -import net.minecraft.world.item.ItemStack; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import java.util.function.BiConsumer; - -public class Containers { - // ------------------------------------------------------------------------------------------------------------------- - // Slots - // ------------------------------------------------------------------------------------------------------------------- - - public static class StorageSlot extends Slot { - protected BiConsumer slot_change_action_ = (oldStack, newStack) -> { - }; - protected int stack_limit_ = 64; - public boolean enabled = true; - - public StorageSlot(Container inventory, int index, int x, int y) { - super(inventory, index, x, y); - } - - public StorageSlot setSlotStackLimit(int limit) { - stack_limit_ = Mth.clamp(limit, 1, 64); - return this; - } - - public int getMaxStackSize() { - return stack_limit_; - } - - public StorageSlot setSlotChangeNotifier(BiConsumer action) { - slot_change_action_ = action; - return this; - } - - @Override - public void onQuickCraft(ItemStack oldStack, ItemStack newStack) { - slot_change_action_.accept(oldStack, newStack); - } // no crafting trigger - - @Override - public void set(ItemStack stack) { - if (stack.is(getItem().getItem())) { - super.set(stack); - } else { - final ItemStack before = getItem().copy(); - super.set(stack); // whatever this does else next to setting inventory. - slot_change_action_.accept(before, getItem()); - } - } - - @Override - public boolean mayPlace(ItemStack stack) { - return enabled && this.container.canPlaceItem(this.getSlotIndex(), stack); - } - - @Override - public int getMaxStackSize(ItemStack stack) { - return Math.min(getMaxStackSize(), stack_limit_); - } - - @OnlyIn(Dist.CLIENT) - public boolean isActive() { - return enabled; - } - } - - public static class LockedSlot extends Slot { - protected int stack_limit_ = 64; - public boolean enabled = true; - - public LockedSlot(Container inventory, int index, int x, int y) { - super(inventory, index, x, y); - } - - public LockedSlot setSlotStackLimit(int limit) { - stack_limit_ = Mth.clamp(limit, 1, 64); - return this; - } - - public int getMaxStackSize() { - return stack_limit_; - } - - @Override - public int getMaxStackSize(ItemStack stack) { - return Math.min(getMaxStackSize(), stack_limit_); - } - - @Override - public boolean mayPlace(ItemStack stack) { - return false; - } - - @Override - public boolean mayPickup(Player player) { - return false; - } - - @OnlyIn(Dist.CLIENT) - public boolean isActive() { - return enabled; - } - } - - public static class HiddenSlot extends Slot { - public HiddenSlot(Container inventory, int index) { - super(inventory, index, 0, 0); - } - - @Override - public int getMaxStackSize(ItemStack stack) { - return getMaxStackSize(); - } - - @Override - public boolean mayPlace(ItemStack stack) { - return false; - } - - @Override - public boolean mayPickup(Player player) { - return false; - } - - @OnlyIn(Dist.CLIENT) - public boolean isActive() { - return false; - } - } - -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/Crafting.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/Crafting.java deleted file mode 100644 index 2708733..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/Crafting.java +++ /dev/null @@ -1,440 +0,0 @@ -/* - * @file Recipes.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Recipe utility functionality. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.core.NonNullList; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Mth; -import net.minecraft.util.Tuple; -import net.minecraft.world.Container; -import net.minecraft.world.SimpleContainer; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.entity.player.StackedContents; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.inventory.CraftingContainer; -import net.minecraft.world.item.EnchantedBookItem; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.Items; -import net.minecraft.world.item.crafting.*; -import net.minecraft.world.item.enchantment.Enchantment; -import net.minecraft.world.item.enchantment.EnchantmentHelper; -import net.minecraft.world.item.enchantment.EnchantmentInstance; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.ComposterBlock; -import net.minecraftforge.common.ForgeHooks; -import net.minecraftforge.common.brewing.BrewingRecipeRegistry; - -import javax.annotation.Nullable; -import java.util.*; -import java.util.function.BiPredicate; - - -public class Crafting { - // ------------------------------------------------------------------------------------------------------------------- - - /** - * Returns a Crafting recipe by registry name. - */ - public static Optional getCraftingRecipe(Level world, ResourceLocation recipe_id) { - Recipe recipe = world.getRecipeManager().byKey(recipe_id).orElse(null); - return (recipe instanceof CraftingRecipe) ? Optional.of((CraftingRecipe) recipe) : Optional.empty(); - } - - /** - * Returns a list of matching recipes by the first N slots (crafting grid slots) of the given inventory. - */ - public static List get3x3CraftingRecipes(Level world, Container crafting_grid_slots) { - return CraftingGrid.instance3x3.getRecipes(world, crafting_grid_slots); - } - - /** - * Returns a recipe by the first N slots (crafting grid slots). - */ - public static Optional get3x3CraftingRecipe(Level world, Container crafting_grid_slots) { - return get3x3CraftingRecipes(world, crafting_grid_slots).stream().findFirst(); - } - - /** - * Returns the result item of the recipe with the given grid layout. - */ - public static ItemStack get3x3CraftingResult(Level world, Container grid, CraftingRecipe recipe) { - return CraftingGrid.instance3x3.getCraftingResult(world, grid, recipe); - } - - /** - * Returns the items remaining in the grid after crafting 3x3. - */ - public static List get3x3RemainingItems(Level world, Container grid, CraftingRecipe recipe) { - return CraftingGrid.instance3x3.getRemainingItems(world, grid, recipe); - } - - public static List get3x3Placement(Level world, CraftingRecipe recipe, Container item_inventory, @Nullable Container crafting_grid) { - final int width = 3; - final int height = 3; - if (!recipe.canCraftInDimensions(width, height)) return Collections.emptyList(); - List used = new ArrayList<>(); //NonNullList.withSize(width*height); - for (int i = width * height; i > 0; --i) used.add(ItemStack.EMPTY); - Container check_inventory = Inventories.copyOf(item_inventory); - Inventories.InventoryRange source = new Inventories.InventoryRange(check_inventory); - final List ingredients = recipe.getIngredients(); - final List preferred = new ArrayList<>(width * height); - if (crafting_grid != null) { - for (int i = 0; i < crafting_grid.getContainerSize(); ++i) { - ItemStack stack = crafting_grid.getItem(i); - if (stack.isEmpty()) continue; - stack = stack.copy(); - stack.setCount(1); - if (!source.extract(stack).isEmpty()) preferred.add(stack); - } - } - for (int i = 0; i < ingredients.size(); ++i) { - final Ingredient ingredient = ingredients.get(i); - if (ingredient == Ingredient.EMPTY) continue; - ItemStack stack = preferred.stream().filter(ingredient).findFirst().orElse(ItemStack.EMPTY); - if (!stack.isEmpty()) { - preferred.remove(stack); - } else { - stack = source.stream().filter(ingredient).findFirst().orElse(ItemStack.EMPTY); - if (stack.isEmpty()) return Collections.emptyList(); - stack = stack.copy(); - stack.setCount(1); - if (source.extract(stack).isEmpty()) return Collections.emptyList(); - } - used.set(i, stack); - } - if (recipe instanceof ShapedRecipe shaped) { - List placement = NonNullList.withSize(width * height, ItemStack.EMPTY); - for (int row = 0; row < shaped.getRecipeHeight(); ++row) { - for (int col = 0; col < shaped.getRecipeWidth(); ++col) { - placement.set(width * row + col, used.get(row * shaped.getRecipeWidth() + col)); - } - } - return placement; - } else { - return used; - } - } - - /** - * Returns the recipe for a given input stack to smelt, null if there is no recipe - * for the given type (SMELTING,BLASTING,SMOKING, etc). - */ - public static > Optional getFurnaceRecipe(RecipeType recipe_type, Level world, ItemStack input_stack) { - if (input_stack.isEmpty()) { - return Optional.empty(); - } else if (recipe_type == RecipeType.SMELTING) { - SimpleContainer inventory = new SimpleContainer(3); - inventory.setItem(0, input_stack); - SmeltingRecipe recipe = world.getRecipeManager().getRecipeFor(RecipeType.SMELTING, inventory, world).orElse(null); - return (recipe == null) ? Optional.empty() : Optional.of(recipe); - } else if (recipe_type == RecipeType.BLASTING) { - SimpleContainer inventory = new SimpleContainer(3); - inventory.setItem(0, input_stack); - BlastingRecipe recipe = world.getRecipeManager().getRecipeFor(RecipeType.BLASTING, inventory, world).orElse(null); - return (recipe == null) ? Optional.empty() : Optional.of(recipe); - } else if (recipe_type == RecipeType.SMOKING) { - SimpleContainer inventory = new SimpleContainer(3); - inventory.setItem(0, input_stack); - SmokingRecipe recipe = world.getRecipeManager().getRecipeFor(RecipeType.SMOKING, inventory, world).orElse(null); - return (recipe == null) ? Optional.empty() : Optional.of(recipe); - } else { - return Optional.empty(); - } - } - - // ------------------------------------------------------------------------------------------------------------------- - - public static > int getSmeltingTimeNeeded(RecipeType recipe_type, Level world, ItemStack stack) { - if (stack.isEmpty()) return 0; - final int t = getFurnaceRecipe(recipe_type, world, stack).map((AbstractCookingRecipe::getCookingTime)).orElse(0); - return (t <= 0) ? 200 : t; - } - - /** - * Returns the burn time of an item when used as fuel, 0 if it is no fuel. - */ - public static int getFuelBurntime(Level world, ItemStack stack) { - if (stack.isEmpty()) return 0; - int t = ForgeHooks.getBurnTime(stack, null); - return Math.max(t, 0); - } - - /** - * Returns true if an item can be used as fuel. - */ - public static boolean isFuel(Level world, ItemStack stack) { - return (getFuelBurntime(world, stack) > 0) || (stack.getItem() == Items.LAVA_BUCKET); - } - - /** - * Returns burntime and remaining stack then the item shall be used as fuel. - */ - public static Tuple consumeFuel(Level world, ItemStack stack) { - if (stack.isEmpty()) return new Tuple<>(0, stack); - int burnime = getFuelBurntime(world, stack); - if ((stack.getItem() == Items.LAVA_BUCKET)) { - if (burnime <= 0) burnime = 1000 * 20; - return new Tuple<>(burnime, new ItemStack(Items.BUCKET)); - } else if (burnime <= 0) { - return new Tuple<>(0, stack); - } else { - ItemStack left_over = stack.copy(); - left_over.shrink(1); - return new Tuple<>(burnime, left_over); - } - } - - /** - * Returns true if the item can be used as brewing fuel. - */ - public static boolean isBrewingFuel(Level world, ItemStack stack) { - return (stack.getItem() == Items.BLAZE_POWDER) || (stack.getItem() == Items.BLAZE_ROD); - } - - // ------------------------------------------------------------------------------------------------------------------- - - /** - * Returns true if the item can be used as brewing ingredient. - */ - public static boolean isBrewingIngredient(Level world, ItemStack stack) { - return BrewingRecipeRegistry.isValidIngredient(stack); - } - - /** - * Returns true if the item can be used as brewing bottle. - */ - public static boolean isBrewingInput(Level world, ItemStack stack) { - return BrewingRecipeRegistry.isValidInput(stack); - } - - /** - * Returns the burn time for brewing of the given stack. - */ - public static int getBrewingFuelBurntime(Level world, ItemStack stack) { - if (stack.isEmpty()) return 0; - if (stack.getItem() == Items.BLAZE_POWDER) return (400 * 20); - if (stack.getItem() == Items.BLAZE_ROD) return (400 * 40); - return 0; - } - - /** - * Returns brewing burn time and remaining stack if the item shall be used as fuel. - */ - public static Tuple consumeBrewingFuel(Level world, ItemStack stack) { - int burntime = getBrewingFuelBurntime(world, stack); - if (burntime <= 0) return new Tuple<>(0, stack.copy()); - stack = stack.copy(); - stack.shrink(1); - return new Tuple<>(burntime, stack.isEmpty() ? ItemStack.EMPTY : stack); - } - - public static double getCompostingChance(ItemStack stack) { - return ComposterBlock.COMPOSTABLES.getOrDefault(stack.getItem(), 0); - } - - /** - * Returns the enchtments bound to the given stack. - */ - public static Map getEnchantmentsOnItem(Level world, ItemStack stack) { - return (stack.isEmpty() || (stack.getTag() == null)) ? Collections.emptyMap() : EnchantmentHelper.getEnchantments(stack); - } - - // ------------------------------------------------------------------------------------------------------------------- - - /** - * Returns an enchanted book with the given enchantment, emtpy stack if not applicable. - */ - public static ItemStack getEnchantmentBook(Level world, Enchantment enchantment, int level) { - return ((!enchantment.isAllowedOnBooks()) || (level <= 0)) ? ItemStack.EMPTY : EnchantedBookItem.createForEnchantment(new EnchantmentInstance(enchantment, level)); - } - - // ------------------------------------------------------------------------------------------------------------------- - - /** - * Returns the accumulated repair cost for the given enchantments. - */ - public static int getEnchantmentRepairCost(Level world, Map enchantments) { - int repair_cost = 0; - for (Map.Entry e : enchantments.entrySet()) - repair_cost = repair_cost * 2 + 1; // @see: RepairContainer.getNewRepairCost() - return repair_cost; - } - - /** - * Trys to add an enchtment to the given stack, returns boolean success. - */ - public static boolean addEnchantmentOnItem(Level world, ItemStack stack, Enchantment enchantment, int level) { - if (stack.isEmpty() || (level <= 0) || (!stack.isEnchantable()) || (level >= enchantment.getMaxLevel())) - return false; - final Map on_item = getEnchantmentsOnItem(world, stack); - if (on_item.keySet().stream().anyMatch(ench -> ench.isCompatibleWith(enchantment))) return false; - final ItemStack book = EnchantedBookItem.createForEnchantment(new EnchantmentInstance(enchantment, level)); - if ((!(stack.isBookEnchantable(book) && enchantment.isAllowedOnBooks())) && (!stack.canApplyAtEnchantingTable(enchantment)) && (!enchantment.canEnchant(stack))) - return false; - final int existing_level = on_item.getOrDefault(enchantment, 0); - if (existing_level > 0) level = Mth.clamp(level + existing_level, 1, enchantment.getMaxLevel()); - on_item.put(enchantment, level); - EnchantmentHelper.setEnchantments(on_item, stack); - stack.setRepairCost(getEnchantmentRepairCost(world, on_item)); - return true; - } - - /** - * Removes enchantments from a stack, returns the removed enchantments. - */ - public static Map removeEnchantmentsOnItem(Level world, ItemStack stack, BiPredicate filter) { - if (stack.isEmpty()) return Collections.emptyMap(); - final Map on_item = getEnchantmentsOnItem(world, stack); - final Map removed = new HashMap<>(); - for (Map.Entry e : on_item.entrySet()) { - if (filter.test(e.getKey(), e.getValue())) { - removed.put(e.getKey(), e.getValue()); - } - } - for (Enchantment e : removed.keySet()) { - on_item.remove(e); - } - EnchantmentHelper.setEnchantments(on_item, stack); - stack.setRepairCost(getEnchantmentRepairCost(world, on_item)); - return removed; - } - - public static final class CraftingGrid implements CraftingContainer { - private static final CraftingGrid instance3x3 = new CraftingGrid(3, 3); - - final int _width; - - private CraftingGrid(int width, int height) { - _width=width; - } - - private void fill(Container grid) { - for (int i = 0; i < getContainerSize(); ++i) - setItem(i, i >= grid.getContainerSize() ? ItemStack.EMPTY : grid.getItem(i)); - } - - public List getRecipes(Level world, Container grid) { - fill(grid); - return world.getRecipeManager().getRecipesFor(RecipeType.CRAFTING, this, world); - } - - public List getRemainingItems(Level world, Container grid, CraftingRecipe recipe) { - fill(grid); - return recipe.getRemainingItems(this); - } - - public ItemStack getCraftingResult(Level world, Container grid, CraftingRecipe recipe) { - fill(grid); - return recipe.assemble(this, world.registryAccess()); - } - - @Override - public int getWidth() { - return _width; - } - - @Override - public int getHeight() { - return 0; - } - - @Override - public List getItems() { - return null; - } - - @Override - public int getContainerSize() { - return 0; - } - - @Override - public boolean isEmpty() { - return false; - } - - @Override - public ItemStack getItem(int i) { - return null; - } - - @Override - public ItemStack removeItem(int i, int i1) { - return null; - } - - @Override - public ItemStack removeItemNoUpdate(int i) { - return null; - } - - @Override - public void setItem(int i, ItemStack itemStack) { - - } - - @Override - public void setChanged() { - - } - - @Override - public boolean stillValid(Player player) { - return false; - } - - @Override - public void clearContent() { - - } - - @Override - public void fillStackedContents(StackedContents stackedContents) { - - } - } - - public static final class BrewingOutput { - public static final int DEFAULT_BREWING_TIME = 400; - public static final BrewingOutput EMPTY = new BrewingOutput(ItemStack.EMPTY, new SimpleContainer(1), new SimpleContainer(1), 0, 0, DEFAULT_BREWING_TIME); - public final ItemStack item; - public final Container potionInventory; - public final Container ingredientInventory; - public final int potionSlot; - public final int ingredientSlot; - public final int brewTime; - - public BrewingOutput(ItemStack output_potion, Container potion_inventory, Container ingredient_inventory, int potion_slot, int ingredient_slot, int time_needed) { - item = output_potion; - potionInventory = potion_inventory; - ingredientInventory = ingredient_inventory; - potionSlot = potion_slot; - ingredientSlot = ingredient_slot; - brewTime = time_needed; - } - - public static BrewingOutput find(Level world, Container potion_inventory, Container ingredient_inventory) { - for (int potion_slot = 0; potion_slot < potion_inventory.getContainerSize(); ++potion_slot) { - final ItemStack pstack = potion_inventory.getItem(potion_slot); - if (!isBrewingInput(world, pstack)) continue; - for (int ingredient_slot = 0; ingredient_slot < ingredient_inventory.getContainerSize(); ++ingredient_slot) { - final ItemStack istack = ingredient_inventory.getItem(ingredient_slot); - if ((!isBrewingIngredient(world, istack)) || (ingredient_slot == potion_slot) || (isBrewingFuel(world, istack))) - continue; - final ItemStack result = BrewingRecipeRegistry.getOutput(pstack, istack); - if (result.isEmpty()) continue; - return new BrewingOutput(result, potion_inventory, ingredient_inventory, potion_slot, ingredient_slot, DEFAULT_BREWING_TIME); - } - } - return BrewingOutput.EMPTY; - } - } - - -} \ No newline at end of file diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/Fluidics.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/Fluidics.java deleted file mode 100644 index 6ac9dbd..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/Fluidics.java +++ /dev/null @@ -1,485 +0,0 @@ -/* - * @file Fluidics.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * General fluid handling functionality. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.util.Mth; -import net.minecraft.util.Tuple; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.material.Fluid; -import net.minecraftforge.common.capabilities.Capability; -import net.minecraftforge.common.capabilities.ForgeCapabilities; -import net.minecraftforge.common.capabilities.ICapabilityProvider; -import net.minecraft.nbt.Tag; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.fluids.FluidActionResult; -import net.minecraftforge.fluids.FluidStack; -import net.minecraftforge.fluids.FluidUtil; -import net.minecraftforge.fluids.IFluidTank; -import net.minecraftforge.fluids.capability.IFluidHandler; -import net.minecraftforge.fluids.capability.IFluidHandler.FluidAction; -import net.minecraftforge.fluids.capability.IFluidHandlerItem; -import net.minecraftforge.items.IItemHandler; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.function.BiConsumer; -import java.util.function.Function; -import java.util.function.Predicate; - - -public class Fluidics { - public static class SingleTankFluidHandler implements IFluidHandler { - private final IFluidTank tank_; - - public SingleTankFluidHandler(IFluidTank tank) { - tank_ = tank; - } - - @Override - public int getTanks() { - return 1; - } - - @Override - public FluidStack getFluidInTank(int tank) { - return tank_.getFluid(); - } - - @Override - public int getTankCapacity(int tank) { - return tank_.getCapacity(); - } - - @Override - public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { - return tank_.isFluidValid(stack); - } - - @Override - public int fill(FluidStack resource, FluidAction action) { - return tank_.fill(resource, action); - } - - @Override - public FluidStack drain(FluidStack resource, FluidAction action) { - return tank_.drain(resource, action); - } - - @Override - public FluidStack drain(int maxDrain, FluidAction action) { - return tank_.drain(maxDrain, action); - } - } - - private static class SingleTankOutputFluidHandler implements IFluidHandler { - private final IFluidTank tank_; - - public SingleTankOutputFluidHandler(IFluidTank tank) { - tank_ = tank; - } - - @Override - public int getTanks() { - return 1; - } - - @Override - public FluidStack getFluidInTank(int tank) { - return tank_.getFluid().copy(); - } - - @Override - public int getTankCapacity(int tank) { - return tank_.getCapacity(); - } - - @Override - public boolean isFluidValid(int tank, @Nonnull FluidStack stack) { - return true; - } - - @Override - public int fill(FluidStack resource, FluidAction action) { - return 0; - } - - @Override - public FluidStack drain(FluidStack resource, FluidAction action) { - return tank_.drain(resource, action); - } - - @Override - public FluidStack drain(int maxDrain, FluidAction action) { - return tank_.drain(maxDrain, action); - } - } - - public static class Tank implements IFluidTank { - private Predicate validator_ = ((e) -> true); - private BiConsumer interaction_notifier_ = ((tank, diff) -> { - }); - private FluidStack fluid_ = FluidStack.EMPTY; - private int capacity_; - private int fill_rate_; - private int drain_rate_; - - public Tank(int capacity) { - this(capacity, capacity, capacity); - } - - public Tank(int capacity, int fill_rate, int drain_rate) { - this(capacity, fill_rate, drain_rate, e -> true); - } - - public Tank(int capacity, int fill_rate, int drain_rate, Predicate validator) { - capacity_ = capacity; - setMaxFillRate(fill_rate); - setMaxDrainRate(drain_rate); - setValidator(validator); - } - - public Tank load(CompoundTag nbt) { - if (nbt.contains("tank", Tag.TAG_COMPOUND)) { - setFluid(FluidStack.loadFluidStackFromNBT(nbt.getCompound("tank"))); - } else { - clear(); - } - return this; - } - - public CompoundTag save(CompoundTag nbt) { - if (!isEmpty()) { - nbt.put("tank", fluid_.writeToNBT(new CompoundTag())); - } - return nbt; - } - - public void reset() { - clear(); - } - - public Tank clear() { - setFluid(null); - return this; - } - - public int getCapacity() { - return capacity_; - } - - public Tank setCapacity(int capacity) { - capacity_ = capacity; - return this; - } - - public int getMaxDrainRate() { - return drain_rate_; - } - - public Tank setMaxDrainRate(int rate) { - drain_rate_ = Mth.clamp(rate, 0, capacity_); - return this; - } - - public int getMaxFillRate() { - return fill_rate_; - } - - public Tank setMaxFillRate(int rate) { - fill_rate_ = Mth.clamp(rate, 0, capacity_); - return this; - } - - public Tank setValidator(Predicate validator) { - validator_ = (validator != null) ? validator : ((e) -> true); - return this; - } - - public Tank setInteractionNotifier(BiConsumer notifier) { - interaction_notifier_ = (notifier != null) ? notifier : ((tank, diff) -> { - }); - return this; - } - - public LazyOptional createFluidHandler() { - return LazyOptional.of(() -> new Fluidics.SingleTankFluidHandler(this)); - } - - public LazyOptional createOutputFluidHandler() { - return LazyOptional.of(() -> new Fluidics.SingleTankOutputFluidHandler(this)); - } - - // IFluidTank ------------------------------------------------------------------------------------ - - @Nonnull - public FluidStack getFluid() { - return fluid_; - } - - public void setFluid(@Nullable FluidStack stack) { - fluid_ = (stack == null) ? FluidStack.EMPTY : stack; - } - - public int getFluidAmount() { - return fluid_.getAmount(); - } - - public boolean isEmpty() { - return fluid_.isEmpty(); - } - - public boolean isFull() { - return getFluidAmount() >= getCapacity(); - } - - public boolean isFluidValid(FluidStack stack) { - return validator_.test(stack); - } - - public boolean isFluidEqual(FluidStack stack) { - return (stack == null) ? (fluid_.isEmpty()) : fluid_.isFluidEqual(stack); - } - - @Override - public int fill(FluidStack fs, FluidAction action) { - if ((fs == null) || fs.isEmpty() || (!isFluidValid(fs))) { - return 0; - } else if (action.simulate()) { - if (fluid_.isEmpty()) return Math.min(capacity_, fs.getAmount()); - if (!fluid_.isFluidEqual(fs)) return 0; - return Math.min(capacity_ - fluid_.getAmount(), fs.getAmount()); - } else if (fluid_.isEmpty()) { - fluid_ = new FluidStack(fs, Math.min(capacity_, fs.getAmount())); - return fluid_.getAmount(); - } else if (!fluid_.isFluidEqual(fs)) { - return 0; - } else { - int amount = capacity_ - fluid_.getAmount(); - if (fs.getAmount() < amount) { - fluid_.grow(fs.getAmount()); - amount = fs.getAmount(); - } else { - fluid_.setAmount(capacity_); - } - if (amount != 0) interaction_notifier_.accept(this, amount); - return amount; - } - } - - @Nonnull - public FluidStack drain(int maxDrain) { - return drain(maxDrain, FluidAction.EXECUTE); - } - - @Nonnull - @Override - public FluidStack drain(FluidStack fs, FluidAction action) { - return ((fs.isEmpty()) || (!fs.isFluidEqual(fluid_))) ? FluidStack.EMPTY : drain(fs.getAmount(), action); - } - - @Nonnull - @Override - public FluidStack drain(int maxDrain, FluidAction action) { - final int amount = Math.min(fluid_.getAmount(), maxDrain); - final FluidStack stack = new FluidStack(fluid_, amount); - if ((amount > 0) && action.execute()) { - fluid_.shrink(amount); - if (fluid_.isEmpty()) fluid_ = FluidStack.EMPTY; - if (amount != 0) interaction_notifier_.accept(this, -amount); - } - return stack; - } - } - - // ------------------------------------------------------------------------------------------------------------------- - - public static @Nullable IFluidHandler handler(Level world, BlockPos pos, @Nullable Direction side) { - return FluidUtil.getFluidHandler(world, pos, side).orElse(null); - } - - /** - * Fills or drains items with fluid handlers from or into tile blocks with fluid handlers. - */ - public static boolean manualFluidHandlerInteraction(Level world, BlockPos pos, @Nullable Direction side, Player player, InteractionHand hand) { - return manualTrackedFluidHandlerInteraction(world, pos, side, player, hand) != null; - } - - public static boolean manualFluidHandlerInteraction(Player player, InteractionHand hand, IFluidHandler handler) { - return FluidUtil.interactWithFluidHandler(player, hand, handler); - } - - /** - * Fills or drains items with fluid handlers from or into tile blocks with fluid handlers. - * Returns the fluid and (possibly negative) amount that transferred from the item into the block. - */ - public static @Nullable Tuple manualTrackedFluidHandlerInteraction(Level world, BlockPos pos, @Nullable Direction side, Player player, InteractionHand hand) { - if (world.isClientSide()) return null; - final ItemStack held = player.getItemInHand(hand); - if (held.isEmpty()) return null; - final IFluidHandler fh = handler(world, pos, side); - if (fh == null) return null; - final IItemHandler ih = player.getCapability(ForgeCapabilities.ITEM_HANDLER).orElse(null); - if (ih == null) return null; - FluidActionResult far = FluidUtil.tryFillContainerAndStow(held, fh, ih, Integer.MAX_VALUE, player, true); - if (!far.isSuccess()) far = FluidUtil.tryEmptyContainerAndStow(held, fh, ih, Integer.MAX_VALUE, player, true); - if (!far.isSuccess()) return null; - final ItemStack rstack = far.getResult().copy(); - player.setItemInHand(hand, far.getResult()); - final IFluidHandler fh_before = FluidUtil.getFluidHandler(held).orElse(null); - final IFluidHandler fh_after = FluidUtil.getFluidHandler(rstack).orElse(null); - if ((fh_before == null) || (fh_after == null) || (fh_after.getTanks() != fh_before.getTanks())) - return null; // should not be, but y'never know. - for (int i = 0; i < fh_before.getTanks(); ++i) { - final int vol_before = fh_before.getFluidInTank(i).getAmount(); - final int vol_after = fh_after.getFluidInTank(i).getAmount(); - if (vol_before != vol_after) { - return new Tuple<>( - (vol_before > 0) ? (fh_before.getFluidInTank(i).getFluid()) : (fh_after.getFluidInTank(i).getFluid()), - (vol_before - vol_after) - ); - } - } - return null; - } - - public static boolean manualFluidHandlerInteraction(Player player, InteractionHand hand, Level world, BlockPos pos, @Nullable Direction side) { - return FluidUtil.interactWithFluidHandler(player, hand, world, pos, side); - } - - public static int fill(Level world, BlockPos pos, Direction side, FluidStack fs, FluidAction action) { - IFluidHandler fh = FluidUtil.getFluidHandler(world, pos, side).orElse(null); - return (fh == null) ? (0) : (fh.fill(fs, action)); - } - - public static int fill(Level world, BlockPos pos, Direction side, FluidStack fs) { - return fill(world, pos, side, fs, FluidAction.EXECUTE); - } - - /** - * Fluid tank access when itemized. - */ - public static class FluidContainerItemCapabilityWrapper implements IFluidHandlerItem, ICapabilityProvider { - private final LazyOptional handler_ = LazyOptional.of(() -> this); - private final Function nbt_getter_; - private final BiConsumer nbt_setter_; - private final Predicate validator_; - private final ItemStack container_; - private final int capacity_; - private final int transfer_rate_; - - public FluidContainerItemCapabilityWrapper(ItemStack container, int capacity, int transfer_rate, - Function nbt_getter, - BiConsumer nbt_setter, - Predicate validator) { - container_ = container; - capacity_ = capacity; - transfer_rate_ = transfer_rate; - nbt_getter_ = nbt_getter; - nbt_setter_ = nbt_setter; - validator_ = (validator != null) ? validator : (e -> true); - } - - @Override - public LazyOptional getCapability(Capability capability, @Nullable Direction side) { - return (capability == ForgeCapabilities.FLUID_HANDLER) ? handler_.cast() : LazyOptional.empty(); - } - - protected FluidStack readnbt() { - final CompoundTag nbt = nbt_getter_.apply(container_); - return ((nbt == null) || (nbt.isEmpty())) ? FluidStack.EMPTY : FluidStack.loadFluidStackFromNBT(nbt); - } - - protected void writenbt(FluidStack fs) { - CompoundTag nbt = new CompoundTag(); - if (!fs.isEmpty()) fs.writeToNBT(nbt); - nbt_setter_.accept(container_, nbt); - } - - @Override - public ItemStack getContainer() { - return container_; - } - - @Override - public int getTanks() { - return 1; - } - - @Override - public FluidStack getFluidInTank(int tank) { - return readnbt(); - } - - @Override - public int getTankCapacity(int tank) { - return capacity_; - } - - @Override - public boolean isFluidValid(int tank, FluidStack fs) { - return isFluidValid(fs); - } - - public boolean isFluidValid(FluidStack fs) { - return validator_.test(fs); - } - - @Override - public int fill(FluidStack fs, FluidAction action) { - if ((fs.isEmpty()) || (!isFluidValid(fs) || (container_.getCount() != 1))) return 0; - FluidStack tank = readnbt(); - final int amount = Math.min(Math.min(fs.getAmount(), transfer_rate_), capacity_ - tank.getAmount()); - if (amount <= 0) return 0; - if (tank.isEmpty()) { - if (action.execute()) { - tank = new FluidStack(fs.getFluid(), amount, fs.getTag()); - writenbt(tank); - } - } else { - if (!tank.isFluidEqual(fs)) { - return 0; - } else if (action.execute()) { - tank.grow(amount); - writenbt(tank); - } - } - return amount; - } - - @Override - public FluidStack drain(FluidStack fs, FluidAction action) { - if ((fs.isEmpty()) || (container_.getCount() != 1)) return FluidStack.EMPTY; - final FluidStack tank = readnbt(); - if ((!tank.isEmpty()) && (!tank.isFluidEqual(fs))) return FluidStack.EMPTY; - return drain(fs.getAmount(), action); - } - - @Override - public FluidStack drain(int max, FluidAction action) { - if ((max <= 0) || (container_.getCount() != 1)) return FluidStack.EMPTY; - FluidStack tank = readnbt(); - if (tank.isEmpty()) return FluidStack.EMPTY; - final int amount = Math.min(Math.min(tank.getAmount(), max), transfer_rate_); - final FluidStack fs = tank.copy(); - fs.setAmount(amount); - if (action.execute()) { - tank.shrink(amount); - writenbt(tank); - } - return fs; - } - } - -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/Guis.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/Guis.java deleted file mode 100644 index 1374a19..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/Guis.java +++ /dev/null @@ -1,466 +0,0 @@ -/* - * @file Guis.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Gui Wrappers and Widgets. - */ -package dev.zontreck.libzontreck.edlibmc; - -import com.mojang.blaze3d.platform.Window; -import com.mojang.blaze3d.systems.RenderSystem; -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.components.AbstractWidget; -import net.minecraft.client.gui.narration.NarrationElementOutput; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; -import net.minecraft.client.renderer.GameRenderer; -import net.minecraft.client.renderer.entity.ItemRenderer; -import net.minecraft.client.sounds.SoundManager; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.Mth; -import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.item.ItemStack; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import java.util.Arrays; -import java.util.function.Consumer; -import java.util.function.Function; - - -public class Guis { - // ------------------------------------------------------------------------------------------------------------------- - // Gui base - // ------------------------------------------------------------------------------------------------------------------- - - @OnlyIn(Dist.CLIENT) - public static abstract class ContainerGui extends AbstractContainerScreen { - protected final ResourceLocation background_image_; - protected final Player player_; - protected final Guis.BackgroundImage gui_background_; - protected final TooltipDisplay tooltip_ = new TooltipDisplay(); - - public ContainerGui(T menu, Inventory player_inv, Component title, String background_image, int width, int height) { - super(menu, player_inv, title); - this.background_image_ = new ResourceLocation(Auxiliaries.modid(), background_image); - this.player_ = player_inv.player; - this.imageWidth = width; - this.imageHeight = height; - gui_background_ = new Guis.BackgroundImage(background_image_, width, height, Coord2d.ORIGIN); - } - - public ContainerGui(T menu, Inventory player_inv, Component title, String background_image) { - super(menu, player_inv, title); - this.background_image_ = new ResourceLocation(Auxiliaries.modid(), background_image); - this.player_ = player_inv.player; - gui_background_ = new Guis.BackgroundImage(background_image_, imageWidth, imageHeight, Coord2d.ORIGIN); - } - - @Override - public void init() { - super.init(); - gui_background_.init(this, Coord2d.ORIGIN).show(); - } - - @Override - public void render(GuiGraphics mx, int mouseX, int mouseY, float partialTicks) { - renderBackground(mx); - super.render(mx, mouseX, mouseY, partialTicks); - if (!tooltip_.render(mx, this, mouseX, mouseY)) renderTooltip(mx, mouseX, mouseY); - } - - @Override - protected void renderLabels(GuiGraphics mx, int x, int y) { - } - - @Override - @SuppressWarnings("deprecation") - protected final void renderBg(GuiGraphics mx, float partialTicks, int mouseX, int mouseY) { - RenderSystem.setShader(GameRenderer::getPositionTexShader); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.enableDepthTest(); - gui_background_.draw(mx, this); - renderBgWidgets(mx, partialTicks, mouseX, mouseY); - RenderSystem.disableBlend(); - } - - public final ResourceLocation getBackgroundImage() { - return background_image_; - } - - protected void renderBgWidgets(GuiGraphics mx, float partialTicks, int mouseX, int mouseY) { - } - - protected void renderItemTemplate(GuiGraphics mx, ItemStack stack, int x, int y) { - final int x0 = getGuiLeft(); - final int y0 = getGuiTop(); - - mx.renderFakeItem(stack, x0 + x, y0 + y); - RenderSystem.disableColorLogicOp(); //RenderSystem.disableColorMaterial(); - RenderSystem.enableDepthTest(); //RenderSystem.enableAlphaTest(); - RenderSystem.defaultBlendFunc(); - RenderSystem.enableBlend(); - RenderSystem.colorMask(true, true, true, true); - RenderSystem.setShaderColor(0.7f, 0.7f, 0.7f, 0.8f); - RenderSystem.setShaderTexture(0, background_image_); - mx.blit(background_image_,x0 + x, y0 + y, x, y, 16, 16); - RenderSystem.setShaderColor(1f, 1f, 1f, 1f); - } - } - - // ------------------------------------------------------------------------------------------------------------------- - // Gui elements - // ------------------------------------------------------------------------------------------------------------------- - - @OnlyIn(Dist.CLIENT) - public static class Coord2d { - public static final Coord2d ORIGIN = new Coord2d(0, 0); - public final int x, y; - - public Coord2d(int x, int y) { - this.x = x; - this.y = y; - } - - public static Coord2d of(int x, int y) { - return new Coord2d(x, y); - } - - public String toString() { - return "[" + x + "," + y + "]"; - } - } - - @OnlyIn(Dist.CLIENT) - public static class UiWidget extends AbstractWidget { - protected static final Component EMPTY_TEXT = Component.literal(""); - protected static final Function NO_TOOLTIP = (uiw) -> EMPTY_TEXT; - - private final Minecraft mc_; - private Function tooltip_ = NO_TOOLTIP; - private Screen parent_; - - public UiWidget(int x, int y, int width, int height, Component title) { - super(x, y, width, height, title); - mc_ = Minecraft.getInstance(); - } - - public UiWidget init(Screen parent) { - this.parent_ = parent; - this.setX(((parent instanceof AbstractContainerScreen) ? ((AbstractContainerScreen) parent).getGuiLeft() : 0)); - this.setY(((parent instanceof AbstractContainerScreen) ? ((AbstractContainerScreen) parent).getGuiTop() : 0)); - return this; - } - - public UiWidget init(Screen parent, Coord2d position) { - this.parent_ = parent; - this.setX(position.x + ((parent instanceof AbstractContainerScreen) ? ((AbstractContainerScreen) parent).getGuiLeft() : 0)); - this.setY(position.y + ((parent instanceof AbstractContainerScreen) ? ((AbstractContainerScreen) parent).getGuiTop() : 0)); - return this; - } - - public final UiWidget tooltip(Function tip) { - tooltip_ = tip; - return this; - } - - public final UiWidget tooltip(Component tip) { - tooltip_ = (o) -> tip; - return this; - } - - public final int getWidth() { - return this.width; - } - - @Override - protected void updateWidgetNarration(NarrationElementOutput narrationElementOutput) { - - } - - public final int getHeight() { - return this.height; - } - - public Coord2d getMousePosition() { - final Window win = mc_.getWindow(); - return Coord2d.of( - Mth.clamp(((int) (mc_.mouseHandler.xpos() * (double) win.getGuiScaledWidth() / (double) win.getScreenWidth())) - this.getX(), -1, this.width + 1), - Mth.clamp(((int) (mc_.mouseHandler.ypos() * (double) win.getGuiScaledHeight() / (double) win.getScreenHeight())) - this.getY(), -1, this.height + 1) - ); - } - - protected final Coord2d screenCoordinates(Coord2d xy, boolean reverse) { - return (reverse) ? (Coord2d.of(xy.x + getX(), xy.y + getY())) : (Coord2d.of(xy.x - getX(), xy.y - getY())); - } - - public UiWidget show() { - visible = true; - return this; - } - - public UiWidget hide() { - visible = false; - return this; - } - - @Override - public void renderWidget(GuiGraphics mxs, int mouseX, int mouseY, float partialTicks) { - //super.renderWidget(mxs, mouseX, mouseY, partialTicks); - if (isHovered) renderToolTip(mxs, mouseX, mouseY); - } - - @SuppressWarnings("all") - public void renderToolTip(GuiGraphics mx, int mouseX, int mouseY) { - if (!visible || (!active) || (tooltip_ == NO_TOOLTIP)) return; - final Component tip = tooltip_.apply(this); - if (tip.getString().trim().isEmpty()) return; - mx.renderTooltip(mc_.font, Arrays.asList(tip.getVisualOrderText()), mouseX, mouseY); - } - } - - @OnlyIn(Dist.CLIENT) - public static class HorizontalProgressBar extends UiWidget { - private final Coord2d texture_position_base_; - private final Coord2d texture_position_filled_; - private final ResourceLocation atlas_; - private double progress_max_ = 100; - private double progress_ = 0; - - public HorizontalProgressBar(ResourceLocation atlas, int width, int height, Coord2d base_texture_xy, Coord2d filled_texture_xy) { - super(0, 0, width, height, EMPTY_TEXT); - atlas_ = atlas; - texture_position_base_ = base_texture_xy; - texture_position_filled_ = filled_texture_xy; - } - - public HorizontalProgressBar setProgress(double progress) { - progress_ = Mth.clamp(progress, 0, progress_max_); - return this; - } - - public double getProgress() { - return progress_; - } - - public HorizontalProgressBar setMaxProgress(double progress) { - progress_max_ = Math.max(progress, 0); - return this; - } - - public double getMaxProgress() { - return progress_max_; - } - - public HorizontalProgressBar show() { - visible = true; - return this; - } - - public HorizontalProgressBar hide() { - visible = false; - return this; - } - - @Override - public void playDownSound(SoundManager handler) { - } - - @Override - public void renderWidget(GuiGraphics mxs, int mouseX, int mouseY, float partialTicks) { - RenderSystem.setShaderTexture(0, atlas_); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.enableDepthTest(); - mxs.blit(atlas_, getX(), getY(), texture_position_base_.x, texture_position_base_.y, width, height); - if ((progress_max_ > 0) && (progress_ > 0)) { - int w = Mth.clamp((int) Math.round((progress_ * width) / progress_max_), 0, width); - mxs.blit(atlas_, getX(), getY(), texture_position_filled_.x, texture_position_filled_.y, w, height); - } - if (isHovered) renderToolTip(mxs, mouseX, mouseY); - } - } - - @OnlyIn(Dist.CLIENT) - public static class BackgroundImage extends UiWidget { - private final ResourceLocation atlas_; - private final Coord2d atlas_position_; - public boolean visible; - - public BackgroundImage(ResourceLocation atlas, int width, int height, Coord2d atlas_position) { - super(0, 0, width, height, EMPTY_TEXT); - atlas_ = atlas; - atlas_position_ = atlas_position; - this.width = width; - this.height = height; - visible = true; - } - - public void draw(GuiGraphics mx, Screen parent) { - if (!visible) return; - RenderSystem.setShaderTexture(0, atlas_); - mx.blit(atlas_, getX(), getY(), atlas_position_.x, atlas_position_.y, width, height); - } - } - - @OnlyIn(Dist.CLIENT) - public static class CheckBox extends UiWidget { - private final Coord2d texture_position_off_; - private final Coord2d texture_position_on_; - private final ResourceLocation atlas_; - private boolean checked_ = false; - private Consumer on_click_ = (checkbox) -> { - }; - - public CheckBox(ResourceLocation atlas, int width, int height, Coord2d atlas_texture_position_off, Coord2d atlas_texture_position_on) { - super(0, 0, width, height, EMPTY_TEXT); - texture_position_off_ = atlas_texture_position_off; - texture_position_on_ = atlas_texture_position_on; - atlas_ = atlas; - } - - public boolean checked() { - return checked_; - } - - public CheckBox checked(boolean on) { - checked_ = on; - return this; - } - - public CheckBox onclick(Consumer action) { - on_click_ = action; - return this; - } - - @Override - public void onClick(double mouseX, double mouseY) { - checked_ = !checked_; - on_click_.accept(this); - } - - @Override - public void renderWidget(GuiGraphics mxs, int mouseX, int mouseY, float partialTicks) { - RenderSystem.setShader(GameRenderer::getPositionTexShader); - RenderSystem.setShaderTexture(0, atlas_); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.enableDepthTest(); - Coord2d pos = checked_ ? texture_position_on_ : texture_position_off_; - mxs.blit(atlas_, getX(), getY(), pos.x, pos.y, width, height); - if (isHovered) renderToolTip(mxs, mouseX, mouseY); - } - } - - @OnlyIn(Dist.CLIENT) - public static class ImageButton extends UiWidget { - private final Coord2d texture_position_; - private final ResourceLocation atlas_; - private Consumer on_click_ = (bt) -> { - }; - - - public ImageButton(ResourceLocation atlas, int width, int height, Coord2d atlas_texture_position) { - super(0, 0, width, height, Component.empty()); - texture_position_ = atlas_texture_position; - atlas_ = atlas; - } - - public ImageButton onclick(Consumer action) { - on_click_ = action; - return this; - } - - @Override - public void onClick(double mouseX, double mouseY) { - on_click_.accept(this); - } - - @Override - public void renderWidget(GuiGraphics mxs, int mouseX, int mouseY, float partialTicks) { - RenderSystem.setShader(GameRenderer::getPositionTexShader); - RenderSystem.setShaderTexture(0, atlas_); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.enableDepthTest(); - Coord2d pos = texture_position_; - mxs.blit(atlas_, getX(), getY(), pos.x, pos.y, width, height); - if (isHovered) renderToolTip(mxs, mouseX, mouseY); - } - } - - @OnlyIn(Dist.CLIENT) - public static class Image extends UiWidget { - private final Coord2d texture_position_; - private final ResourceLocation atlas_; - - public Image(ResourceLocation atlas, int width, int height, Coord2d atlas_texture_position) { - super(0, 0, width, height, Component.empty()); - texture_position_ = atlas_texture_position; - atlas_ = atlas; - } - - @Override - public void onClick(double mouseX, double mouseY) { - } - - @Override - public void renderWidget(GuiGraphics mxs, int mouseX, int mouseY, float partialTicks) { - RenderSystem.setShader(GameRenderer::getPositionTexShader); - RenderSystem.setShaderTexture(0, atlas_); - RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, this.alpha); - RenderSystem.enableBlend(); - RenderSystem.defaultBlendFunc(); - RenderSystem.enableDepthTest(); - Coord2d pos = texture_position_; - mxs.blit(atlas_, getX(), getY(), pos.x, pos.y, width, height); - if (isHovered) renderToolTip(mxs, mouseX, mouseY); - } - } - - @OnlyIn(Dist.CLIENT) - public static class TextBox extends net.minecraft.client.gui.components.EditBox { - public TextBox(int x, int y, int width, int height, Component title, Font font) { - super(font, x, y, width, height, title); - setBordered(false); - } - - public TextBox withMaxLength(int len) { - super.setMaxLength(len); - return this; - } - - public TextBox withBordered(boolean b) { - super.setBordered(b); - return this; - } - - public TextBox withValue(String s) { - super.setValue(s); - return this; - } - - public TextBox withEditable(boolean e) { - super.setEditable(e); - return this; - } - - public TextBox withResponder(Consumer r) { - super.setResponder(r); - return this; - } - } -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/Inventories.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/Inventories.java deleted file mode 100644 index e7442e0..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/Inventories.java +++ /dev/null @@ -1,1134 +0,0 @@ -/* - * @file Inventories.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * General inventory item handling functionality. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.core.NonNullList; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.util.Mth; -import net.minecraft.world.*; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.entity.player.Inventory; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; -import net.minecraft.nbt.Tag; -import net.minecraftforge.common.capabilities.ForgeCapabilities; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.items.IItemHandler; -import net.minecraftforge.items.ItemHandlerHelper; -import net.minecraftforge.items.wrapper.InvWrapper; -import net.minecraftforge.items.wrapper.PlayerMainInvWrapper; -import net.minecraftforge.items.wrapper.SidedInvWrapper; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import java.util.*; -import java.util.function.BiConsumer; -import java.util.function.BiFunction; -import java.util.function.BiPredicate; -import java.util.function.Consumer; -import java.util.stream.Collectors; -import java.util.stream.IntStream; -import java.util.stream.Stream; - - -public class Inventories { - public static boolean areItemStacksIdentical(ItemStack a, ItemStack b) { - return (a.getItem() == b.getItem()) && ItemStack.isSameItemSameTags(a, b); - } - - public static boolean areItemStacksDifferent(ItemStack a, ItemStack b) { - return (a.getItem() != b.getItem()) || (!ItemStack.isSameItemSameTags(a, b)); - } - - public static IItemHandler itemhandler(Level world, BlockPos pos, @Nullable Direction side) { - BlockEntity te = world.getBlockEntity(pos); - if (te == null) return null; - IItemHandler ih = te.getCapability(ForgeCapabilities.ITEM_HANDLER, side).orElse(null); - if (ih != null) return ih; - if ((side != null) && (te instanceof WorldlyContainer)) return new SidedInvWrapper((WorldlyContainer) te, side); - if (te instanceof Container) return new InvWrapper((Container) te); - return null; - } - - public static IItemHandler itemhandler(Level world, BlockPos pos, @Nullable Direction side, boolean including_entities) { - IItemHandler ih = itemhandler(world, pos, side); - if (ih != null) return ih; - if (!including_entities) return null; - Entity entity = world.getEntitiesOfClass(Entity.class, new AABB(pos), (e) -> (e instanceof Container)).stream().findFirst().orElse(null); - return (entity == null) ? (null) : (itemhandler(entity, side)); - } - - public static IItemHandler itemhandler(Player player) { - return new PlayerMainInvWrapper(player.getInventory()); - } - - public static IItemHandler itemhandler(Entity entity) { - return itemhandler(entity, null); - } - - public static IItemHandler itemhandler(Entity entity, @Nullable Direction side) { - if (entity == null) return null; - final IItemHandler ih = entity.getCapability(ForgeCapabilities.ITEM_HANDLER, side).orElse(null); - if (ih != null) return ih; - if (entity instanceof Container container) return (new InvWrapper(container)); - return null; - } - - public static boolean insertionPossible(Level world, BlockPos pos, @Nullable Direction side, boolean including_entities) { - return itemhandler(world, pos, side, including_entities) != null; - } - - public static ItemStack insert(IItemHandler handler, ItemStack stack, boolean simulate) { - return ItemHandlerHelper.insertItemStacked(handler, stack, simulate); - } - - public static ItemStack insert(BlockEntity te, @Nullable Direction side, ItemStack stack, boolean simulate) { - if (te == null) return stack; - IItemHandler hnd = te.getCapability(ForgeCapabilities.ITEM_HANDLER, side).orElse(null); - if (hnd == null) { - if ((side != null) && (te instanceof WorldlyContainer)) { - hnd = new SidedInvWrapper((WorldlyContainer) te, side); - } else if (te instanceof Container) { - hnd = new InvWrapper((Container) te); - } - } - return (hnd == null) ? stack : insert(hnd, stack, simulate); - } - - public static ItemStack insert(Level world, BlockPos pos, @Nullable Direction side, ItemStack stack, boolean simulate, boolean including_entities) { - return insert(itemhandler(world, pos, side, including_entities), stack, simulate); - } - - public static ItemStack insert(Level world, BlockPos pos, @Nullable Direction side, ItemStack stack, boolean simulate) { - return insert(world, pos, side, stack, simulate, false); - } - - public static ItemStack extract(IItemHandler inventory, @Nullable ItemStack match, int amount, boolean simulate) { - if ((inventory == null) || (amount <= 0) || ((match != null) && (match.isEmpty()))) return ItemStack.EMPTY; - final int max = inventory.getSlots(); - ItemStack out_stack = ItemStack.EMPTY; - for (int i = 0; i < max; ++i) { - final ItemStack stack = inventory.getStackInSlot(i); - if (stack.isEmpty()) continue; - if (out_stack.isEmpty()) { - if ((match != null) && areItemStacksDifferent(stack, match)) continue; - out_stack = inventory.extractItem(i, amount, simulate); - } else if (areItemStacksIdentical(stack, out_stack)) { - ItemStack es = inventory.extractItem(i, (amount - out_stack.getCount()), simulate); - out_stack.grow(es.getCount()); - } - if (out_stack.getCount() >= amount) break; - } - return out_stack; - } - - private static ItemStack checked(ItemStack stack) { - return stack.isEmpty() ? ItemStack.EMPTY : stack; - } - - public static Container copyOf(Container src) { - final int size = src.getContainerSize(); - SimpleContainer dst = new SimpleContainer(size); - for (int i = 0; i < size; ++i) dst.setItem(i, src.getItem(i).copy()); - return dst; - } - - //-------------------------------------------------------------------------------------------------------------------- - - public static ItemStack insert(InventoryRange[] to_ranges, ItemStack stack) { - ItemStack remaining = stack.copy(); - for (InventoryRange range : to_ranges) { - remaining = range.insert(remaining, false, 0, false, true); - if (remaining.isEmpty()) return remaining; - } - return remaining; - } - - //-------------------------------------------------------------------------------------------------------------------- - - public static class MappedItemHandler implements IItemHandler { - private final BiPredicate extraction_predicate_; - private final BiPredicate insertion_predicate_; - private final BiConsumer insertion_notifier_; - private final BiConsumer extraction_notifier_; - private final List slot_map_; - private final Container inv_; - - public MappedItemHandler(Container inv, BiPredicate extraction_predicate, BiPredicate insertion_predicate, BiConsumer insertion_notifier, BiConsumer extraction_notifier) { - inv_ = inv; - extraction_predicate_ = extraction_predicate; - insertion_predicate_ = insertion_predicate; - insertion_notifier_ = insertion_notifier; - extraction_notifier_ = extraction_notifier; - slot_map_ = IntStream.range(0, inv.getContainerSize()).boxed().collect(Collectors.toList()); - } - - public MappedItemHandler(Container inv, List slot_map, BiPredicate extraction_predicate, BiPredicate insertion_predicate, BiConsumer insertion_notifier, BiConsumer extraction_notifier) { - inv_ = inv; - extraction_predicate_ = extraction_predicate; - insertion_predicate_ = insertion_predicate; - insertion_notifier_ = insertion_notifier; - extraction_notifier_ = extraction_notifier; - slot_map_ = slot_map; - } - - public MappedItemHandler(Container inv, List slot_map, BiPredicate extraction_predicate, BiPredicate insertion_predicate) { - this(inv, slot_map, extraction_predicate, insertion_predicate, (i, s) -> { - }, (i, s) -> { - }); - } - - public MappedItemHandler(Container inv, BiPredicate extraction_predicate, BiPredicate insertion_predicate) { - this(inv, IntStream.range(0, inv.getContainerSize()).boxed().collect(Collectors.toList()), extraction_predicate, insertion_predicate); - } - - public MappedItemHandler(Container inv) { - this(inv, (i, s) -> true, (i, s) -> true); - } - - @Override - public int hashCode() { - return inv_.hashCode(); - } - - @Override - public boolean equals(Object o) { - return (o == this) || ((o != null) && (getClass() == o.getClass()) && (inv_.equals(((MappedItemHandler) o).inv_))); - } - - // IItemHandler ----------------------------------------------------------------------------------------------- - - @Override - public int getSlots() { - return slot_map_.size(); - } - - @Override - @Nonnull - public ItemStack getStackInSlot(int slot) { - return (slot >= slot_map_.size()) ? ItemStack.EMPTY : inv_.getItem(slot_map_.get(slot)); - } - - @Override - public int getSlotLimit(int slot) { - return inv_.getMaxStackSize(); - } - - @Override - public boolean isItemValid(int slot, @Nonnull ItemStack stack) { - if (slot >= slot_map_.size()) return false; - slot = slot_map_.get(slot); - return insertion_predicate_.test(slot, stack) && inv_.canPlaceItem(slot, stack); - } - - @Override - @Nonnull - public ItemStack insertItem(int slot, @Nonnull ItemStack stack, boolean simulate) { - if (stack.isEmpty()) return ItemStack.EMPTY; - if (slot >= slot_map_.size()) return stack; - slot = slot_map_.get(slot); - if (!insertion_predicate_.test(slot, stack)) return stack; - if (!inv_.canPlaceItem(slot, stack)) return stack; - ItemStack sst = inv_.getItem(slot); - final int slot_limit = inv_.getMaxStackSize(); - if (!sst.isEmpty()) { - if (sst.getCount() >= Math.min(sst.getMaxStackSize(), slot_limit)) return stack; - if (!ItemHandlerHelper.canItemStacksStack(stack, sst)) return stack; - final int limit = Math.min(stack.getMaxStackSize(), slot_limit) - sst.getCount(); - if (stack.getCount() <= limit) { - if (!simulate) { - stack = stack.copy(); - stack.grow(sst.getCount()); - inv_.setItem(slot, stack); - inv_.setChanged(); - insertion_notifier_.accept(slot, sst); - } - return ItemStack.EMPTY; - } else { - stack = stack.copy(); - if (simulate) { - stack.shrink(limit); - } else { - final ItemStack diff = stack.split(limit); - sst.grow(diff.getCount()); - inv_.setItem(slot, sst); - inv_.setChanged(); - insertion_notifier_.accept(slot, diff); - } - return stack; - } - } else { - final int limit = Math.min(slot_limit, stack.getMaxStackSize()); - if (stack.getCount() >= limit) { - stack = stack.copy(); - final ItemStack ins = stack.split(limit); - if (!simulate) { - inv_.setItem(slot, ins); - inv_.setChanged(); - insertion_notifier_.accept(slot, ins.copy()); - } - if (stack.isEmpty()) { - stack = ItemStack.EMPTY; - } - return stack; - } else { - if (!simulate) { - inv_.setItem(slot, stack.copy()); - inv_.setChanged(); - insertion_notifier_.accept(slot, stack.copy()); - } - return ItemStack.EMPTY; - } - } - } - - @Override - public ItemStack extractItem(int slot, int amount, boolean simulate) { - if (amount <= 0) return ItemStack.EMPTY; - if (slot >= slot_map_.size()) return ItemStack.EMPTY; - slot = slot_map_.get(slot); - ItemStack stack = inv_.getItem(slot); - if (!extraction_predicate_.test(slot, stack)) return ItemStack.EMPTY; - if (simulate) { - stack = stack.copy(); - if (amount < stack.getCount()) stack.setCount(amount); - } else { - stack = inv_.removeItem(slot, Math.min(stack.getCount(), amount)); - inv_.setChanged(); - extraction_notifier_.accept(slot, stack.copy()); - } - return stack; - } - - // Factories -------------------------------------------------------------------------------------------- - - public static LazyOptional createGenericHandler(Container inv, BiPredicate extraction_predicate, BiPredicate insertion_predicate, BiConsumer insertion_notifier, BiConsumer extraction_notifier) { - return LazyOptional.of(() -> new MappedItemHandler(inv, extraction_predicate, insertion_predicate, insertion_notifier, extraction_notifier)); - } - - public static LazyOptional createGenericHandler(Container inv, BiPredicate extraction_predicate, BiPredicate insertion_predicate, BiConsumer insertion_notifier, BiConsumer extraction_notifier, List slot_map) { - return LazyOptional.of(() -> new MappedItemHandler(inv, slot_map, extraction_predicate, insertion_predicate, insertion_notifier, extraction_notifier)); - } - - public static LazyOptional createGenericHandler(Container inv, BiPredicate extraction_predicate, BiPredicate insertion_predicate, List slot_map) { - return LazyOptional.of(() -> new MappedItemHandler(inv, slot_map, extraction_predicate, insertion_predicate)); - } - - public static LazyOptional createGenericHandler(Container inv, BiPredicate extraction_predicate, BiPredicate insertion_predicate) { - return LazyOptional.of(() -> new MappedItemHandler(inv, extraction_predicate, insertion_predicate)); - } - - public static LazyOptional createGenericHandler(Container inv) { - return LazyOptional.of(() -> new MappedItemHandler(inv)); - } - - public static LazyOptional createExtractionHandler(Container inv, BiPredicate extraction_predicate, List slot_map) { - return LazyOptional.of(() -> new MappedItemHandler(inv, slot_map, extraction_predicate, (i, s) -> false)); - } - - public static LazyOptional createExtractionHandler(Container inv, BiPredicate extraction_predicate) { - return LazyOptional.of(() -> new MappedItemHandler(inv, extraction_predicate, (i, s) -> false)); - } - - public static LazyOptional createExtractionHandler(Container inv, Integer... slots) { - return LazyOptional.of(() -> new MappedItemHandler(inv, Arrays.asList(slots), (i, s) -> true, (i, s) -> false)); - } - - public static LazyOptional createExtractionHandler(Container inv) { - return LazyOptional.of(() -> new MappedItemHandler(inv, (i, s) -> true, (i, s) -> false)); - } - - public static LazyOptional createInsertionHandler(Container inv, BiPredicate insertion_predicate, List slot_map) { - return LazyOptional.of(() -> new MappedItemHandler(inv, slot_map, (i, s) -> false, insertion_predicate)); - } - - public static LazyOptional createInsertionHandler(Container inv, Integer... slots) { - return LazyOptional.of(() -> new MappedItemHandler(inv, Arrays.asList(slots), (i, s) -> false, (i, s) -> true)); - } - - public static LazyOptional createInsertionHandler(Container inv, BiPredicate insertion_predicate) { - return LazyOptional.of(() -> new MappedItemHandler(inv, (i, s) -> false, insertion_predicate)); - } - - public static LazyOptional createInsertionHandler(Container inv) { - return LazyOptional.of(() -> new MappedItemHandler(inv, (i, s) -> false, (i, s) -> true)); - } - } - - //-------------------------------------------------------------------------------------------------------------------- - - public static class InventoryRange implements Container, Iterable { - protected final Container inventory_; - protected final int offset_, size_, num_rows; - protected int max_stack_size_ = 64; - protected BiPredicate validator_ = (index, stack) -> true; - - public static InventoryRange fromPlayerHotbar(Player player) { - return new InventoryRange(player.getInventory(), 0, 9, 1); - } - - public static InventoryRange fromPlayerStorage(Player player) { - return new InventoryRange(player.getInventory(), 9, 27, 3); - } - - public static InventoryRange fromPlayerInventory(Player player) { - return new InventoryRange(player.getInventory(), 0, 36, 4); - } - - public InventoryRange(Container inventory, int offset, int size, int num_rows) { - this.inventory_ = inventory; - this.offset_ = Mth.clamp(offset, 0, inventory.getContainerSize() - 1); - this.size_ = Mth.clamp(size, 0, inventory.getContainerSize() - this.offset_); - this.num_rows = num_rows; - } - - public InventoryRange(Container inventory, int offset, int size) { - this(inventory, offset, size, 1); - } - - public InventoryRange(Container inventory) { - this(inventory, 0, inventory.getContainerSize(), 1); - } - - public final Container inventory() { - return inventory_; - } - - public final int size() { - return size_; - } - - public final int offset() { - return offset_; - } - - public final ItemStack get(int index) { - return inventory_.getItem(offset_ + index); - } - - public final void set(int index, ItemStack stack) { - inventory_.setItem(offset_ + index, stack); - } - - public final InventoryRange setValidator(BiPredicate validator) { - validator_ = validator; - return this; - } - - public final BiPredicate getValidator() { - return validator_; - } - - public final InventoryRange setMaxStackSize(int count) { - max_stack_size_ = Math.max(count, 1); - return this; - } - - // Container ------------------------------------------------------------------------------------------------------ - - @Override - public void clearContent() { - for (int i = 0; i < size_; ++i) setItem(i, ItemStack.EMPTY); - } - - @Override - public int getContainerSize() { - return size_; - } - - @Override - public boolean isEmpty() { - for (int i = 0; i < size_; ++i) - if (!inventory_.getItem(offset_ + i).isEmpty()) { - return false; - } - return true; - } - - @Override - public ItemStack getItem(int index) { - return inventory_.getItem(offset_ + index); - } - - @Override - public ItemStack removeItem(int index, int count) { - return inventory_.removeItem(offset_ + index, count); - } - - @Override - public ItemStack removeItemNoUpdate(int index) { - return inventory_.removeItemNoUpdate(offset_ + index); - } - - @Override - public void setItem(int index, ItemStack stack) { - inventory_.setItem(offset_ + index, stack); - } - - @Override - public int getMaxStackSize() { - return Math.min(max_stack_size_, inventory_.getMaxStackSize()); - } - - @Override - public void setChanged() { - inventory_.setChanged(); - } - - @Override - public boolean stillValid(Player player) { - return inventory_.stillValid(player); - } - - @Override - public void startOpen(Player player) { - inventory_.startOpen(player); - } - - @Override - public void stopOpen(Player player) { - inventory_.stopOpen(player); - } - - @Override - public boolean canPlaceItem(int index, ItemStack stack) { - return validator_.test(offset_ + index, stack) && inventory_.canPlaceItem(offset_ + index, stack); - } - - //------------------------------------------------------------------------------------------------------------------ - - /** - * Iterates using a function (slot, stack) -> bool until the function matches (returns true). - */ - public boolean iterate(BiPredicate fn) { - for (int i = 0; i < size_; ++i) { - if (fn.test(i, getItem(i))) { - return true; - } - } - return false; - } - - public boolean contains(ItemStack stack) { - for (int i = 0; i < size_; ++i) { - if (areItemStacksIdentical(stack, getItem(i))) { - return true; - } - } - return false; - } - - public int indexOf(ItemStack stack) { - for (int i = 0; i < size_; ++i) { - if (areItemStacksIdentical(stack, getItem(i))) { - return i; - } - } - return -1; - } - - public Optional find(BiFunction> fn) { - for (int i = 0; i < size_; ++i) { - Optional r = fn.apply(i, getItem(i)); - if (r.isPresent()) return r; - } - return Optional.empty(); - } - - public List collect(BiFunction> fn) { - List data = new ArrayList<>(); - for (int i = 0; i < size_; ++i) { - fn.apply(i, getItem(i)).ifPresent(data::add); - } - return data; - } - - public Stream stream() { - return java.util.stream.StreamSupport.stream(this.spliterator(), false); - } - - public Iterator iterator() { - return new InventoryRangeIterator(this); - } - - public static class InventoryRangeIterator implements Iterator { - private final InventoryRange parent_; - private int index = 0; - - public InventoryRangeIterator(InventoryRange range) { - parent_ = range; - } - - public boolean hasNext() { - return index < parent_.size_; - } - - public ItemStack next() { - if (index >= parent_.size_) throw new NoSuchElementException(); - return parent_.getItem(index++); - } - } - - //------------------------------------------------------------------------------------------------------------------ - - /** - * Returns the number of stacks that match the given stack with NBT. - */ - public int stackMatchCount(final ItemStack ref_stack) { - int n = 0; // ... std::accumulate() the old school way. - for (int i = 0; i < size_; ++i) { - if (areItemStacksIdentical(ref_stack, getItem(i))) ++n; - } - return n; - } - - public int totalMatchingItemCount(final ItemStack ref_stack) { - int n = 0; - for (int i = 0; i < size_; ++i) { - ItemStack stack = getItem(i); - if (areItemStacksIdentical(ref_stack, stack)) n += stack.getCount(); - } - return n; - } - - //------------------------------------------------------------------------------------------------------------------ - - /** - * Moves as much items from the stack to the slots in range [offset_, end_slot] of the inventory_, - * filling up existing stacks first, then (player inventory_ only) checks appropriate empty slots next - * to stacks that have that item already, and last uses any empty slot that can be found. - * Returns the stack that is still remaining in the referenced `stack`. - */ - public ItemStack insert(final ItemStack input_stack, boolean only_fillup, int limit, boolean reverse, boolean force_group_stacks) { - final ItemStack mvstack = input_stack.copy(); - //final int end_slot = offset_ + size; - if (mvstack.isEmpty()) return checked(mvstack); - int limit_left = (limit > 0) ? (Math.min(limit, mvstack.getMaxStackSize())) : (mvstack.getMaxStackSize()); - boolean[] matches = new boolean[size_]; - boolean[] empties = new boolean[size_]; - int num_matches = 0; - for (int i = 0; i < size_; ++i) { - final int sno = reverse ? (size_ - 1 - i) : (i); - final ItemStack stack = getItem(sno); - if (stack.isEmpty()) { - empties[sno] = true; - } else if (areItemStacksIdentical(stack, mvstack)) { - matches[sno] = true; - ++num_matches; - } - } - // first iteration: fillup existing stacks - for (int i = 0; i < size_; ++i) { - final int sno = reverse ? (size_ - 1 - i) : (i); - if ((empties[sno]) || (!matches[sno])) continue; - final ItemStack stack = getItem(sno); - int nmax = Math.min(limit_left, stack.getMaxStackSize() - stack.getCount()); - if (mvstack.getCount() <= nmax) { - stack.setCount(stack.getCount() + mvstack.getCount()); - setItem(sno, stack); - return ItemStack.EMPTY; - } else { - stack.grow(nmax); - mvstack.shrink(nmax); - setItem(sno, stack); - limit_left -= nmax; - } - } - if (only_fillup) return checked(mvstack); - if ((num_matches > 0) && ((force_group_stacks) || (inventory_ instanceof Inventory))) { - // second iteration: use appropriate empty slots, - // a) between - { - int insert_start = -1; - int insert_end = -1; - int i = 1; - for (; i < size_ - 1; ++i) { - final int sno = reverse ? (size_ - 1 - i) : (i); - if (insert_start < 0) { - if (matches[sno]) insert_start = sno; - } else if (matches[sno]) { - insert_end = sno; - } - } - for (i = insert_start; i < insert_end; ++i) { - final int sno = reverse ? (size_ - 1 - i) : (i); - if ((!empties[sno]) || (!canPlaceItem(sno, mvstack))) continue; - int nmax = Math.min(limit_left, mvstack.getCount()); - ItemStack moved = mvstack.copy(); - moved.setCount(nmax); - mvstack.shrink(nmax); - setItem(sno, moved); - return checked(mvstack); - } - } - // b) before/after - { - for (int i = 1; i < size_ - 1; ++i) { - final int sno = reverse ? (size_ - 1 - i) : (i); - if (!matches[sno]) continue; - int ii = (empties[sno - 1]) ? (sno - 1) : (empties[sno + 1] ? (sno + 1) : -1); - if ((ii >= 0) && (canPlaceItem(ii, mvstack))) { - int nmax = Math.min(limit_left, mvstack.getCount()); - ItemStack moved = mvstack.copy(); - moved.setCount(nmax); - mvstack.shrink(nmax); - setItem(ii, moved); - return checked(mvstack); - } - } - } - } - // third iteration: use any empty slots - for (int i = 0; i < size_; ++i) { - final int sno = reverse ? (size_ - 1 - i) : (i); - if ((!empties[sno]) || (!canPlaceItem(sno, mvstack))) continue; - int nmax = Math.min(limit_left, mvstack.getCount()); - ItemStack placed = mvstack.copy(); - placed.setCount(nmax); - mvstack.shrink(nmax); - setItem(sno, placed); - return checked(mvstack); - } - return checked(mvstack); - } - - public ItemStack insert(final ItemStack stack_to_move) { - return insert(stack_to_move, false, 0, false, true); - } - - public ItemStack insert(final int index, final ItemStack stack_to_move) { - if (stack_to_move.isEmpty()) return stack_to_move; - final ItemStack stack = getItem(index); - final int limit = Math.min(getMaxStackSize(), stack.getMaxStackSize()); - if (stack.isEmpty()) { - setItem(index, stack_to_move.copy()); - return ItemStack.EMPTY; - } else if ((stack.getCount() >= limit) || !areItemStacksIdentical(stack, stack_to_move)) { - return stack_to_move; - } else { - final int amount = Math.min(limit - stack.getCount(), stack_to_move.getCount()); - ItemStack remaining = stack_to_move.copy(); - remaining.shrink(amount); - stack.grow(amount); - return remaining.isEmpty() ? ItemStack.EMPTY : remaining; - } - } - - //------------------------------------------------------------------------------------------------------------------ - - /** - * Extracts maximum amount of items from the inventory_. - * The first non-empty stack defines the item. - */ - public ItemStack extract(int amount) { - return extract(amount, false); - } - - public ItemStack extract(int amount, boolean random) { - ItemStack out_stack = ItemStack.EMPTY; - int offset = random ? (int) (Math.random() * size_) : 0; - for (int k = 0; k < size_; ++k) { - int i = (offset + k) % size_; - final ItemStack stack = getItem(i); - if (stack.isEmpty()) continue; - if (out_stack.isEmpty()) { - if (stack.getCount() < amount) { - out_stack = stack; - setItem(i, ItemStack.EMPTY); - if (!out_stack.isStackable()) break; - amount -= out_stack.getCount(); - } else { - out_stack = stack.split(amount); - break; - } - } else if (areItemStacksIdentical(stack, out_stack)) { - if (stack.getCount() <= amount) { - out_stack.grow(stack.getCount()); - amount -= stack.getCount(); - setItem(i, ItemStack.EMPTY); - } else { - out_stack.grow(amount); - stack.shrink(amount); - if (stack.isEmpty()) setItem(i, ItemStack.EMPTY); - break; - } - } - } - if (!out_stack.isEmpty()) setChanged(); - return out_stack; - } - - /** - * Moves as much items from the slots in range [offset_, end_slot] of the inventory_ into a new stack. - * Implicitly shrinks the inventory_ stacks and the `request_stack`. - */ - public ItemStack extract(final ItemStack request_stack) { - if (request_stack.isEmpty()) return ItemStack.EMPTY; - List matches = new ArrayList<>(); - for (int i = 0; i < size_; ++i) { - final ItemStack stack = getItem(i); - if ((!stack.isEmpty()) && (areItemStacksIdentical(stack, request_stack))) { - if (stack.hasTag()) { - final CompoundTag nbt = stack.getOrCreateTag(); - int n = nbt.size(); - if ((n > 0) && (nbt.contains("Damage"))) --n; - if (n > 0) continue; - } - matches.add(stack); - } - } - matches.sort(Comparator.comparingInt(ItemStack::getCount)); - if (matches.isEmpty()) return ItemStack.EMPTY; - int n_left = request_stack.getCount(); - ItemStack fetched_stack = matches.get(0).split(n_left); - n_left -= fetched_stack.getCount(); - for (int i = 1; (i < matches.size()) && (n_left > 0); ++i) { - ItemStack stack = matches.get(i).split(n_left); - n_left -= stack.getCount(); - fetched_stack.grow(stack.getCount()); - } - return checked(fetched_stack); - } - - //------------------------------------------------------------------------------------------------------------------ - - /** - * Moves items from this inventory_ range to another. Returns true if something was moved - * (if the inventories should be marked dirty). - */ - public boolean move(int index, final InventoryRange target_range, boolean all_identical_stacks, boolean only_fillup, boolean reverse, boolean force_group_stacks) { - final ItemStack source_stack = getItem(index); - if (source_stack.isEmpty()) return false; - if (!all_identical_stacks) { - ItemStack remaining = target_range.insert(source_stack, only_fillup, 0, reverse, force_group_stacks); - setItem(index, remaining); - return (remaining.getCount() != source_stack.getCount()); - } else { - ItemStack remaining = source_stack.copy(); - setItem(index, ItemStack.EMPTY); - final ItemStack ref_stack = remaining.copy(); - ref_stack.setCount(ref_stack.getMaxStackSize()); - for (int i = size_; (i > 0) && (!remaining.isEmpty()); --i) { - remaining = target_range.insert(remaining, only_fillup, 0, reverse, force_group_stacks); - if (!remaining.isEmpty()) break; - remaining = this.extract(ref_stack); - } - if (!remaining.isEmpty()) { - setItem(index, remaining); // put back - } - return (remaining.getCount() != source_stack.getCount()); - } - } - - public boolean move(int index, final InventoryRange target_range) { - return move(index, target_range, false, false, false, true); - } - - /** - * Moves/clears the complete range to another range if possible. Returns true if something was moved - * (if the inventories should be marked dirty). - */ - public boolean move(final InventoryRange target_range, boolean only_fillup, boolean reverse, boolean force_group_stacks) { - boolean changed = false; - for (int i = 0; i < size_; ++i) - changed |= move(i, target_range, false, only_fillup, reverse, force_group_stacks); - return changed; - } - - public boolean move(final InventoryRange target_range, boolean only_fillup) { - return move(target_range, only_fillup, false, true); - } - - public boolean move(final InventoryRange target_range) { - return move(target_range, false, false, true); - } - - } - - //-------------------------------------------------------------------------------------------------------------------- - - public static class StorageInventory implements Container, Iterable { - protected final NonNullList stacks_; - protected final BlockEntity te_; - protected final int size_; - protected final int num_rows_; - protected int stack_limit_ = 64; - protected BiPredicate validator_ = (index, stack) -> true; - protected Consumer open_action_ = (player) -> { - }; - protected Consumer close_action_ = (player) -> { - }; - protected BiConsumer slot_set_action_ = (index, stack) -> { - }; - - public StorageInventory(BlockEntity te, int size) { - this(te, size, 1); - } - - public StorageInventory(BlockEntity te, int size, int num_rows) { - te_ = te; - size_ = Math.max(size, 1); - stacks_ = NonNullList.withSize(size_, ItemStack.EMPTY); - num_rows_ = Mth.clamp(num_rows, 1, size_); - } - - public CompoundTag save(CompoundTag nbt, String key) { - nbt.put(key, save(new CompoundTag(), false)); - return nbt; - } - - public CompoundTag save(CompoundTag nbt) { - return ContainerHelper.saveAllItems(nbt, stacks_); - } - - public CompoundTag save(CompoundTag nbt, boolean save_empty) { - return ContainerHelper.saveAllItems(nbt, stacks_, save_empty); - } - - public CompoundTag save(boolean save_empty) { - return save(new CompoundTag(), save_empty); - } - - public StorageInventory load(CompoundTag nbt, String key) { - if (!nbt.contains("key", Tag.TAG_COMPOUND)) { - stacks_.clear(); - return this; - } else { - return load(nbt.getCompound(key)); - } - } - - public StorageInventory load(CompoundTag nbt) { - stacks_.clear(); - ContainerHelper.loadAllItems(nbt, stacks_); - return this; - } - - public List stacks() { - return stacks_; - } - - public BlockEntity getBlockEntity() { - return te_; - } - - public StorageInventory setOpenAction(Consumer fn) { - open_action_ = fn; - return this; - } - - public StorageInventory setCloseAction(Consumer fn) { - close_action_ = fn; - return this; - } - - public StorageInventory setSlotChangeAction(BiConsumer fn) { - slot_set_action_ = fn; - return this; - } - - public StorageInventory setStackLimit(int max_slot_stack_size) { - stack_limit_ = Math.max(max_slot_stack_size, 1); - return this; - } - - public StorageInventory setValidator(BiPredicate validator) { - validator_ = validator; - return this; - } - - public BiPredicate getValidator() { - return validator_; - } - - // Iterable --------------------------------------------------------------------- - - public Iterator iterator() { - return stacks_.iterator(); - } - - public Stream stream() { - return stacks_.stream(); - } - - // Container ------------------------------------------------------------------------------ - - @Override - public int getContainerSize() { - return size_; - } - - @Override - public boolean isEmpty() { - for (ItemStack stack : stacks_) { - if (!stack.isEmpty()) return false; - } - return true; - } - - @Override - public ItemStack getItem(int index) { - return (index < size_) ? stacks_.get(index) : ItemStack.EMPTY; - } - - @Override - public ItemStack removeItem(int index, int count) { - return ContainerHelper.removeItem(stacks_, index, count); - } - - @Override - public ItemStack removeItemNoUpdate(int index) { - return ContainerHelper.takeItem(stacks_, index); - } - - @Override - public void setItem(int index, ItemStack stack) { - stacks_.set(index, stack); - if ((stack.getCount() != stacks_.get(index).getCount()) || !areItemStacksDifferent(stacks_.get(index), stack)) { - slot_set_action_.accept(index, stack); - } - } - - @Override - public int getMaxStackSize() { - return stack_limit_; - } - - @Override - public void setChanged() { - te_.setChanged(); - } - - @Override - public boolean stillValid(Player player) { - return ((te_.getLevel().getBlockEntity(te_.getBlockPos()) == te_)) && (te_.getBlockPos().distSqr(player.blockPosition()) < 64); - } - - @Override - public void startOpen(Player player) { - open_action_.accept(player); - } - - @Override - public void stopOpen(Player player) { - setChanged(); - close_action_.accept(player); - } - - @Override - public boolean canPlaceItem(int index, ItemStack stack) { - return validator_.test(index, stack); - } - - @Override - public void clearContent() { - stacks_.clear(); - setChanged(); - } - - } - - //-------------------------------------------------------------------------------------------------------------------- - - public static void give(Player entity, ItemStack stack) { - ItemHandlerHelper.giveItemToPlayer(entity, stack); - } - - public static void setItemInPlayerHand(Player player, InteractionHand hand, ItemStack stack) { - if (stack.isEmpty()) stack = ItemStack.EMPTY; - if (hand == InteractionHand.MAIN_HAND) { - player.getInventory().items.set(player.getInventory().selected, stack); - } else { - player.getInventory().offhand.set(0, stack); - } - } - - //-------------------------------------------------------------------------------------------------------------------- - - public static Container readNbtStacks(CompoundTag nbt, String key, Container target) { - NonNullList stacks = Inventories.readNbtStacks(nbt, key, target.getContainerSize()); - for (int i = 0; i < stacks.size(); ++i) target.setItem(i, stacks.get(i)); - return target; - } - - public static NonNullList readNbtStacks(CompoundTag nbt, String key, int size) { - NonNullList stacks = NonNullList.withSize(size, ItemStack.EMPTY); - if ((nbt == null) || (!nbt.contains(key, Tag.TAG_COMPOUND))) return stacks; - CompoundTag stacknbt = nbt.getCompound(key); - ContainerHelper.loadAllItems(stacknbt, stacks); - return stacks; - } - - public static NonNullList readNbtStacks(CompoundTag nbt, int size) { - NonNullList stacks = NonNullList.withSize(size, ItemStack.EMPTY); - if ((nbt == null) || (!nbt.contains("Items", Tag.TAG_LIST))) return stacks; - ContainerHelper.loadAllItems(nbt, stacks); - return stacks; - } - - public static CompoundTag writeNbtStacks(CompoundTag nbt, String key, NonNullList stacks, boolean omit_trailing_empty) { - CompoundTag stacknbt = new CompoundTag(); - if (omit_trailing_empty) { - for (int i = stacks.size() - 1; i >= 0; --i) { - if (!stacks.get(i).isEmpty()) break; - stacks.remove(i); - } - } - ContainerHelper.saveAllItems(stacknbt, stacks); - if (nbt == null) nbt = new CompoundTag(); - nbt.put(key, stacknbt); - return nbt; - } - - public static CompoundTag writeNbtStacks(CompoundTag nbt, String key, NonNullList stacks) { - return writeNbtStacks(nbt, key, stacks, false); - } - - //-------------------------------------------------------------------------------------------------------------------- - - public static void dropStack(Level world, Vec3 pos, ItemStack stack, Vec3 velocity, double position_noise, double velocity_noise) { - if (stack.isEmpty()) return; - if (position_noise > 0) { - position_noise = Math.min(position_noise, 0.8); - pos = pos.add( - position_noise * (world.getRandom().nextDouble() - .5), - position_noise * (world.getRandom().nextDouble() - .5), - position_noise * (world.getRandom().nextDouble() - .5) - ); - } - if (velocity_noise > 0) { - velocity_noise = Math.min(velocity_noise, 1.0); - velocity = velocity.add( - (velocity_noise) * (world.getRandom().nextDouble() - .5), - (velocity_noise) * (world.getRandom().nextDouble() - .5), - (velocity_noise) * (world.getRandom().nextDouble() - .5) - ); - } - ItemEntity e = new ItemEntity(world, pos.x, pos.y, pos.z, stack); - e.setDeltaMovement((float) velocity.x, (float) velocity.y, (float) velocity.z); - e.setDefaultPickUpDelay(); - world.addFreshEntity(e); - } - - public static void dropStack(Level world, Vec3 pos, ItemStack stack, Vec3 velocity) { - dropStack(world, pos, stack, velocity, 0.3, 0.2); - } - - public static void dropStack(Level world, Vec3 pos, ItemStack stack) { - dropStack(world, pos, stack, Vec3.ZERO, 0.3, 0.2); - } - -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/Networking.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/Networking.java deleted file mode 100644 index 67a3540..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/Networking.java +++ /dev/null @@ -1,409 +0,0 @@ -/* - * @file Networking.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Main client/server message handling. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.core.BlockPos; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.FriendlyByteBuf; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.server.level.ServerPlayer; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraftforge.common.util.FakePlayer; -import net.minecraftforge.network.NetworkDirection; -import net.minecraftforge.network.NetworkEvent; -import net.minecraftforge.network.NetworkRegistry; -import net.minecraftforge.network.simple.SimpleChannel; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Supplier; - - -public class Networking { - private static final String PROTOCOL = "1"; - private static SimpleChannel DEFAULT_CHANNEL; - - public static void init(String modid) { - DEFAULT_CHANNEL = NetworkRegistry.ChannelBuilder - .named(new ResourceLocation(modid, "default_ch")) - .clientAcceptedVersions(PROTOCOL::equals).serverAcceptedVersions(PROTOCOL::equals).networkProtocolVersion(() -> PROTOCOL) - .simpleChannel(); - int discr = -1; - DEFAULT_CHANNEL.registerMessage(++discr, PacketTileNotifyClientToServer.class, PacketTileNotifyClientToServer::compose, PacketTileNotifyClientToServer::parse, PacketTileNotifyClientToServer.Handler::handle); - DEFAULT_CHANNEL.registerMessage(++discr, PacketTileNotifyServerToClient.class, PacketTileNotifyServerToClient::compose, PacketTileNotifyServerToClient::parse, PacketTileNotifyServerToClient.Handler::handle); - DEFAULT_CHANNEL.registerMessage(++discr, PacketContainerSyncClientToServer.class, PacketContainerSyncClientToServer::compose, PacketContainerSyncClientToServer::parse, PacketContainerSyncClientToServer.Handler::handle); - DEFAULT_CHANNEL.registerMessage(++discr, PacketContainerSyncServerToClient.class, PacketContainerSyncServerToClient::compose, PacketContainerSyncServerToClient::parse, PacketContainerSyncServerToClient.Handler::handle); - DEFAULT_CHANNEL.registerMessage(++discr, PacketNbtNotifyClientToServer.class, PacketNbtNotifyClientToServer::compose, PacketNbtNotifyClientToServer::parse, PacketNbtNotifyClientToServer.Handler::handle); - DEFAULT_CHANNEL.registerMessage(++discr, PacketNbtNotifyServerToClient.class, PacketNbtNotifyServerToClient::compose, PacketNbtNotifyServerToClient::parse, PacketNbtNotifyServerToClient.Handler::handle); - DEFAULT_CHANNEL.registerMessage(++discr, OverlayTextMessage.class, OverlayTextMessage::compose, OverlayTextMessage::parse, OverlayTextMessage.Handler::handle); - } - - //-------------------------------------------------------------------------------------------------------------------- - // Tile entity notifications - //-------------------------------------------------------------------------------------------------------------------- - - public interface IPacketTileNotifyReceiver { - default void onServerPacketReceived(CompoundTag nbt) { - } - - default void onClientPacketReceived(Player player, CompoundTag nbt) { - } - } - - public static class PacketTileNotifyClientToServer { - CompoundTag nbt = null; - BlockPos pos = BlockPos.ZERO; - - public static void sendToServer(BlockPos pos, CompoundTag nbt) { - if ((pos != null) && (nbt != null)) - DEFAULT_CHANNEL.sendToServer(new PacketTileNotifyClientToServer(pos, nbt)); - } - - public static void sendToServer(BlockEntity te, CompoundTag nbt) { - if ((te != null) && (nbt != null)) - DEFAULT_CHANNEL.sendToServer(new PacketTileNotifyClientToServer(te, nbt)); - } - - public PacketTileNotifyClientToServer() { - } - - public PacketTileNotifyClientToServer(BlockPos pos, CompoundTag nbt) { - this.nbt = nbt; - this.pos = pos; - } - - public PacketTileNotifyClientToServer(BlockEntity te, CompoundTag nbt) { - this.nbt = nbt; - pos = te.getBlockPos(); - } - - public static PacketTileNotifyClientToServer parse(final FriendlyByteBuf buf) { - return new PacketTileNotifyClientToServer(buf.readBlockPos(), buf.readNbt()); - } - - public static void compose(final PacketTileNotifyClientToServer pkt, final FriendlyByteBuf buf) { - buf.writeBlockPos(pkt.pos); - buf.writeNbt(pkt.nbt); - } - - @SuppressWarnings("all") - public static class Handler { - public static void handle(final PacketTileNotifyClientToServer pkt, final Supplier ctx) { - ctx.get().enqueueWork(() -> { - Player player = ctx.get().getSender(); - if (player == null) return; - Level world = player.level(); - final BlockEntity te = world.getBlockEntity(pkt.pos); - if (!(te instanceof IPacketTileNotifyReceiver)) return; - ((IPacketTileNotifyReceiver) te).onClientPacketReceived(ctx.get().getSender(), pkt.nbt); - }); - ctx.get().setPacketHandled(true); - } - } - } - - public static class PacketTileNotifyServerToClient { - CompoundTag nbt = null; - BlockPos pos = BlockPos.ZERO; - - public static void sendToPlayer(Player player, BlockEntity te, CompoundTag nbt) { - if ((!(player instanceof ServerPlayer)) || (player instanceof FakePlayer) || (te == null) || (nbt == null)) - return; - DEFAULT_CHANNEL.sendTo(new PacketTileNotifyServerToClient(te, nbt), ((ServerPlayer) player).connection.connection, NetworkDirection.PLAY_TO_CLIENT); - } - - public static void sendToPlayers(BlockEntity te, CompoundTag nbt) { - if (te == null || te.getLevel() == null) return; - for (Player player : te.getLevel().players()) sendToPlayer(player, te, nbt); - } - - public PacketTileNotifyServerToClient() { - } - - public PacketTileNotifyServerToClient(BlockPos pos, CompoundTag nbt) { - this.nbt = nbt; - this.pos = pos; - } - - public PacketTileNotifyServerToClient(BlockEntity te, CompoundTag nbt) { - this.nbt = nbt; - pos = te.getBlockPos(); - } - - public static PacketTileNotifyServerToClient parse(final FriendlyByteBuf buf) { - return new PacketTileNotifyServerToClient(buf.readBlockPos(), buf.readNbt()); - } - - public static void compose(final PacketTileNotifyServerToClient pkt, final FriendlyByteBuf buf) { - buf.writeBlockPos(pkt.pos); - buf.writeNbt(pkt.nbt); - } - - public static class Handler { - public static void handle(final PacketTileNotifyServerToClient pkt, final Supplier ctx) { - ctx.get().enqueueWork(() -> { - Level world = SidedProxy.getWorldClientSide(); - if (world == null) return; - final BlockEntity te = world.getBlockEntity(pkt.pos); - if (!(te instanceof IPacketTileNotifyReceiver)) return; - ((IPacketTileNotifyReceiver) te).onServerPacketReceived(pkt.nbt); - }); - ctx.get().setPacketHandled(true); - } - } - } - - //-------------------------------------------------------------------------------------------------------------------- - // (GUI) Container synchronization - //-------------------------------------------------------------------------------------------------------------------- - - public interface INetworkSynchronisableContainer { - void onServerPacketReceived(int windowId, CompoundTag nbt); - - void onClientPacketReceived(int windowId, Player player, CompoundTag nbt); - } - - public static class PacketContainerSyncClientToServer { - int id = -1; - CompoundTag nbt = null; - - public static void sendToServer(int windowId, CompoundTag nbt) { - if (nbt != null) DEFAULT_CHANNEL.sendToServer(new PacketContainerSyncClientToServer(windowId, nbt)); - } - - public static void sendToServer(AbstractContainerMenu container, CompoundTag nbt) { - if (nbt != null) - DEFAULT_CHANNEL.sendToServer(new PacketContainerSyncClientToServer(container.containerId, nbt)); - } - - public PacketContainerSyncClientToServer() { - } - - public PacketContainerSyncClientToServer(int id, CompoundTag nbt) { - this.nbt = nbt; - this.id = id; - } - - public static PacketContainerSyncClientToServer parse(final FriendlyByteBuf buf) { - return new PacketContainerSyncClientToServer(buf.readInt(), buf.readNbt()); - } - - public static void compose(final PacketContainerSyncClientToServer pkt, final FriendlyByteBuf buf) { - buf.writeInt(pkt.id); - buf.writeNbt(pkt.nbt); - } - - public static class Handler { - public static void handle(final PacketContainerSyncClientToServer pkt, final Supplier ctx) { - ctx.get().enqueueWork(() -> { - Player player = ctx.get().getSender(); - if ((player == null) || !(player.containerMenu instanceof INetworkSynchronisableContainer)) return; - if (player.containerMenu.containerId != pkt.id) return; - ((INetworkSynchronisableContainer) player.containerMenu).onClientPacketReceived(pkt.id, player, pkt.nbt); - }); - ctx.get().setPacketHandled(true); - } - } - } - - public static class PacketContainerSyncServerToClient { - int id = -1; - CompoundTag nbt = null; - - public static void sendToPlayer(Player player, int windowId, CompoundTag nbt) { - if ((!(player instanceof ServerPlayer)) || (player instanceof FakePlayer) || (nbt == null)) return; - DEFAULT_CHANNEL.sendTo(new PacketContainerSyncServerToClient(windowId, nbt), ((ServerPlayer) player).connection.connection, NetworkDirection.PLAY_TO_CLIENT); - } - - public static void sendToPlayer(Player player, AbstractContainerMenu container, CompoundTag nbt) { - if ((!(player instanceof ServerPlayer)) || (player instanceof FakePlayer) || (nbt == null)) return; - DEFAULT_CHANNEL.sendTo(new PacketContainerSyncServerToClient(container.containerId, nbt), ((ServerPlayer) player).connection.connection, NetworkDirection.PLAY_TO_CLIENT); - } - - public static - void sendToListeners(Level world, C container, CompoundTag nbt) { - for (Player player : world.players()) { - if (player.containerMenu.containerId != container.containerId) continue; - sendToPlayer(player, container.containerId, nbt); - } - } - - public PacketContainerSyncServerToClient() { - } - - public PacketContainerSyncServerToClient(int id, CompoundTag nbt) { - this.nbt = nbt; - this.id = id; - } - - public static PacketContainerSyncServerToClient parse(final FriendlyByteBuf buf) { - return new PacketContainerSyncServerToClient(buf.readInt(), buf.readNbt()); - } - - public static void compose(final PacketContainerSyncServerToClient pkt, final FriendlyByteBuf buf) { - buf.writeInt(pkt.id); - buf.writeNbt(pkt.nbt); - } - - public static class Handler { - public static void handle(final PacketContainerSyncServerToClient pkt, final Supplier ctx) { - ctx.get().enqueueWork(() -> { - Player player = SidedProxy.getPlayerClientSide(); - if ((player == null) || !(player.containerMenu instanceof INetworkSynchronisableContainer)) return; - if (player.containerMenu.containerId != pkt.id) return; - ((INetworkSynchronisableContainer) player.containerMenu).onServerPacketReceived(pkt.id, pkt.nbt); - }); - ctx.get().setPacketHandled(true); - } - } - } - - //-------------------------------------------------------------------------------------------------------------------- - // World notifications - //-------------------------------------------------------------------------------------------------------------------- - - public static class PacketNbtNotifyClientToServer { - public static final Map> handlers = new HashMap<>(); - final CompoundTag nbt; - - public static void sendToServer(CompoundTag nbt) { - if (nbt != null) DEFAULT_CHANNEL.sendToServer(new PacketNbtNotifyClientToServer(nbt)); - } - - public PacketNbtNotifyClientToServer(CompoundTag nbt) { - this.nbt = nbt; - } - - public static PacketNbtNotifyClientToServer parse(final FriendlyByteBuf buf) { - return new PacketNbtNotifyClientToServer(buf.readNbt()); - } - - public static void compose(final PacketNbtNotifyClientToServer pkt, final FriendlyByteBuf buf) { - buf.writeNbt(pkt.nbt); - } - - public static class Handler { - public static void handle(final PacketNbtNotifyClientToServer pkt, final Supplier ctx) { - ctx.get().enqueueWork(() -> { - final ServerPlayer player = ctx.get().getSender(); - if (player == null) return; - final String hnd = pkt.nbt.getString("hnd"); - if (hnd.isEmpty()) return; - if (handlers.containsKey(hnd)) handlers.get(hnd).accept(player, pkt.nbt); - }); - ctx.get().setPacketHandled(true); - } - } - } - - public static class PacketNbtNotifyServerToClient { - public static final Map> handlers = new HashMap<>(); - final CompoundTag nbt; - - public static void sendToPlayer(Player player, CompoundTag nbt) { - if ((!(player instanceof ServerPlayer)) || (player instanceof FakePlayer) || (nbt == null)) return; - DEFAULT_CHANNEL.sendTo(new PacketNbtNotifyServerToClient(nbt), ((ServerPlayer) player).connection.connection, NetworkDirection.PLAY_TO_CLIENT); - } - - public static void sendToPlayers(Level world, CompoundTag nbt) { - for (Player player : world.players()) sendToPlayer(player, nbt); - } - - public PacketNbtNotifyServerToClient(CompoundTag nbt) { - this.nbt = nbt; - } - - public static PacketNbtNotifyServerToClient parse(final FriendlyByteBuf buf) { - return new PacketNbtNotifyServerToClient(buf.readNbt()); - } - - public static void compose(final PacketNbtNotifyServerToClient pkt, final FriendlyByteBuf buf) { - buf.writeNbt(pkt.nbt); - } - - public static class Handler { - public static void handle(final PacketNbtNotifyServerToClient pkt, final Supplier ctx) { - ctx.get().enqueueWork(() -> { - final String hnd = pkt.nbt.getString("hnd"); - if (hnd.isEmpty()) return; - if (handlers.containsKey(hnd)) handlers.get(hnd).accept(pkt.nbt); - }); - ctx.get().setPacketHandled(true); - } - } - } - - //-------------------------------------------------------------------------------------------------------------------- - // Main window GUI text message - //-------------------------------------------------------------------------------------------------------------------- - - public static class OverlayTextMessage { - public static final int DISPLAY_TIME_MS = 3000; - private static BiConsumer handler_ = null; - private final Component data_; - private int delay_ = DISPLAY_TIME_MS; - - private Component data() { - return data_; - } - - private int delay() { - return delay_; - } - - public static void setHandler(BiConsumer handler) { - if (handler_ == null) handler_ = handler; - } - - public static void sendToPlayer(Player player, Component message, int delay) { - if ((!(player instanceof ServerPlayer)) || (player instanceof FakePlayer) || Auxiliaries.isEmpty(message)) - return; - DEFAULT_CHANNEL.sendTo(new OverlayTextMessage(message, delay), ((ServerPlayer) player).connection.connection, NetworkDirection.PLAY_TO_CLIENT); - } - - public OverlayTextMessage() { - data_ = Component.translatable("[unset]"); - } - - public OverlayTextMessage(final Component tct, int delay) { - data_ = tct.copy(); - delay_ = delay; - } - - public static OverlayTextMessage parse(final FriendlyByteBuf buf) { - try { - return new OverlayTextMessage(buf.readComponent(), DISPLAY_TIME_MS); - } catch (Throwable e) { - return new OverlayTextMessage(Component.translatable("[incorrect translation]"), DISPLAY_TIME_MS); - } - } - - public static void compose(final OverlayTextMessage pkt, final FriendlyByteBuf buf) { - try { - buf.writeComponent(pkt.data()); - } catch (Throwable e) { - Auxiliaries.logger().error("OverlayTextMessage.toBytes() failed: " + e); - } - } - - public static class Handler { - public static void handle(final OverlayTextMessage pkt, final Supplier ctx) { - if (handler_ != null) ctx.get().enqueueWork(() -> handler_.accept(pkt.data(), pkt.delay())); - ctx.get().setPacketHandled(true); - } - } - } - -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/OptionalRecipeCondition.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/OptionalRecipeCondition.java deleted file mode 100644 index 681daff..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/OptionalRecipeCondition.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * @file OptionalRecipeCondition.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Recipe condition to enable opt'ing out JSON based recipes. - */ -package dev.zontreck.libzontreck.edlibmc; - -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.GsonHelper; -import net.minecraft.world.item.Item; -import net.minecraft.world.level.block.Block; -import net.minecraftforge.common.crafting.conditions.ICondition; -import net.minecraftforge.common.crafting.conditions.IConditionSerializer; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.IForgeRegistry; -import org.slf4j.Logger; - -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.List; -import java.util.function.Predicate; - - -public class OptionalRecipeCondition implements ICondition { - private static ResourceLocation NAME; - - private final List all_required; - private final List any_missing; - private final List all_required_tags; - private final List any_missing_tags; - private final @Nullable ResourceLocation result; - private final boolean result_is_tag; - private final boolean experimental; - - private static boolean with_experimental = false; - private static boolean without_recipes = false; - private static Predicate block_optouts = (block) -> false; - private static Predicate item_optouts = (item) -> false; - - public static void init(String modid, Logger logger) { - NAME = new ResourceLocation(modid, "optional"); - } - - public static void on_config(boolean enable_experimental, boolean disable_all_recipes, - Predicate block_optout_provider, - Predicate item_optout_provider) { - with_experimental = enable_experimental; - without_recipes = disable_all_recipes; - block_optouts = block_optout_provider; - item_optouts = item_optout_provider; - } - - public OptionalRecipeCondition(ResourceLocation result, List required, List missing, List required_tags, List missing_tags, boolean isexperimental, boolean result_is_tag) { - all_required = required; - any_missing = missing; - all_required_tags = required_tags; - any_missing_tags = missing_tags; - this.result = result; - this.result_is_tag = result_is_tag; - experimental = isexperimental; - } - - @Override - public ResourceLocation getID() { - return NAME; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("Optional recipe, all-required: ["); - for (ResourceLocation e : all_required) sb.append(e.toString()).append(","); - for (ResourceLocation e : all_required_tags) sb.append("#").append(e.toString()).append(","); - sb.delete(sb.length() - 1, sb.length()).append("], any-missing: ["); - for (ResourceLocation e : any_missing) sb.append(e.toString()).append(","); - for (ResourceLocation e : any_missing_tags) sb.append("#").append(e.toString()).append(","); - sb.delete(sb.length() - 1, sb.length()).append("]"); - if (experimental) sb.append(" EXPERIMENTAL"); - return sb.toString(); - } - - @Override - public boolean test(IContext context) { - if (without_recipes) return false; - if ((experimental) && (!with_experimental)) return false; - final IForgeRegistry item_registry = ForgeRegistries.ITEMS; - //final Collection item_tags = SerializationTags.getInstance().getOrEmpty(Registry.ITEM_REGISTRY).getAvailableTags(); - if (result != null) { - boolean item_registered = item_registry.containsKey(result); - if (!item_registered) return false; // required result not registered - if (item_optouts.test(item_registry.getValue(result))) return false; - if (ForgeRegistries.BLOCKS.containsKey(result) && block_optouts.test(ForgeRegistries.BLOCKS.getValue(result))) - return false; - } - if (!all_required.isEmpty()) { - for (ResourceLocation rl : all_required) { - if (!item_registry.containsKey(rl)) return false; - } - } - if (!all_required_tags.isEmpty()) { - for (ResourceLocation rl : all_required_tags) { - if (item_registry.tags().getTagNames().noneMatch(tk -> tk.location().equals(rl))) - return false; // if(!item_tags.contains(rl)) return false; - } - } - if (!any_missing.isEmpty()) { - for (ResourceLocation rl : any_missing) { - if (!item_registry.containsKey(rl)) return true; - } - return false; - } - if (!any_missing_tags.isEmpty()) { - for (ResourceLocation rl : any_missing_tags) { - if (item_registry.tags().getTagNames().noneMatch(tk -> tk.location().equals(rl))) - return true; // if(!item_tags.contains(rl)) return true; - } - return false; - } - return true; - } - - public static class Serializer implements IConditionSerializer { - public static final Serializer INSTANCE = new Serializer(); - - @Override - public ResourceLocation getID() { - return OptionalRecipeCondition.NAME; - } - - @Override - public void write(JsonObject json, OptionalRecipeCondition condition) { - JsonArray required = new JsonArray(); - JsonArray missing = new JsonArray(); - for (ResourceLocation e : condition.all_required) required.add(e.toString()); - for (ResourceLocation e : condition.any_missing) missing.add(e.toString()); - json.add("required", required); - json.add("missing", missing); - if (condition.result != null) { - json.addProperty("result", (condition.result_is_tag ? "#" : "") + condition.result); - } - } - - @Override - public OptionalRecipeCondition read(JsonObject json) { - List required = new ArrayList<>(); - List missing = new ArrayList<>(); - List required_tags = new ArrayList<>(); - List missing_tags = new ArrayList<>(); - ResourceLocation result = null; - boolean experimental = false; - boolean result_is_tag = false; - if (json.has("result")) { - String s = json.get("result").getAsString(); - if (s.startsWith("#")) { - result = new ResourceLocation(s.substring(1)); - result_is_tag = true; - } else { - result = new ResourceLocation(s); - } - } - if (json.has("required")) { - for (JsonElement e : GsonHelper.getAsJsonArray(json, "required")) { - String s = e.getAsString(); - if (s.startsWith("#")) { - required_tags.add(new ResourceLocation(s.substring(1))); - } else { - required.add(new ResourceLocation(s)); - } - } - } - if (json.has("missing")) { - for (JsonElement e : GsonHelper.getAsJsonArray(json, "missing")) { - String s = e.getAsString(); - if (s.startsWith("#")) { - missing_tags.add(new ResourceLocation(s.substring(1))); - } else { - missing.add(new ResourceLocation(s)); - } - } - } - if (json.has("experimental")) experimental = json.get("experimental").getAsBoolean(); - return new OptionalRecipeCondition(result, required, missing, required_tags, missing_tags, experimental, result_is_tag); - } - } -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/Overlay.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/Overlay.java deleted file mode 100644 index 43f71cc..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/Overlay.java +++ /dev/null @@ -1,165 +0,0 @@ -/* - * @file Overlay.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Renders status messages in one line. - */ -package dev.zontreck.libzontreck.edlibmc; - -import com.mojang.blaze3d.platform.Window; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.Font; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.screens.Screen; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.player.LocalPlayer; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.Component; -import net.minecraft.util.Mth; -import net.minecraft.util.Tuple; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.LightLayer; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; -import net.minecraftforge.fml.DistExecutor; - -import javax.annotation.Nullable; -import java.util.Optional; - - -public class Overlay { - public static void show(Player player, final Component message) { - Networking.OverlayTextMessage.sendToPlayer(player, message, 3000); - } - - public static void show(Player player, final Component message, int delay) { - Networking.OverlayTextMessage.sendToPlayer(player, message, delay); - } - - public static void show(BlockState state, BlockPos pos) { - show(state, pos, 100); - } - - public static void show(BlockState state, BlockPos pos, int displayTimeoutMs) { - DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> (() -> TextOverlayGui.show(state, pos, displayTimeoutMs))); - } // Only called when client side - - // ----------------------------------------------------------------------------- - // Client side handler - // ----------------------------------------------------------------------------- - - @OnlyIn(Dist.CLIENT) - public static class TextOverlayGui extends Screen { - public static final TextOverlayGui INSTANCE = new TextOverlayGui(); - private static final Component EMPTY_TEXT = Component.literal(""); - private static final BlockState EMPTY_STATE = null; - private static double overlay_y_ = 0.75; - private static int text_color_ = 0x00ffaa00; - private static int border_color_ = 0xaa333333; - private static int background_color1_ = 0xaa333333; - private static int background_color2_ = 0xaa444444; - private static long text_deadline_ = 0; - private static Component text_ = EMPTY_TEXT; - private static long state_deadline_ = 0; - private static @Nullable BlockState state_ = EMPTY_STATE; - private static BlockPos pos_ = BlockPos.ZERO; - - public static void on_config(double overlay_y) { - on_config(overlay_y, 0x00ffaa00, 0xaa333333, 0xaa333333, 0xaa444444); - } - - public static void on_config(double overlay_y, int text_color, int border_color, int background_color1, int background_color2) { - overlay_y_ = overlay_y; - text_color_ = text_color; - border_color_ = border_color; - background_color1_ = background_color1; - background_color2_ = background_color2; - } - - public static synchronized Component text() { - return text_; - } - - public static synchronized long deadline() { - return text_deadline_; - } - - public static synchronized void hide() { - text_deadline_ = 0; - text_ = EMPTY_TEXT; - } - - public static synchronized void show(Component s, int displayTimeoutMs) { - text_ = (s == null) ? (EMPTY_TEXT) : (s.copy()); - text_deadline_ = System.currentTimeMillis() + displayTimeoutMs; - } - - public static synchronized void show(String s, int displayTimeoutMs) { - text_ = ((s == null) || (s.isEmpty())) ? (EMPTY_TEXT) : (Component.literal(s)); - text_deadline_ = System.currentTimeMillis() + displayTimeoutMs; - } - - public static synchronized void show(BlockState state, BlockPos pos, int displayTimeoutMs) { - pos_ = new BlockPos(pos); - state_ = state; - state_deadline_ = System.currentTimeMillis() + displayTimeoutMs; - } - - private static synchronized Optional> state_pos() { - return ((state_deadline_ < System.currentTimeMillis()) || (state_ == EMPTY_STATE)) ? Optional.empty() : Optional.of(new Tuple<>(state_, pos_)); - } - - TextOverlayGui() { - super(Component.literal("")); - } - - public void onRenderGui(final GuiGraphics mxs) { - if (deadline() < System.currentTimeMillis()) return; - if (text() == EMPTY_TEXT) return; - String txt = text().getString(); - if (txt.isEmpty()) return; - final net.minecraft.client.Minecraft mc = net.minecraft.client.Minecraft.getInstance(); - final Window win = mc.getWindow(); - final Font fr = mc.font; - final boolean was_unicode = fr.isBidirectional(); - final int cx = win.getGuiScaledWidth() / 2; - final int cy = (int) (win.getGuiScaledHeight() * overlay_y_); - final int w = fr.width(txt); - final int h = fr.lineHeight; - mxs.fillGradient(cx - (w / 2) - 3, cy - 2, cx + (w / 2) + 2, cy + h + 2, 0xaa333333, 0xaa444444); - mxs.hLine(cx - (w / 2) - 3, cx + (w / 2) + 2, cy - 2, 0xaa333333); - mxs.hLine(cx - (w / 2) - 3, cx + (w / 2) + 2, cy + h + 2, 0xaa333333); - mxs.vLine(cx - (w / 2) - 3, cy - 2, cy + h + 2, 0xaa333333); - mxs.vLine(cx + (w / 2) + 2, cy - 2, cy + h + 2, 0xaa333333); - mxs.drawCenteredString(fr, text(), cx, cy + 1, 0x00ffaa00); - } - - @SuppressWarnings("deprecation") - public void onRenderWorldOverlay(final com.mojang.blaze3d.vertex.PoseStack mxs, final double partialTick) { - final Optional> sp = state_pos(); - if (sp.isEmpty()) return; - final ClientLevel world = Minecraft.getInstance().level; - final LocalPlayer player = Minecraft.getInstance().player; - if ((player == null) || (world == null)) return; - final BlockState state = sp.get().getA(); - final BlockPos pos = sp.get().getB(); - final int light = (world.hasChunkAt(pos)) ? LightTexture.pack(world.getBrightness(LightLayer.BLOCK, pos), world.getBrightness(LightLayer.SKY, pos)) : LightTexture.pack(15, 15); - final MultiBufferSource buffer = Minecraft.getInstance().renderBuffers().bufferSource(); - final double px = Mth.lerp(partialTick, player.xo, player.getX()); - final double py = Mth.lerp(partialTick, player.yo, player.getY()); - final double pz = Mth.lerp(partialTick, player.zo, player.getZ()); - mxs.pushPose(); - mxs.translate((pos.getX() - px), (pos.getY() - py - player.getEyeHeight()), (pos.getZ() - pz)); - Minecraft.getInstance().getBlockRenderer().renderSingleBlock(state, mxs, buffer, light, OverlayTexture.NO_OVERLAY); - mxs.popPose(); - } - - } - -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/README.md b/src/main/java/dev/zontreck/libzontreck/edlibmc/README.md deleted file mode 100644 index f4bf684..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Engineer's Decor LibMC -____________ - -As Engineer's Decor has been abandoned and discontinued, i've adopted the LibMC, and split the mod up among my various mods. Engineer's Decor blocks, and items, will now reside in Thresholds. \ No newline at end of file diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/Registries.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/Registries.java deleted file mode 100644 index 02542bc..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/Registries.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * @file Registries.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Common game registry handling. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.tags.TagKey; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.flag.FeatureFlagSet; -import net.minecraft.world.flag.FeatureFlags; -import net.minecraft.world.inventory.MenuType; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.Item; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.crafting.RecipeSerializer; -import net.minecraft.world.level.ItemLike; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraftforge.eventbus.api.IEventBus; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.ForgeRegistries; -import net.minecraftforge.registries.RegistryObject; - -import javax.annotation.Nonnull; -import java.util.*; -import java.util.function.BiFunction; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.stream.Collectors; - -public class Registries { - private static String modid = null; - private static String creative_tab_icon = ""; - private static CreativeModeTab creative_tab = null; - private static final Map> registered_block_tag_keys = new HashMap<>(); - private static final Map> registered_item_tag_keys = new HashMap<>(); - - private static final Map> registered_blocks = new HashMap<>(); - private static final Map> registered_items = new HashMap<>(); - private static final Map>> registered_block_entity_types = new HashMap<>(); - private static final Map>> registered_entity_types = new HashMap<>(); - private static final Map>> registered_menu_types = new HashMap<>(); - private static final Map>> recipe_serializers = new HashMap<>(); - private static final Map> registered_tabs = new HashMap<>(); - - public static final List> tabItems = new ArrayList<>(); - - - - private static DeferredRegister BLOCKS; - private static DeferredRegister ITEMS; - private static DeferredRegister TABS; - private static DeferredRegister> BLOCK_ENTITIES; - private static DeferredRegister> MENUS; - private static DeferredRegister> ENTITIES; - private static DeferredRegister> RECIPE_SERIALIZERS; - private static List> MOD_REGISTRIES; - - public static void init(String mod_id, String creative_tab_icon_item_name, IEventBus bus) { - modid = mod_id; - creative_tab_icon = creative_tab_icon_item_name; - BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, modid); - ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, modid); - BLOCK_ENTITIES = DeferredRegister.create(ForgeRegistries.BLOCK_ENTITY_TYPES, modid); - MENUS = DeferredRegister.create(ForgeRegistries.MENU_TYPES, modid); - ENTITIES = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, modid); - RECIPE_SERIALIZERS = DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, modid); - TABS = DeferredRegister.create(net.minecraft.core.registries.Registries.CREATIVE_MODE_TAB, modid); - - Consumer> consumer = (X)->{ - X.register(bus); - }; - - List.of(BLOCKS, ITEMS, BLOCK_ENTITIES, MENUS, ENTITIES, RECIPE_SERIALIZERS, TABS).forEach(consumer); - } - - // ------------------------------------------------------------------------------------------------------------- - - public static Block getBlock(String block_name) { - return registered_blocks.get(block_name).get(); - } - - public static RegistryObject withTab(RegistryObject item) - { - tabItems.add(item); - - return item; - } - - public static Item getItem(String name) { - return registered_items.get(name).get(); - } - - public static EntityType getEntityType(String name) { - return registered_entity_types.get(name).get(); - } - - public static BlockEntityType getBlockEntityType(String block_name) { - return registered_block_entity_types.get(block_name).get(); - } - - public static MenuType getMenuType(String name) { - return registered_menu_types.get(name).get(); - } - - public static RecipeSerializer getRecipeSerializer(String name) { - return recipe_serializers.get(name).get(); - } - - public static BlockEntityType getBlockEntityTypeOfBlock(String block_name) { - return getBlockEntityType("tet_" + block_name); - } - - public static BlockEntityType getBlockEntityTypeOfBlock(Block block) { - return getBlockEntityTypeOfBlock(ForgeRegistries.BLOCKS.getKey(block).getPath()); - } - - public static MenuType getMenuTypeOfBlock(String name) { - return getMenuType("ct_" + name); - } - - public static MenuType getMenuTypeOfBlock(Block block) { - return getMenuTypeOfBlock(ForgeRegistries.BLOCKS.getKey(block).getPath()); - } - - public static TagKey getBlockTagKey(String name) { - return registered_block_tag_keys.get(name); - } - - public static TagKey getItemTagKey(String name) { - return registered_item_tag_keys.get(name); - } - - // ------------------------------------------------------------------------------------------------------------- - - @Nonnull - public static List getRegisteredBlocks() { - return Collections.unmodifiableList(registered_blocks.values().stream().map(RegistryObject::get).toList()); - } - - @Nonnull - public static List getRegisteredItems() { - return Collections.unmodifiableList(registered_items.values().stream().map(RegistryObject::get).toList()); - } - - @Nonnull - public static List> getRegisteredBlockEntityTypes() { - return Collections.unmodifiableList(registered_block_entity_types.values().stream().map(RegistryObject::get).toList()); - } - - @Nonnull - public static List> getRegisteredEntityTypes() { - return Collections.unmodifiableList(registered_entity_types.values().stream().map(RegistryObject::get).toList()); - } - - // ------------------------------------------------------------------------------------------------------------- - - public static void addItem(String registry_name, Supplier supplier) { - registered_items.put(registry_name, withTab(ITEMS.register(registry_name, supplier))); - - } - - public static void addBlock(String registry_name, Supplier block_supplier) { - registered_blocks.put(registry_name, BLOCKS.register(registry_name, block_supplier)); - registered_items.put(registry_name, withTab(ITEMS.register(registry_name, () -> new BlockItem(registered_blocks.get(registry_name).get(), (new Item.Properties()))))); - } - - public static void addCreativeModeTab(String id, Component title, ItemStack icon) - { - registered_tabs.put(id, TABS.register(id, ()-> CreativeModeTab - .builder() - .icon(()->icon) - .title(title) - .withSearchBar() - - .displayItems((display, output) -> tabItems.forEach(it->output.accept(it.get()))) - - .build() - )); - } - - public static void addBlock(String registry_name, Supplier block_supplier, Supplier item_supplier) { - registered_blocks.put(registry_name, BLOCKS.register(registry_name, block_supplier)); - registered_items.put(registry_name, ITEMS.register(registry_name, item_supplier)); - } - - public static void addBlockEntityType(String registry_name, BlockEntityType.BlockEntitySupplier ctor, String... block_names) { - registered_block_entity_types.put(registry_name, BLOCK_ENTITIES.register(registry_name, () -> { - final Block[] blocks = Arrays.stream(block_names).map(s -> { - Block b = BLOCKS.getEntries().stream().filter((ro) -> ro.getId().getPath().equals(s)).findFirst().map(RegistryObject::get).orElse(null); - if (b == null) Auxiliaries.logError("registered_blocks does not encompass '" + s + "'"); - return b; - }).filter(Objects::nonNull).collect(Collectors.toList()).toArray(new Block[]{}); - return BlockEntityType.Builder.of(ctor, blocks).build(null); - })); - } - - public static > void addEntityType(String registry_name, Supplier> supplier) { - registered_entity_types.put(registry_name, ENTITIES.register(registry_name, supplier)); - } - - public static > void addMenuType(String registry_name, MenuType.MenuSupplier supplier, FeatureFlagSet flags) { - registered_menu_types.put(registry_name, MENUS.register(registry_name, () -> new MenuType<>(supplier, flags))); - } - - public static void addRecipeSerializer(String registry_name, Supplier> serializer_supplier) { - recipe_serializers.put(registry_name, RECIPE_SERIALIZERS.register(registry_name, serializer_supplier)); - } - - public static void addOptionalBlockTag(String tag_name, ResourceLocation... default_blocks) { - final Set> default_suppliers = new HashSet<>(); - for (ResourceLocation rl : default_blocks) default_suppliers.add(() -> ForgeRegistries.BLOCKS.getValue(rl)); - final TagKey key = ForgeRegistries.BLOCKS.tags().createOptionalTagKey(new ResourceLocation(modid, tag_name), default_suppliers); - registered_block_tag_keys.put(tag_name, key); - } - - public static void addOptionaItemTag(String tag_name, ResourceLocation... default_items) { - final Set> default_suppliers = new HashSet<>(); - for (ResourceLocation rl : default_items) default_suppliers.add(() -> ForgeRegistries.ITEMS.getValue(rl)); - final TagKey key = ForgeRegistries.ITEMS.tags().createOptionalTagKey(new ResourceLocation(modid, tag_name), default_suppliers); - registered_item_tag_keys.put(tag_name, key); - } - - // ------------------------------------------------------------------------------------------------------------- - - @Deprecated - /** - * This function is to be removed as it cannot add items to a tab anymore - */ - public static void addBlock(String registry_name, Supplier block_supplier, BiFunction item_builder) { - addBlock(registry_name, block_supplier, () -> item_builder.apply(registered_blocks.get(registry_name).get(), (new Item.Properties()))); - } - - public static void addBlock(String registry_name, Supplier block_supplier, BlockEntityType.BlockEntitySupplier block_entity_ctor) { - addBlock(registry_name, block_supplier); - addBlockEntityType("tet_" + registry_name, block_entity_ctor, registry_name); - } - - public static void addBlock(String registry_name, Supplier block_supplier, BiFunction item_builder, BlockEntityType.BlockEntitySupplier block_entity_ctor) { - addBlock(registry_name, block_supplier, item_builder); - addBlockEntityType("tet_" + registry_name, block_entity_ctor, registry_name); - } - - public static void addBlock(String registry_name, Supplier block_supplier, BiFunction item_builder, BlockEntityType.BlockEntitySupplier block_entity_ctor, MenuType.MenuSupplier menu_type_supplier, FeatureFlagSet menuFlags) { - addBlock(registry_name, block_supplier, item_builder); - addBlockEntityType("tet_" + registry_name, block_entity_ctor, registry_name); - addMenuType("ct_" + registry_name, menu_type_supplier, menuFlags); - } - - public static void addBlock(String registry_name, Supplier block_supplier, BlockEntityType.BlockEntitySupplier block_entity_ctor, MenuType.MenuSupplier menu_type_supplier, FeatureFlagSet menuFlags) { - addBlock(registry_name, block_supplier, block_entity_ctor); - addMenuType("ct_" + registry_name, menu_type_supplier, menuFlags); - } - -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/RfEnergy.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/RfEnergy.java deleted file mode 100644 index 8636926..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/RfEnergy.java +++ /dev/null @@ -1,180 +0,0 @@ -/* - * @file RfEnergy.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * General RF/FE energy handling functionality. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.util.Mth; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraftforge.common.capabilities.ForgeCapabilities; -import net.minecraftforge.common.util.LazyOptional; -import net.minecraftforge.energy.IEnergyStorage; - -import javax.annotation.Nullable; - -public class RfEnergy { - public static int feed(Level world, BlockPos pos, @Nullable Direction side, int rf_energy) { - final BlockEntity te = world.getBlockEntity(pos); - if (te == null) return 0; - final IEnergyStorage es = te.getCapability(ForgeCapabilities.ENERGY, side).orElse(null); - if (es == null) return 0; - return es.receiveEnergy(rf_energy, false); - } - - public static class Battery implements IEnergyStorage { - protected int capacity_; - protected int charge_rate_; - protected int discharge_rate_; - protected int energy_; - - public Battery(int capacity) { - this(capacity, capacity); - } - - public Battery(int capacity, int transfer_rate) { - this(capacity, transfer_rate, transfer_rate, 0); - } - - public Battery(int capacity, int charge_rate, int discharge_rate) { - this(capacity, charge_rate, discharge_rate, 0); - } - - public Battery(int capacity, int charge_rate, int discharge_rate, int energy) { - capacity_ = Math.max(capacity, 1); - charge_rate_ = Mth.clamp(charge_rate, 0, capacity_); - discharge_rate_ = Mth.clamp(discharge_rate, 0, capacity_); - energy_ = Mth.clamp(energy, 0, capacity_); - } - - // --------------------------------------------------------------------------------------------------- - - public Battery setMaxEnergyStored(int capacity) { - capacity_ = Math.max(capacity, 1); - return this; - } - - public Battery setEnergyStored(int energy) { - energy_ = Mth.clamp(energy, 0, capacity_); - return this; - } - - public Battery setChargeRate(int in_rate) { - charge_rate_ = Mth.clamp(in_rate, 0, capacity_); - return this; - } - - public Battery setDischargeRate(int out_rate) { - discharge_rate_ = Mth.clamp(out_rate, 0, capacity_); - return this; - } - - public int getChargeRate() { - return charge_rate_; - } - - public int getDischargeRate() { - return discharge_rate_; - } - - public boolean isEmpty() { - return energy_ <= 0; - } - - public boolean isFull() { - return energy_ >= capacity_; - } - - public int getSOC() { - return (int) Mth.clamp((100.0 * energy_ / capacity_ + .5), 0, 100); - } - - public int getComparatorOutput() { - return (int) Mth.clamp((15.0 * energy_ / capacity_ + .2), 0, 15); - } - - public boolean draw(int energy) { - if (energy_ < energy) return false; - energy_ -= energy; - return true; - } - - public boolean feed(int energy) { - energy_ = Math.min(energy_ + energy, capacity_); - return energy_ >= capacity_; - } - - public Battery clear() { - energy_ = 0; - return this; - } - - public Battery load(CompoundTag nbt, String key) { - setEnergyStored(nbt.getInt(key)); - return this; - } - - public Battery load(CompoundTag nbt) { - return load(nbt, "Energy"); - } - - public CompoundTag save(CompoundTag nbt, String key) { - nbt.putInt(key, energy_); - return nbt; - } - - public CompoundTag save(CompoundTag nbt) { - return save(nbt, "Energy"); - } - - public LazyOptional createEnergyHandler() { - return LazyOptional.of(() -> this); - } - - // IEnergyStorage ------------------------------------------------------------------------------------ - - @Override - public int receiveEnergy(int feed_energy, boolean simulate) { - if (!canReceive()) return 0; - int e = Math.min(Math.min(charge_rate_, feed_energy), capacity_ - energy_); - if (!simulate) energy_ += e; - return e; - } - - @Override - public int extractEnergy(int draw_energy, boolean simulate) { - if (!canExtract()) return 0; - int e = Math.min(Math.min(discharge_rate_, draw_energy), energy_); - if (!simulate) energy_ -= e; - return e; - } - - @Override - public int getEnergyStored() { - return energy_; - } - - @Override - public int getMaxEnergyStored() { - return capacity_; - } - - @Override - public boolean canExtract() { - return discharge_rate_ > 0; - } - - @Override - public boolean canReceive() { - return charge_rate_ > 0; - } - - } -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/RsSignals.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/RsSignals.java deleted file mode 100644 index 70509bd..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/RsSignals.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * @file RsSignals.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * General redstone signal related functionality. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.world.Container; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.state.BlockState; - -import javax.annotation.Nullable; - -public class RsSignals { - - public static boolean hasSignalConnector(BlockState state, BlockGetter world, BlockPos pos, @Nullable Direction realSide) { - return state.isSignalSource(); - } - - public static int fromContainer(@Nullable Container container) { - if (container == null) return 0; - final double max = container.getMaxStackSize(); - if (max <= 0) return 0; - boolean nonempty = false; - double fill_level = 0; - for (int i = 0; i < container.getContainerSize(); ++i) { - ItemStack stack = container.getItem(i); - if (stack.isEmpty() || (stack.getMaxStackSize() <= 0)) continue; - fill_level += ((double) stack.getCount()) / Math.min(max, stack.getMaxStackSize()); - nonempty = true; - } - fill_level /= container.getContainerSize(); - return (int) (Math.floor(fill_level * 14) + (nonempty ? 1 : 0)); // vanilla compliant calculation. - } - -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/SidedProxy.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/SidedProxy.java deleted file mode 100644 index ba5f04b..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/SidedProxy.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * @file SidedProxy.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * General client/server sidedness selection proxy. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.client.Minecraft; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import net.minecraftforge.fml.DistExecutor; - -import javax.annotation.Nullable; -import java.util.Optional; - -public class SidedProxy { - @Nullable - public static Player getPlayerClientSide() { - return proxy.getPlayerClientSide(); - } - - @Nullable - public static Level getWorldClientSide() { - return proxy.getWorldClientSide(); - } - - @Nullable - public static Minecraft mc() { - return proxy.mc(); - } - - public static Optional isCtrlDown() { - return proxy.isCtrlDown(); - } - - public static Optional isShiftDown() { - return proxy.isShiftDown(); - } - - public static Optional getClipboard() { - return proxy.getClipboard(); - } - - public static boolean setClipboard(String text) { - return proxy.setClipboard(text); - } - - // -------------------------------------------------------------------------------------------------------- - - private static final ISidedProxy proxy = DistExecutor.unsafeRunForDist(() -> ClientProxy::new, () -> ServerProxy::new); - - private interface ISidedProxy { - default @Nullable Player getPlayerClientSide() { - return null; - } - - default @Nullable Level getWorldClientSide() { - return null; - } - - default @Nullable Minecraft mc() { - return null; - } - - default Optional isCtrlDown() { - return Optional.empty(); - } - - default Optional isShiftDown() { - return Optional.empty(); - } - - default Optional getClipboard() { - return Optional.empty(); - } - - default boolean setClipboard(String text) { - return false; - } - } - - private static final class ClientProxy implements ISidedProxy { - public @Nullable Player getPlayerClientSide() { - return Minecraft.getInstance().player; - } - - public @Nullable Level getWorldClientSide() { - return Minecraft.getInstance().level; - } - - public @Nullable Minecraft mc() { - return Minecraft.getInstance(); - } - - public Optional isCtrlDown() { - return Optional.of(Auxiliaries.isCtrlDown()); - } - - public Optional isShiftDown() { - return Optional.of(Auxiliaries.isShiftDown()); - } - - public Optional getClipboard() { - return (mc() == null) ? Optional.empty() : Optional.of(net.minecraft.client.gui.font.TextFieldHelper.getClipboardContents(mc())); - } - - public boolean setClipboard(String text) { - if (mc() == null) { - return false; - } - net.minecraft.client.gui.font.TextFieldHelper.setClipboardContents(Minecraft.getInstance(), text); - return true; - } - } - - private static final class ServerProxy implements ISidedProxy { - } - -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/SlabSliceBlock.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/SlabSliceBlock.java deleted file mode 100644 index 40e3401..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/SlabSliceBlock.java +++ /dev/null @@ -1,228 +0,0 @@ -/* - * @file SlabSliceBlock.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Half slab ("slab slices") characteristics class. Actually - * it's now a quarter slab, but who cares. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.network.chat.Component; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.SpawnPlacements; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -public class SlabSliceBlock extends StandardBlocks.WaterLoggable implements StandardBlocks.IStandardBlock { - public static final IntegerProperty PARTS = IntegerProperty.create("parts", 0, 14); - - protected static final VoxelShape[] AABBs = { - Shapes.create(new AABB(0, 0. / 16, 0, 1, 2. / 16, 1)), - Shapes.create(new AABB(0, 0. / 16, 0, 1, 4. / 16, 1)), - Shapes.create(new AABB(0, 0. / 16, 0, 1, 6. / 16, 1)), - Shapes.create(new AABB(0, 0. / 16, 0, 1, 8. / 16, 1)), - Shapes.create(new AABB(0, 0. / 16, 0, 1, 10. / 16, 1)), - Shapes.create(new AABB(0, 0. / 16, 0, 1, 12. / 16, 1)), - Shapes.create(new AABB(0, 0. / 16, 0, 1, 14. / 16, 1)), - Shapes.create(new AABB(0, 0. / 16, 0, 1, 16. / 16, 1)), - Shapes.create(new AABB(0, 2. / 16, 0, 1, 16. / 16, 1)), - Shapes.create(new AABB(0, 4. / 16, 0, 1, 16. / 16, 1)), - Shapes.create(new AABB(0, 6. / 16, 0, 1, 16. / 16, 1)), - Shapes.create(new AABB(0, 8. / 16, 0, 1, 16. / 16, 1)), - Shapes.create(new AABB(0, 10. / 16, 0, 1, 16. / 16, 1)), - Shapes.create(new AABB(0, 12. / 16, 0, 1, 16. / 16, 1)), - Shapes.create(new AABB(0, 14. / 16, 0, 1, 16. / 16, 1)), - Shapes.create(new AABB(0, 0, 0, 1, 1, 1)) // <- with 4bit fill - }; - - protected static final int[] num_slabs_contained_in_parts_ = {1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0x1}; // <- with 4bit fill - private static boolean with_pickup = false; - - public static void on_config(boolean direct_slab_pickup) { - with_pickup = direct_slab_pickup; - } - - public SlabSliceBlock(long config, BlockBehaviour.Properties builder) { - super(config, builder); - } - - protected boolean is_cube(BlockState state) { - return state.getValue(PARTS) == 0x07; - } - - @Override - @OnlyIn(Dist.CLIENT) - public void appendHoverText(ItemStack stack, @Nullable BlockGetter world, List tooltip, TooltipFlag flag) { - if (!Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true)) return; - if (with_pickup) Auxiliaries.Tooltip.addInformation("engineersdecor.tooltip.slabpickup", tooltip); - } - - @Override - public RenderTypeHint getRenderTypeHint() { - return (((config & StandardBlocks.CFG_TRANSLUCENT) != 0) ? (RenderTypeHint.TRANSLUCENT) : (RenderTypeHint.CUTOUT)); - } - - @Override - public boolean isPossibleToRespawnInThis(BlockState p_279289_) { - return false; - } - - @Override - public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType entityType) { - return false; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter source, BlockPos pos, CollisionContext selectionContext) { - return AABBs[state.getValue(PARTS) & 0xf]; - } - - @Override - public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) { - return getShape(state, world, pos, selectionContext); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - builder.add(PARTS); - } - - @Override - @Nullable - public BlockState getStateForPlacement(BlockPlaceContext context) { - final BlockPos pos = context.getClickedPos(); - BlockState state = context.getLevel().getBlockState(pos); - if (state.getBlock() == this) { - int parts = state.getValue(PARTS); - if (parts == 7) return null; // -> is already a full block. - parts += (parts < 7) ? 1 : -1; - if (parts == 7) state = state.setValue(WATERLOGGED, false); - return state.setValue(PARTS, parts); - } else { - final Direction face = context.getClickedFace(); - final BlockState placement_state = super.getStateForPlacement(context); // fluid state - if (face == Direction.UP) return placement_state.setValue(PARTS, 0); - if (face == Direction.DOWN) return placement_state.setValue(PARTS, 14); - if (!face.getAxis().isHorizontal()) return placement_state; - final boolean isupper = ((context.getClickLocation().y() - context.getClickedPos().getY()) > 0.5); - return placement_state.setValue(PARTS, isupper ? 14 : 0); - } - } - - @Override - @SuppressWarnings("deprecation") - public boolean canBeReplaced(BlockState state, BlockPlaceContext context) { - if (context.getItemInHand().getItem() != this.asItem()) return false; - if (!context.replacingClickedOnBlock()) return true; - final Direction face = context.getClickedFace(); - final int parts = state.getValue(PARTS); - if (parts == 7) return false; - if ((face == Direction.UP) && (parts < 7)) return true; - if ((face == Direction.DOWN) && (parts > 7)) return true; - if (!face.getAxis().isHorizontal()) return false; - final boolean isupper = ((context.getClickLocation().y() - context.getClickedPos().getY()) > 0.5); - return isupper ? (parts == 0) : (parts == 1); - } - - @Override - @SuppressWarnings("deprecation") - public BlockState rotate(BlockState state, Rotation rot) { - return state; - } - - @Override - @SuppressWarnings("deprecation") - public BlockState mirror(BlockState state, Mirror mirrorIn) { - return state; - } - - @Override - public boolean hasDynamicDropList() { - return true; - } - - @Override - public List dropList(BlockState state, Level world, BlockEntity te, boolean explosion) { - return new ArrayList<>(Collections.singletonList(new ItemStack(this.asItem(), num_slabs_contained_in_parts_[state.getValue(PARTS) & 0xf]))); - } - - @Override - @SuppressWarnings("deprecation") - public void attack(BlockState state, Level world, BlockPos pos, Player player) { - if ((world.isClientSide) || (!with_pickup)) return; - final ItemStack stack = player.getMainHandItem(); - if (stack.isEmpty() || (Block.byItem(stack.getItem()) != this)) return; - if (stack.getCount() >= stack.getMaxStackSize()) return; - Vec3 lv = player.getLookAngle(); - Direction facing = Direction.getNearest((float) lv.x, (float) lv.y, (float) lv.z); - if ((facing != Direction.UP) && (facing != Direction.DOWN)) return; - if (state.getBlock() != this) return; - int parts = state.getValue(PARTS); - if ((facing == Direction.DOWN) && (parts <= 7)) { - if (parts > 0) { - world.setBlock(pos, state.setValue(PARTS, parts - 1), 3); - } else { - world.removeBlock(pos, false); - } - } else if ((facing == Direction.UP) && (parts >= 7)) { - if (parts < 14) { - world.setBlock(pos, state.setValue(PARTS, parts + 1), 3); - } else { - world.removeBlock(pos, false); - } - } else { - return; - } - if (!player.isCreative()) { - stack.grow(1); - if (player.getInventory() != null) player.getInventory().setChanged(); - } - SoundType st = this.getSoundType(state, world, pos, null); - world.playSound(player, pos, st.getPlaceSound(), SoundSource.BLOCKS, (st.getVolume() + 1f) / 2.5f, 0.9f * st.getPitch()); - } - - @Override - public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) { - return (state.getValue(PARTS) != 14) && (super.placeLiquid(world, pos, state, fluidState)); - } - - @Override - public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { - return (state.getValue(PARTS) != 14) && (super.canPlaceLiquid(world, pos, state, fluid)); - } - -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardBlocks.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardBlocks.java deleted file mode 100644 index 69343b1..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardBlocks.java +++ /dev/null @@ -1,698 +0,0 @@ -/* - * @file StandardBlocks.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Common functionality class for decor blocks. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.network.chat.Component; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.SpawnPlacements; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.SimpleWaterloggedBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.block.state.properties.DirectionProperty; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.material.PushReaction; -import net.minecraft.world.level.pathfinder.PathComputationType; -import net.minecraft.world.level.storage.loot.LootContext; -import net.minecraft.world.level.storage.loot.LootParams; -import net.minecraft.world.level.storage.loot.parameters.LootContextParams; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.shapes.BooleanOp; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import javax.annotation.Nullable; -import java.util.*; -import java.util.function.Function; -import java.util.function.Supplier; - - -@SuppressWarnings("deprecation") -public class StandardBlocks { - public static final long CFG_DEFAULT = 0x0000000000000000L; // no special config - public static final long CFG_CUTOUT = 0x0000000000000001L; // cutout rendering - public static final long CFG_MIPPED = 0x0000000000000002L; // cutout mipped rendering - public static final long CFG_TRANSLUCENT = 0x0000000000000004L; // indicates a block/pane is glass like (transparent, etc) - public static final long CFG_WATERLOGGABLE = 0x0000000000000008L; // The derived block extends IWaterLoggable - public static final long CFG_HORIZIONTAL = 0x0000000000000010L; // horizontal block, affects bounding box calculation at construction time and placement - public static final long CFG_LOOK_PLACEMENT = 0x0000000000000020L; // placed in direction the player is looking when placing. - public static final long CFG_FACING_PLACEMENT = 0x0000000000000040L; // placed on the facing the player has clicked. - public static final long CFG_OPPOSITE_PLACEMENT = 0x0000000000000080L; // placed placed in the opposite direction of the face the player clicked. - public static final long CFG_FLIP_PLACEMENT_IF_SAME = 0x0000000000000100L; // placement direction flipped if an instance of the same class was clicked - public static final long CFG_FLIP_PLACEMENT_SHIFTCLICK = 0x0000000000000200L; // placement direction flipped if player is sneaking - public static final long CFG_STRICT_CONNECTIONS = 0x0000000000000400L; // blocks do not connect to similar blocks around (implementation details may vary a bit) - public static final long CFG_AI_PASSABLE = 0x0000000000000800L; // does not block movement path for AI, needed for non-opaque blocks with collision shapes not thin at the bottom or one side. - - public interface IStandardBlock { - default long config() { - return 0; - } - - default boolean hasDynamicDropList() { - return false; - } - - default List dropList(BlockState state, Level world, @Nullable BlockEntity te, boolean explosion) { - return Collections.singletonList((!world.isClientSide()) ? (new ItemStack(state.getBlock().asItem())) : (ItemStack.EMPTY)); - } - - enum RenderTypeHint {SOLID, CUTOUT, CUTOUT_MIPPED, TRANSLUCENT, TRANSLUCENT_NO_CRUMBLING} - - default RenderTypeHint getRenderTypeHint() { - return getRenderTypeHint(config()); - } - - default RenderTypeHint getRenderTypeHint(long config) { - if ((config & CFG_CUTOUT) != 0) return RenderTypeHint.CUTOUT; - if ((config & CFG_MIPPED) != 0) return RenderTypeHint.CUTOUT_MIPPED; - if ((config & CFG_TRANSLUCENT) != 0) return RenderTypeHint.TRANSLUCENT; - return RenderTypeHint.SOLID; - } - } - - public static class BaseBlock extends Block implements IStandardBlock, SimpleWaterloggedBlock { - public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; - public final long config; - - public BaseBlock(long conf, BlockBehaviour.Properties properties) { - super(properties); - config = conf; - BlockState state = getStateDefinition().any(); - if ((conf & CFG_WATERLOGGABLE) != 0) state = state.setValue(WATERLOGGED, false); - registerDefaultState(state); - } - - @Override - public long config() { - return config; - } - - @Override - @OnlyIn(Dist.CLIENT) - public void appendHoverText(ItemStack stack, @Nullable BlockGetter world, List tooltip, TooltipFlag flag) { - Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); - } - - @Override - public RenderTypeHint getRenderTypeHint() { - return getRenderTypeHint(config); - } - - @Override - @SuppressWarnings("deprecation") - public boolean isPathfindable(BlockState state, BlockGetter world, BlockPos pos, PathComputationType type) { - return ((config & CFG_AI_PASSABLE) != 0) && (super.isPathfindable(state, world, pos, type)); - } - - public boolean hasSignalConnector(BlockState state, BlockGetter world, BlockPos pos, @Nullable Direction side) { - return state.isSignalSource(); - } - - @Override - @SuppressWarnings("deprecation") - public void onRemove(BlockState state, Level world, BlockPos pos, BlockState newState, boolean isMoving) { - final boolean rsup = (state.hasBlockEntity() && (state.getBlock() != newState.getBlock())); - super.onRemove(state, world, pos, newState, isMoving); - if (rsup) world.updateNeighbourForOutputSignal(pos, this); - } - - @Override - public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) { - return (((config & CFG_WATERLOGGABLE) == 0) || (!state.getValue(WATERLOGGED))) && super.propagatesSkylightDown(state, reader, pos); - } - - @Override - @SuppressWarnings("deprecation") - public FluidState getFluidState(BlockState state) { - return (((config & CFG_WATERLOGGABLE) != 0) && state.getValue(WATERLOGGED)) ? Fluids.WATER.getSource(false) : super.getFluidState(state); - } - - @Override - @SuppressWarnings("deprecation") - public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos) { - if (((config & CFG_WATERLOGGABLE) != 0) && (state.getValue(WATERLOGGED))) - world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); - return state; - } - - @Override // SimpleWaterloggedBlock - public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { - return ((config & CFG_WATERLOGGABLE) != 0) && SimpleWaterloggedBlock.super.canPlaceLiquid(world, pos, state, fluid); - } - - @Override // SimpleWaterloggedBlock - public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) { - return ((config & CFG_WATERLOGGABLE) != 0) && SimpleWaterloggedBlock.super.placeLiquid(world, pos, state, fluidState); - } - - @Override // SimpleWaterloggedBlock - public ItemStack pickupBlock(LevelAccessor world, BlockPos pos, BlockState state) { - return ((config & CFG_WATERLOGGABLE) != 0) ? (SimpleWaterloggedBlock.super.pickupBlock(world, pos, state)) : (ItemStack.EMPTY); - } - - @Override // SimpleWaterloggedBlock - public Optional getPickupSound() { - return ((config & CFG_WATERLOGGABLE) != 0) ? (SimpleWaterloggedBlock.super.getPickupSound()) : Optional.empty(); - } - } - - public static class Cutout extends BaseBlock implements IStandardBlock { - private final VoxelShape vshape; - - public Cutout(long conf, BlockBehaviour.Properties properties) { - this(conf, properties, Auxiliaries.getPixeledAABB(0, 0, 0, 16, 16, 16)); - } - - public Cutout(long conf, BlockBehaviour.Properties properties, AABB aabb) { - this(conf, properties, Shapes.create(aabb)); - } - - public Cutout(long conf, BlockBehaviour.Properties properties, AABB[] aabbs) { - this(conf, properties, Arrays.stream(aabbs).map(Shapes::create).reduce(Shapes.empty(), (shape, aabb) -> Shapes.joinUnoptimized(shape, aabb, BooleanOp.OR))); - } - - public Cutout(long conf, BlockBehaviour.Properties properties, VoxelShape voxel_shape) { - super(conf, properties); - vshape = voxel_shape; - } - - @Override - @SuppressWarnings("deprecation") - public VoxelShape getShape(BlockState state, BlockGetter source, BlockPos pos, CollisionContext selectionContext) { - return vshape; - } - - @Override - @SuppressWarnings("deprecation") - public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) { - return vshape; - } - - @Override - @Nullable - public BlockState getStateForPlacement(BlockPlaceContext context) { - BlockState state = super.getStateForPlacement(context); - if ((config & CFG_WATERLOGGABLE) != 0) { - FluidState fs = context.getLevel().getFluidState(context.getClickedPos()); - state = state.setValue(WATERLOGGED, fs.getType() == Fluids.WATER); - } - return state; - } - - - @Override - public boolean isPossibleToRespawnInThis(BlockState p_279289_) { - return false; - } - - @Override - @SuppressWarnings("deprecation") - public PushReaction getPistonPushReaction(BlockState state) { - return PushReaction.NORMAL; - } - - @Override - public boolean propagatesSkylightDown(BlockState state, BlockGetter reader, BlockPos pos) { - if ((config & CFG_WATERLOGGABLE) != 0) { - if (state.getValue(WATERLOGGED)) return false; - } - return super.propagatesSkylightDown(state, reader, pos); - } - - @Override - @SuppressWarnings("deprecation") - public FluidState getFluidState(BlockState state) { - if ((config & CFG_WATERLOGGABLE) != 0) { - return state.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(state); - } - return super.getFluidState(state); - } - - @Override - @SuppressWarnings("deprecation") - public BlockState updateShape(BlockState state, Direction facing, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos) { - if ((config & CFG_WATERLOGGABLE) != 0) { - if (state.getValue(WATERLOGGED)) - world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); - } - return state; - } - } - - public static class WaterLoggable extends Cutout implements IStandardBlock { - public WaterLoggable(long config, BlockBehaviour.Properties properties) { - super(config | CFG_WATERLOGGABLE, properties); - } - - public WaterLoggable(long config, BlockBehaviour.Properties properties, AABB aabb) { - super(config | CFG_WATERLOGGABLE, properties, aabb); - } - - public WaterLoggable(long config, BlockBehaviour.Properties properties, VoxelShape voxel_shape) { - super(config | CFG_WATERLOGGABLE, properties, voxel_shape); - } - - public WaterLoggable(long config, BlockBehaviour.Properties properties, AABB[] aabbs) { - super(config | CFG_WATERLOGGABLE, properties, aabbs); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - builder.add(WATERLOGGED); - } - } - - public static class Directed extends Cutout implements IStandardBlock { - public static final DirectionProperty FACING = BlockStateProperties.FACING; - protected final Map vshapes; - - public Directed(long config, BlockBehaviour.Properties properties, final Function, Map> shape_supplier) { - super(config, properties); - registerDefaultState(super.defaultBlockState().setValue(FACING, Direction.UP)); - vshapes = shape_supplier.apply(getStateDefinition().getPossibleStates()); - } - - public Directed(long config, BlockBehaviour.Properties properties, final Supplier> shape_supplier) { - this(config, properties, (states) -> { - final Map vshapes = new HashMap<>(); - final ArrayList indexed_shapes = shape_supplier.get(); - for (BlockState state : states) - vshapes.put(state, indexed_shapes.get(state.getValue(FACING).get3DDataValue())); - return vshapes; - }); - } - - public Directed(long config, BlockBehaviour.Properties properties, final AABB[] unrotatedAABBs) { - this(config, properties, (states) -> { - final boolean is_horizontal = ((config & CFG_HORIZIONTAL) != 0); - Map vshapes = new HashMap<>(); - for (BlockState state : states) { - vshapes.put(state, Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, state.getValue(FACING), is_horizontal))); - } - return vshapes; - }); - } - - public Directed(long config, BlockBehaviour.Properties properties, final AABB unrotatedAABB) { - this(config, properties, new AABB[]{unrotatedAABB}); - } - - - @Override - public boolean isPossibleToRespawnInThis(BlockState p_279289_) { - return false; - } - - @Override - public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType entityType) { - return false; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter source, BlockPos pos, CollisionContext selectionContext) { - return vshapes.get(state); - } - - @Override - public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) { - return getShape(state, world, pos, selectionContext); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - builder.add(FACING); - } - - @Override - @Nullable - public BlockState getStateForPlacement(BlockPlaceContext context) { - BlockState state = super.getStateForPlacement(context); - if (state == null) return null; - Direction facing = context.getClickedFace(); - if ((config & (CFG_HORIZIONTAL | CFG_LOOK_PLACEMENT)) == (CFG_HORIZIONTAL | CFG_LOOK_PLACEMENT)) { - // horizontal placement in direction the player is looking - facing = context.getHorizontalDirection(); - } else if ((config & (CFG_HORIZIONTAL | CFG_LOOK_PLACEMENT)) == (CFG_HORIZIONTAL)) { - // horizontal placement on a face - if (((facing == Direction.UP) || (facing == Direction.DOWN))) return null; - } else if ((config & CFG_LOOK_PLACEMENT) != 0) { - // placement in direction the player is looking, with up and down - facing = context.getNearestLookingDirection(); - } - if ((config & CFG_OPPOSITE_PLACEMENT) != 0) facing = facing.getOpposite(); - if (((config & CFG_FLIP_PLACEMENT_SHIFTCLICK) != 0) && (context.getPlayer() != null) && (context.getPlayer().isShiftKeyDown())) - facing = facing.getOpposite(); - return state.setValue(FACING, facing); - } - } - - public static class AxisAligned extends Cutout implements IStandardBlock { - public static final EnumProperty AXIS = BlockStateProperties.AXIS; - protected final ArrayList vshapes; - - public AxisAligned(long config, BlockBehaviour.Properties properties, final Supplier> shape_supplier) { - super(config, properties); - registerDefaultState(super.defaultBlockState().setValue(AXIS, Direction.Axis.X)); - vshapes = shape_supplier.get(); - } - - public AxisAligned(long config, BlockBehaviour.Properties properties, final AABB[] unrotatedAABBs) { - this(config, properties, () -> new ArrayList<>(Arrays.asList( - Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.EAST, false)), - Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.UP, false)), - Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, Direction.SOUTH, false)), - Shapes.block() - ))); - } - - public AxisAligned(long config, BlockBehaviour.Properties properties, final AABB unrotatedAABB) { - this(config, properties, new AABB[]{unrotatedAABB}); - } - - - @Override - public boolean isPossibleToRespawnInThis(BlockState p_279289_) { - return false; - } - - @Override - public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType entityType) { - return false; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter source, BlockPos pos, CollisionContext selectionContext) { - return vshapes.get((state.getValue(AXIS)).ordinal() & 0x3); - } - - @Override - public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) { - return getShape(state, world, pos, selectionContext); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - builder.add(AXIS); - } - - @Override - @Nullable - public BlockState getStateForPlacement(BlockPlaceContext context) { - Direction facing; - if ((config & CFG_LOOK_PLACEMENT) != 0) { - facing = context.getNearestLookingDirection(); - } else { - facing = context.getClickedFace(); - } - return super.getStateForPlacement(context).setValue(AXIS, facing.getAxis()); - } - - @Override - @SuppressWarnings("deprecation") - public BlockState rotate(BlockState state, Rotation rotation) { - switch (rotation) { - case CLOCKWISE_90: - case COUNTERCLOCKWISE_90: - switch (state.getValue(AXIS)) { - case X: - return state.setValue(AXIS, Direction.Axis.Z); - case Z: - return state.setValue(AXIS, Direction.Axis.X); - } - } - return state; - } - } - - public static class Horizontal extends Cutout implements IStandardBlock { - public static final DirectionProperty HORIZONTAL_FACING = BlockStateProperties.HORIZONTAL_FACING; - protected final Map vshapes; - protected final Map cshapes; - - public Horizontal(long config, BlockBehaviour.Properties properties, final Function, Map> shape_supplier) { - super(config | CFG_HORIZIONTAL, properties); - registerDefaultState(super.defaultBlockState().setValue(HORIZONTAL_FACING, Direction.NORTH)); - vshapes = shape_supplier.apply(getStateDefinition().getPossibleStates()); - cshapes = shape_supplier.apply(getStateDefinition().getPossibleStates()); - } - - public Horizontal(long config, BlockBehaviour.Properties properties, final Supplier> shape_supplier) { - this(config, properties, (states) -> { - final Map vshapes = new HashMap<>(); - final ArrayList indexed_shapes = shape_supplier.get(); - for (BlockState state : states) - vshapes.put(state, indexed_shapes.get(state.getValue(HORIZONTAL_FACING).get3DDataValue())); - return vshapes; - }); - } - - public Horizontal(long config, BlockBehaviour.Properties properties, final AABB unrotatedAABB) { - this(config, properties, new AABB[]{unrotatedAABB}); - } - - public Horizontal(long config, BlockBehaviour.Properties properties, final AABB[] unrotatedAABBs) { - this(config, properties, (states) -> { - Map vshapes = new HashMap<>(); - for (BlockState state : states) { - vshapes.put(state, Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(unrotatedAABBs, state.getValue(HORIZONTAL_FACING), true))); - } - return vshapes; - }); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - builder.add(HORIZONTAL_FACING); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter source, BlockPos pos, CollisionContext selectionContext) { - return vshapes.get(state); - } - - @Override - public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) { - return cshapes.get(state); - } - - @Override - @Nullable - public BlockState getStateForPlacement(BlockPlaceContext context) { - BlockState state = super.getStateForPlacement(context); - if (state == null) return null; - Direction facing = context.getClickedFace(); - if ((config & CFG_LOOK_PLACEMENT) != 0) { - // horizontal placement in direction the player is looking - facing = context.getHorizontalDirection(); - } else { - // horizontal placement on a face - facing = ((facing == Direction.UP) || (facing == Direction.DOWN)) ? (context.getHorizontalDirection()) : facing; - } - if ((config & CFG_OPPOSITE_PLACEMENT) != 0) facing = facing.getOpposite(); - if (((config & CFG_FLIP_PLACEMENT_SHIFTCLICK) != 0) && (context.getPlayer() != null) && (context.getPlayer().isShiftKeyDown())) - facing = facing.getOpposite(); - return state.setValue(HORIZONTAL_FACING, facing); - } - - @Override - @SuppressWarnings("deprecation") - public BlockState rotate(BlockState state, Rotation rot) { - return state.setValue(HORIZONTAL_FACING, rot.rotate(state.getValue(HORIZONTAL_FACING))); - } - - @Override - @SuppressWarnings("deprecation") - public BlockState mirror(BlockState state, Mirror mirrorIn) { - return state.rotate(mirrorIn.getRotation(state.getValue(HORIZONTAL_FACING))); - } - } - - public static class DirectedWaterLoggable extends Directed implements IStandardBlock { - public DirectedWaterLoggable(long config, BlockBehaviour.Properties properties, AABB aabb) { - super(config | CFG_WATERLOGGABLE, properties, aabb); - } - - public DirectedWaterLoggable(long config, BlockBehaviour.Properties properties, AABB[] aabbs) { - super(config | CFG_WATERLOGGABLE, properties, aabbs); - } - - public DirectedWaterLoggable(long config, BlockBehaviour.Properties properties, final Function, Map> shape_supplier) { - super(config | CFG_WATERLOGGABLE, properties, shape_supplier); - } - - public DirectedWaterLoggable(long config, BlockBehaviour.Properties properties, final Supplier> shape_supplier) { - super(config | CFG_WATERLOGGABLE, properties, shape_supplier); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - builder.add(WATERLOGGED); - } - } - - public static class AxisAlignedWaterLoggable extends AxisAligned implements IStandardBlock { - public AxisAlignedWaterLoggable(long config, BlockBehaviour.Properties properties, AABB aabb) { - super(config | CFG_WATERLOGGABLE, properties, aabb); - } - - public AxisAlignedWaterLoggable(long config, BlockBehaviour.Properties properties, AABB[] aabbs) { - super(config | CFG_WATERLOGGABLE, properties, aabbs); - } - - public AxisAlignedWaterLoggable(long config, BlockBehaviour.Properties properties, final Supplier> shape_supplier) { - super(config | CFG_WATERLOGGABLE, properties, shape_supplier); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - builder.add(WATERLOGGED); - } - } - - public static class HorizontalWaterLoggable extends Horizontal implements IStandardBlock { - public HorizontalWaterLoggable(long config, BlockBehaviour.Properties properties, AABB aabb) { - super(config | CFG_WATERLOGGABLE | CFG_HORIZIONTAL, properties, aabb); - } - - public HorizontalWaterLoggable(long config, BlockBehaviour.Properties properties, AABB[] aabbs) { - super(config | CFG_WATERLOGGABLE | CFG_HORIZIONTAL, properties, aabbs); - } - - public HorizontalWaterLoggable(long config, BlockBehaviour.Properties properties, final Supplier> shape_supplier) { - super(config | CFG_WATERLOGGABLE | CFG_HORIZIONTAL, properties, shape_supplier); - } - - public HorizontalWaterLoggable(long config, BlockBehaviour.Properties properties, final Function, Map> shape_supplier) { - super(config | CFG_WATERLOGGABLE | CFG_HORIZIONTAL, properties, shape_supplier); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - builder.add(WATERLOGGED); - } - } - - static public class HorizontalFourWayWaterLoggable extends WaterLoggable implements IStandardBlock { - public static final BooleanProperty NORTH = BlockStateProperties.NORTH; - public static final BooleanProperty EAST = BlockStateProperties.EAST; - public static final BooleanProperty SOUTH = BlockStateProperties.SOUTH; - public static final BooleanProperty WEST = BlockStateProperties.WEST; - protected final Map shapes; - protected final Map collision_shapes; - - public HorizontalFourWayWaterLoggable(long config, BlockBehaviour.Properties properties, AABB base_aabb, final AABB[] side_aabb, int railing_height_extension) { - super(config, properties, base_aabb); - Map build_shapes = new HashMap<>(); - Map build_collision_shapes = new HashMap<>(); - for (BlockState state : getStateDefinition().getPossibleStates()) { - { - VoxelShape shape = ((base_aabb.getXsize() == 0) || (base_aabb.getYsize() == 0) || (base_aabb.getZsize() == 0)) ? Shapes.empty() : Shapes.create(base_aabb); - if (state.getValue(NORTH)) - shape = Shapes.joinUnoptimized(shape, Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(side_aabb, Direction.NORTH, true)), BooleanOp.OR); - if (state.getValue(EAST)) - shape = Shapes.joinUnoptimized(shape, Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(side_aabb, Direction.EAST, true)), BooleanOp.OR); - if (state.getValue(SOUTH)) - shape = Shapes.joinUnoptimized(shape, Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(side_aabb, Direction.SOUTH, true)), BooleanOp.OR); - if (state.getValue(WEST)) - shape = Shapes.joinUnoptimized(shape, Auxiliaries.getUnionShape(Auxiliaries.getRotatedAABB(side_aabb, Direction.WEST, true)), BooleanOp.OR); - if (shape.isEmpty()) shape = Shapes.block(); - build_shapes.put(state.setValue(WATERLOGGED, false), shape); - build_shapes.put(state.setValue(WATERLOGGED, true), shape); - } - { - // how the hack to extend a shape, these are the above with y+4px. - VoxelShape shape = ((base_aabb.getXsize() == 0) || (base_aabb.getYsize() == 0) || (base_aabb.getZsize() == 0)) ? Shapes.empty() : Shapes.create(base_aabb); - if (state.getValue(NORTH)) - shape = Shapes.joinUnoptimized(shape, Auxiliaries.getUnionShape(Auxiliaries.getMappedAABB(Auxiliaries.getRotatedAABB(side_aabb, - Direction.NORTH, true), bb -> bb.expandTowards(0, railing_height_extension, 0))), BooleanOp.OR); - if (state.getValue(EAST)) - shape = Shapes.joinUnoptimized(shape, Auxiliaries.getUnionShape(Auxiliaries.getMappedAABB(Auxiliaries.getRotatedAABB(side_aabb, - Direction.EAST, true), bb -> bb.expandTowards(0, railing_height_extension, 0))), BooleanOp.OR); - if (state.getValue(SOUTH)) - shape = Shapes.joinUnoptimized(shape, Auxiliaries.getUnionShape(Auxiliaries.getMappedAABB(Auxiliaries.getRotatedAABB(side_aabb, - Direction.SOUTH, true), bb -> bb.expandTowards(0, railing_height_extension, 0))), BooleanOp.OR); - if (state.getValue(WEST)) - shape = Shapes.joinUnoptimized(shape, Auxiliaries.getUnionShape(Auxiliaries.getMappedAABB(Auxiliaries.getRotatedAABB(side_aabb, - Direction.WEST, true), bb -> bb.expandTowards(0, railing_height_extension, 0))), BooleanOp.OR); - if (shape.isEmpty()) shape = Shapes.block(); - build_collision_shapes.put(state.setValue(WATERLOGGED, false), shape); - build_collision_shapes.put(state.setValue(WATERLOGGED, true), shape); - } - } - shapes = build_shapes; - collision_shapes = build_collision_shapes; - registerDefaultState(super.defaultBlockState().setValue(NORTH, false).setValue(EAST, false).setValue(SOUTH, false).setValue(WEST, false).setValue(WATERLOGGED, false)); - } - - public HorizontalFourWayWaterLoggable(long config, BlockBehaviour.Properties properties, AABB base_aabb, final AABB side_aabb, int railing_height_extension) { - this(config, properties, base_aabb, new AABB[]{side_aabb}, railing_height_extension); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - builder.add(NORTH, EAST, SOUTH, WEST); - } - - @Override - @Nullable - public BlockState getStateForPlacement(BlockPlaceContext context) { - return super.getStateForPlacement(context).setValue(NORTH, false).setValue(EAST, false).setValue(SOUTH, false).setValue(WEST, false); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { - return shapes.getOrDefault(state, Shapes.block()); - } - - @Override - public VoxelShape getCollisionShape(BlockState state, BlockGetter worldIn, BlockPos pos, CollisionContext context) { - return collision_shapes.getOrDefault(state, Shapes.block()); - } - - public static BooleanProperty getDirectionProperty(Direction face) { - return switch (face) { - case EAST -> HorizontalFourWayWaterLoggable.EAST; - case SOUTH -> HorizontalFourWayWaterLoggable.SOUTH; - case WEST -> HorizontalFourWayWaterLoggable.WEST; - default -> HorizontalFourWayWaterLoggable.NORTH; - }; - } - } - -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardDoorBlock.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardDoorBlock.java deleted file mode 100644 index 8c7f10b..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardDoorBlock.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * @file StandardDoorBlock.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Door blocks, almost entirely based on vanilla. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.network.chat.Component; -import net.minecraft.sounds.SoundEvent; -import net.minecraft.sounds.SoundEvents; -import net.minecraft.sounds.SoundSource; -import net.minecraft.world.InteractionHand; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.SpawnPlacements; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.DoorBlock; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.properties.BlockSetType; -import net.minecraft.world.level.block.state.properties.DoorHingeSide; -import net.minecraft.world.level.block.state.properties.DoubleBlockHalf; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.shapes.BooleanOp; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import javax.annotation.Nullable; -import java.util.List; - - -public class StandardDoorBlock extends DoorBlock implements StandardBlocks.IStandardBlock { - private final long config_; - protected final VoxelShape[][][][] shapes_; - protected final SoundEvent open_sound_; - protected final SoundEvent close_sound_; - - public StandardDoorBlock(long config, BlockBehaviour.Properties properties, AABB[] open_aabbs_top, AABB[] open_aabbs_bottom, AABB[] closed_aabbs_top, AABB[] closed_aabbs_bottom, SoundEvent open_sound, SoundEvent close_sound, BlockSetType blockSetType) { - super(properties, blockSetType); - VoxelShape[][][][] shapes = new VoxelShape[Direction.values().length][2][2][2]; - for (Direction facing : Direction.values()) { - for (boolean open : new boolean[]{false, true}) { - for (DoubleBlockHalf half : new DoubleBlockHalf[]{DoubleBlockHalf.UPPER, DoubleBlockHalf.LOWER}) { - for (boolean hinge_right : new boolean[]{false, true}) { - VoxelShape shape = Shapes.empty(); - if (facing.getAxis() == Direction.Axis.Y) { - shape = Shapes.block(); - } else { - final AABB[] aabbs = (open) ? ((half == DoubleBlockHalf.UPPER) ? open_aabbs_top : open_aabbs_bottom) : ((half == DoubleBlockHalf.UPPER) ? closed_aabbs_top : closed_aabbs_bottom); - for (AABB e : aabbs) { - AABB aabb = Auxiliaries.getRotatedAABB(e, facing, true); - if (!hinge_right) - aabb = Auxiliaries.getMirroredAABB(aabb, facing.getClockWise().getAxis()); - shape = Shapes.join(shape, Shapes.create(aabb), BooleanOp.OR); - } - } - shapes[facing.ordinal()][open ? 1 : 0][hinge_right ? 1 : 0][half == DoubleBlockHalf.UPPER ? 0 : 1] = shape; - } - } - } - } - config_ = config; - shapes_ = shapes; - open_sound_ = open_sound; - close_sound_ = close_sound; - } - - public StandardDoorBlock(long config, BlockBehaviour.Properties properties, AABB open_aabb, AABB closed_aabb, SoundEvent open_sound, SoundEvent close_sound, BlockSetType blockSetType) { - this(config, properties, new AABB[]{open_aabb}, new AABB[]{open_aabb}, new AABB[]{closed_aabb}, new AABB[]{closed_aabb}, open_sound, close_sound, blockSetType); - } - - public StandardDoorBlock(long config, BlockBehaviour.Properties properties, SoundEvent open_sound, SoundEvent close_sound, BlockSetType blockSetType) { - this( - config, properties, - Auxiliaries.getPixeledAABB(13, 0, 0, 16, 16, 16), - Auxiliaries.getPixeledAABB(0, 0, 13, 16, 16, 16), - open_sound, - close_sound, - blockSetType - ); - } - - public StandardDoorBlock(long config, BlockBehaviour.Properties properties) { - this( - config, properties, - Auxiliaries.getPixeledAABB(13, 0, 0, 16, 16, 16), - Auxiliaries.getPixeledAABB(0, 0, 13, 16, 16, 16), - SoundEvents.WOODEN_DOOR_OPEN, - SoundEvents.WOODEN_DOOR_CLOSE, - BlockSetType.OAK - ); - } - - @Override - public long config() { - return config_; - } - - protected void sound(BlockGetter world, BlockPos pos, boolean open) { - if (world instanceof Level) - ((Level) world).playSound(null, pos, open ? open_sound_ : close_sound_, SoundSource.BLOCKS, 0.7f, 1f); - } - - protected void actuate_adjacent_wing(BlockState state, BlockGetter world_ro, BlockPos pos, boolean open) { - if (!(world_ro instanceof final Level world)) return; - final BlockPos adjecent_pos = pos.relative((state.getValue(HINGE) == DoorHingeSide.LEFT) ? (state.getValue(FACING).getClockWise()) : (state.getValue(FACING).getCounterClockWise())); - if (!world.isLoaded(adjecent_pos)) return; - BlockState adjacent_state = world.getBlockState(adjecent_pos); - if (adjacent_state.getBlock() != this) return; - if (adjacent_state.getValue(OPEN) == open) return; - world.setBlock(adjecent_pos, adjacent_state.setValue(OPEN, open), 2 | 10); - } - - @Override - @OnlyIn(Dist.CLIENT) - public void appendHoverText(ItemStack stack, @Nullable BlockGetter world, List tooltip, TooltipFlag flag) { - Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); - } - - - @Override - public boolean isPossibleToRespawnInThis(BlockState p_279289_) { - return false; - } - - @Override - public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType entityType) { - return false; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext context) { - return shapes_[state.getValue(FACING).ordinal()][state.getValue(OPEN) ? 1 : 0][state.getValue(HINGE) == DoorHingeSide.RIGHT ? 1 : 0][state.getValue(HALF) == DoubleBlockHalf.UPPER ? 0 : 1]; - } - - @Override - public InteractionResult use(BlockState state, Level world, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hit) { - setOpen(player, world, state, pos, !state.getValue(OPEN)); - return InteractionResult.sidedSuccess(world.isClientSide()); - } - - @Override - public void neighborChanged(BlockState state, Level world, BlockPos pos, Block block, BlockPos fromPos, boolean isMoving) { - boolean powered = world.hasNeighborSignal(pos) || world.hasNeighborSignal(pos.relative(state.getValue(HALF) == DoubleBlockHalf.LOWER ? Direction.UP : Direction.DOWN)); - if ((block == this) || (powered == state.getValue(POWERED))) return; - world.setBlock(pos, state.setValue(POWERED, powered).setValue(OPEN, powered), 2); - actuate_adjacent_wing(state, world, pos, powered); - if (powered != state.getValue(OPEN)) sound(world, pos, powered); - } - - @Override - public void setOpen(@Nullable Entity entity, Level world, BlockState state, BlockPos pos, boolean open) { - if (!state.is(this) || (state.getValue(OPEN) == open)) return; - state = state.setValue(OPEN, open); - world.setBlock(pos, state, 2 | 8); - sound(world, pos, open); - actuate_adjacent_wing(state, world, pos, open); - } - -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardEntityBlocks.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardEntityBlocks.java deleted file mode 100644 index 78bf385..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardEntityBlocks.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * @file StandardEntityBlocks.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Common functionality class for blocks with block entities. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.core.BlockPos; -import net.minecraft.server.level.ServerLevel; -import net.minecraft.world.InteractionResult; -import net.minecraft.world.MenuProvider; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.block.EntityBlock; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.entity.BlockEntityTicker; -import net.minecraft.world.level.block.entity.BlockEntityType; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.gameevent.GameEventListener; -import net.minecraftforge.common.util.FakePlayer; - -import javax.annotation.Nullable; - - -public class StandardEntityBlocks { - public interface IStandardEntityBlock extends EntityBlock { - - default boolean isBlockEntityTicking(Level world, BlockState state) { - return false; - } - - default InteractionResult useOpenGui(BlockState state, Level world, BlockPos pos, Player player) { - if (world.isClientSide()) return InteractionResult.SUCCESS; - final BlockEntity te = world.getBlockEntity(pos); - if (!(te instanceof MenuProvider) || ((player instanceof FakePlayer))) return InteractionResult.FAIL; - player.openMenu((MenuProvider) te); - return InteractionResult.CONSUME; - } - - @Override - @Nullable - default BlockEntity newBlockEntity(BlockPos pos, BlockState state) { - BlockEntityType tet = Registries.getBlockEntityTypeOfBlock(state.getBlock()); - return (tet == null) ? null : tet.create(pos, state); - } - - @Override - @Nullable - default BlockEntityTicker getTicker(Level world, BlockState state, BlockEntityType te_type) { - return (world.isClientSide || (!isBlockEntityTicking(world, state))) ? (null) : ((Level w, BlockPos p, BlockState s, T te) -> ((StandardBlockEntity) te).tick()); - } - - @Override - @Nullable - default GameEventListener getListener(ServerLevel world, T te) { - return null; - } - } - - public static abstract class StandardBlockEntity extends BlockEntity { - public StandardBlockEntity(BlockEntityType type, BlockPos pos, BlockState state) { - super(type, pos, state); - } - - public void tick() { - } - } - -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardFenceBlock.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardFenceBlock.java deleted file mode 100644 index 0097d76..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardFenceBlock.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * @file StandardFenceBlock.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Wall blocks. - */ -package dev.zontreck.libzontreck.edlibmc; - -import com.google.common.collect.ImmutableMap; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.network.chat.Component; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.SpawnPlacements; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.FenceGateBlock; -import net.minecraft.world.level.block.WallBlock; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.BooleanProperty; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.block.state.properties.WallSide; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.material.PushReaction; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import javax.annotation.Nullable; -import java.util.List; -import java.util.Map; - - -public class StandardFenceBlock extends WallBlock implements StandardBlocks.IStandardBlock { - public static final BooleanProperty UP = BlockStateProperties.UP; - public static final EnumProperty WALL_EAST = BlockStateProperties.EAST_WALL; - public static final EnumProperty WALL_NORTH = BlockStateProperties.NORTH_WALL; - public static final EnumProperty WALL_SOUTH = BlockStateProperties.SOUTH_WALL; - public static final EnumProperty WALL_WEST = BlockStateProperties.WEST_WALL; - public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; - private final Map shape_voxels; - private final Map collision_shape_voxels; - private final long config; - - public StandardFenceBlock(long config, BlockBehaviour.Properties properties) { - this(config, properties, 1.5, 16, 1.5, 0, 14, 16); - } - - public StandardFenceBlock(long config, BlockBehaviour.Properties properties, double pole_width, double pole_height, double side_width, double side_min_y, double side_max_low_y, double side_max_tall_y) { - super(properties); - shape_voxels = buildShapes(pole_width, pole_height, side_width, side_min_y, side_max_low_y, side_max_tall_y); - collision_shape_voxels = buildShapes(pole_width, 24, pole_width, 0, 24, 24); - this.config = config; - } - - @Override - public long config() { - return config; - } - - @Override - @OnlyIn(Dist.CLIENT) - public void appendHoverText(ItemStack stack, @Nullable BlockGetter world, List tooltip, TooltipFlag flag) { - Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); - } - - private static VoxelShape combinedShape(VoxelShape pole, WallSide height, VoxelShape low, VoxelShape high) { - if (height == WallSide.TALL) return Shapes.or(pole, high); - if (height == WallSide.LOW) return Shapes.or(pole, low); - return pole; - } - - protected Map buildShapes(double pole_width, double pole_height, double side_width, double side_min_y, double side_max_low_y, double side_max_tall_y) { - final double px0 = 8.0 - pole_width, px1 = 8.0 + pole_width, sx0 = 8.0 - side_width, sx1 = 8.0 + side_width; - VoxelShape vp = Block.box(px0, 0, px0, px1, pole_height, px1); - VoxelShape vs1 = Block.box(sx0, side_min_y, 0, sx1, side_max_low_y, sx1); - VoxelShape vs2 = Block.box(sx0, side_min_y, sx0, sx1, side_max_low_y, 16); - VoxelShape vs3 = Block.box(0, side_min_y, sx0, sx1, side_max_low_y, sx1); - VoxelShape vs4 = Block.box(sx0, side_min_y, sx0, 16, side_max_low_y, sx1); - VoxelShape vs5 = Block.box(sx0, side_min_y, 0, sx1, side_max_tall_y, sx1); - VoxelShape vs6 = Block.box(sx0, side_min_y, sx0, sx1, side_max_tall_y, 16); - VoxelShape vs7 = Block.box(0, side_min_y, sx0, sx1, side_max_tall_y, sx1); - VoxelShape vs8 = Block.box(sx0, side_min_y, sx0, 16, side_max_tall_y, sx1); - ImmutableMap.Builder builder = ImmutableMap.builder(); - for (Boolean up : UP.getPossibleValues()) { - for (WallSide wh_east : WALL_EAST.getPossibleValues()) { - for (WallSide wh_north : WALL_NORTH.getPossibleValues()) { - for (WallSide wh_west : WALL_WEST.getPossibleValues()) { - for (WallSide wh_south : WALL_SOUTH.getPossibleValues()) { - VoxelShape shape = Shapes.empty(); - shape = combinedShape(shape, wh_east, vs4, vs8); - shape = combinedShape(shape, wh_west, vs3, vs7); - shape = combinedShape(shape, wh_north, vs1, vs5); - shape = combinedShape(shape, wh_south, vs2, vs6); - if (up) shape = Shapes.or(shape, vp); - BlockState bs = defaultBlockState().setValue(UP, up) - .setValue(WALL_EAST, wh_east) - .setValue(WALL_NORTH, wh_north) - .setValue(WALL_WEST, wh_west) - .setValue(WALL_SOUTH, wh_south); - builder.put(bs.setValue(WATERLOGGED, false), shape); - builder.put(bs.setValue(WATERLOGGED, true), shape); - } - } - } - } - } - return builder.build(); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) { - return shape_voxels.getOrDefault(state, Shapes.block()); - } - - @Override - public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) { - return collision_shape_voxels.getOrDefault(state, Shapes.block()); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - } - - protected boolean attachesTo(BlockState facingState, LevelReader world, BlockPos facingPos, Direction side) { - final Block block = facingState.getBlock(); - if ((block instanceof FenceGateBlock) || (block instanceof StandardFenceBlock) || (block instanceof VariantWallBlock)) - return true; - final BlockState oppositeState = world.getBlockState(facingPos.relative(side, 2)); - if (!(oppositeState.getBlock() instanceof StandardFenceBlock)) return false; - return facingState.isRedstoneConductor(world, facingPos) && canSupportCenter(world, facingPos, side); - } - - protected WallSide selectWallHeight(LevelReader world, BlockPos pos, Direction direction) { - return WallSide.LOW; // @todo: implement - } - - public BlockState getStateForPlacement(BlockPlaceContext context) { - LevelReader world = context.getLevel(); - BlockPos pos = context.getClickedPos(); - FluidState fs = context.getLevel().getFluidState(context.getClickedPos()); - boolean n = attachesTo(world.getBlockState(pos.north()), world, pos.north(), Direction.SOUTH); - boolean e = attachesTo(world.getBlockState(pos.east()), world, pos.east(), Direction.WEST); - boolean s = attachesTo(world.getBlockState(pos.south()), world, pos.south(), Direction.NORTH); - boolean w = attachesTo(world.getBlockState(pos.west()), world, pos.west(), Direction.EAST); - boolean not_straight = (!n || !s || e || w) && (n || s || !e || !w); - return defaultBlockState() - .setValue(UP, not_straight) - .setValue(WALL_NORTH, n ? selectWallHeight(world, pos, Direction.NORTH) : WallSide.NONE) - .setValue(WALL_EAST, e ? selectWallHeight(world, pos, Direction.EAST) : WallSide.NONE) - .setValue(WALL_SOUTH, s ? selectWallHeight(world, pos, Direction.SOUTH) : WallSide.NONE) - .setValue(WALL_WEST, w ? selectWallHeight(world, pos, Direction.WEST) : WallSide.NONE) - .setValue(WATERLOGGED, fs.getType() == Fluids.WATER); - } - - @Override - public BlockState updateShape(BlockState state, Direction side, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos) { - if (state.getValue(BlockStateProperties.WATERLOGGED)) - world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); - if (side == Direction.DOWN) return super.updateShape(state, side, facingState, world, pos, facingPos); - boolean n = (side == Direction.NORTH) ? attachesTo(facingState, world, facingPos, side) : (state.getValue(WALL_NORTH) != WallSide.NONE); - boolean e = (side == Direction.EAST) ? attachesTo(facingState, world, facingPos, side) : (state.getValue(WALL_EAST) != WallSide.NONE); - boolean s = (side == Direction.SOUTH) ? attachesTo(facingState, world, facingPos, side) : (state.getValue(WALL_SOUTH) != WallSide.NONE); - boolean w = (side == Direction.WEST) ? attachesTo(facingState, world, facingPos, side) : (state.getValue(WALL_WEST) != WallSide.NONE); - boolean not_straight = (!n || !s || e || w) && (n || s || !e || !w); - return state.setValue(UP, not_straight) - .setValue(WALL_NORTH, n ? selectWallHeight(world, pos, Direction.NORTH) : WallSide.NONE) - .setValue(WALL_EAST, e ? selectWallHeight(world, pos, Direction.EAST) : WallSide.NONE) - .setValue(WALL_SOUTH, s ? selectWallHeight(world, pos, Direction.SOUTH) : WallSide.NONE) - .setValue(WALL_WEST, w ? selectWallHeight(world, pos, Direction.WEST) : WallSide.NONE); - } - - @Override - public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType entityType) { - return false; - } - - - @Override - public boolean isPossibleToRespawnInThis(BlockState p_279289_) { - return false; - } - - @Override - @SuppressWarnings("deprecation") - public PushReaction getPistonPushReaction(BlockState state) { - return PushReaction.NORMAL; - } -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardStairsBlock.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardStairsBlock.java deleted file mode 100644 index 64a9f05..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/StandardStairsBlock.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * @file StandardStairsBlock.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Stairs and roof blocks, almost entirely based on vanilla stairs. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.core.BlockPos; -import net.minecraft.network.chat.Component; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.SpawnPlacements; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.block.StairBlock; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.material.PushReaction; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import javax.annotation.Nullable; -import java.util.List; - - -public class StandardStairsBlock extends StairBlock implements StandardBlocks.IStandardBlock { - private final long config; - - public StandardStairsBlock(long config, java.util.function.Supplier state, BlockBehaviour.Properties properties) { - super(state, properties); - this.config = config; - } - - @Override - @OnlyIn(Dist.CLIENT) - public void appendHoverText(ItemStack stack, @Nullable BlockGetter world, List tooltip, TooltipFlag flag) { - Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); - } - - - @Override - public boolean isPossibleToRespawnInThis(BlockState p_279289_) { - return false; - } - - @Override - public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType entityType) { - return false; - } - - @Override - @SuppressWarnings("deprecation") - public PushReaction getPistonPushReaction(BlockState state) { - return PushReaction.NORMAL; - } -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/TooltipDisplay.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/TooltipDisplay.java deleted file mode 100644 index 76eb760..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/TooltipDisplay.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * @file Tooltip.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Delayed tooltip for a selected area. Constructed with a - * GUI, invoked in `render()`. - */ -package dev.zontreck.libzontreck.edlibmc; - -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiGraphics; -import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; -import net.minecraft.network.chat.*; -import net.minecraft.util.Mth; -import net.minecraft.world.inventory.AbstractContainerMenu; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.function.Supplier; - - -@OnlyIn(Dist.CLIENT) -public class TooltipDisplay { - private static long default_delay = 800; - private static int default_max_deviation = 1; - - public static void config(long delay, int max_deviation) { - default_delay = clamp(delay, 500, 5000); - default_max_deviation = Mth.clamp(max_deviation, 1, 5); - } - private static long clamp(long p1, long a, long b) { - return p1 < a ? a : Math.min(p1, b); - } - - // --------------------------------------------------------------------------------------------------- - - public static class TipRange { - public final int x0, y0, x1, y1; - public final Supplier text; - - public TipRange(int x, int y, int w, int h, Component text) { - this(x, y, w, h, () -> text); - } - - public TipRange(int x, int y, int w, int h, Supplier text) { - this.text = text; - this.x0 = x; - this.y0 = y; - this.x1 = x0 + w - 1; - this.y1 = y0 + h - 1; - } - - } - - // --------------------------------------------------------------------------------------------------- - - private List ranges = new ArrayList<>(); - private long delay = default_delay; - private int max_deviation = default_max_deviation; - private int x_last, y_last; - private long t; - private static boolean had_render_exception = false; - - public TooltipDisplay() { - t = System.currentTimeMillis(); - } - - public TooltipDisplay init(List ranges, long delay_ms, int max_deviation_xy) { - this.ranges = ranges; - this.delay = delay_ms; - this.max_deviation = max_deviation_xy; - t = System.currentTimeMillis(); - x_last = y_last = 0; - return this; - } - - public TooltipDisplay init(List ranges) { - return init(ranges, default_delay, default_max_deviation); - } - - public TooltipDisplay init(TipRange... ranges) { - return init(Arrays.asList(ranges), default_delay, default_max_deviation); - } - - public TooltipDisplay delay(int ms) { - delay = (ms <= 0) ? default_delay : ms; - return this; - } - - public void resetTimer() { - t = System.currentTimeMillis(); - } - - public boolean render(GuiGraphics mx, final AbstractContainerScreen gui, int x, int y) { - if (had_render_exception) return false; - if ((Math.abs(x - x_last) > max_deviation) || (Math.abs(y - y_last) > max_deviation)) { - x_last = x; - y_last = y; - resetTimer(); - return false; - } else if (Math.abs(System.currentTimeMillis() - t) < delay) { - return false; - } else if (ranges.stream().noneMatch( - (tip) -> { - if ((x < tip.x0) || (x > tip.x1) || (y < tip.y0) || (y > tip.y1)) return false; - String text = tip.text.get().toString(); - if (text.isEmpty()) return false; - try { - mx.renderComponentTooltip(Minecraft.getInstance().font, tip.text.get().toFlatList(Style.EMPTY), x, y); - } catch (Exception ex) { - had_render_exception = true; - Auxiliaries.logError("Tooltip rendering disabled due to exception: '" + ex.getMessage() + "'"); - return false; - } - return true; - }) - ) { - resetTimer(); - return false; - } else { - return true; - } - } -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/VariantSlabBlock.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/VariantSlabBlock.java deleted file mode 100644 index 4f2eeb7..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/VariantSlabBlock.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * @file VariantSlabBlock.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Standard half block horizontal slab characteristics class. - */ -package dev.zontreck.libzontreck.edlibmc; - -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.network.chat.Component; -import net.minecraft.sounds.SoundSource; -import net.minecraft.util.Mth; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.SpawnPlacements; -import net.minecraft.world.entity.player.Player; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.Level; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.Mirror; -import net.minecraft.world.level.block.Rotation; -import net.minecraft.world.level.block.SoundType; -import net.minecraft.world.level.block.entity.BlockEntity; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.BlockStateProperties; -import net.minecraft.world.level.block.state.properties.EnumProperty; -import net.minecraft.world.level.block.state.properties.IntegerProperty; -import net.minecraft.world.level.block.state.properties.SlabType; -import net.minecraft.world.level.material.Fluid; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.phys.AABB; -import net.minecraft.world.phys.Vec3; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import javax.annotation.Nullable; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - - -public class VariantSlabBlock extends StandardBlocks.WaterLoggable implements StandardBlocks.IStandardBlock { - public static final EnumProperty TYPE = BlockStateProperties.SLAB_TYPE; - public static final IntegerProperty TEXTURE_VARIANT = IntegerProperty.create("tvariant", 0, 3); - - protected static final VoxelShape[] AABBs = { - Shapes.create(new AABB(0, 8. / 16, 0, 1, 16. / 16, 1)), // top slab - Shapes.create(new AABB(0, 0. / 16, 0, 1, 8. / 16, 1)), // bottom slab - Shapes.create(new AABB(0, 0. / 16, 0, 1, 16. / 16, 1)), // both slabs - Shapes.create(new AABB(0, 0. / 16, 0, 1, 16. / 16, 1)) // << 2bit fill - }; - protected static final int[] num_slabs_contained_in_parts_ = {1, 1, 2, 2}; - private static boolean with_pickup = false; - - public static void on_config(boolean direct_slab_pickup) { - with_pickup = direct_slab_pickup; - } - - protected boolean is_cube(BlockState state) { - return state.getValue(TYPE) == SlabType.DOUBLE; - } - - public VariantSlabBlock(long config, BlockBehaviour.Properties builder) { - super(config, builder); - registerDefaultState(defaultBlockState().setValue(TYPE, SlabType.BOTTOM)); - } - - @Override - public RenderTypeHint getRenderTypeHint() { - return (((config & StandardBlocks.CFG_TRANSLUCENT) != 0) ? (RenderTypeHint.TRANSLUCENT) : (RenderTypeHint.CUTOUT)); - } - - @Override - @OnlyIn(Dist.CLIENT) - public void appendHoverText(ItemStack stack, @Nullable BlockGetter world, List tooltip, TooltipFlag flag) { - if (!Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true)) return; - if (with_pickup && Auxiliaries.Tooltip.helpCondition()) - Auxiliaries.Tooltip.addInformation("engineersdecor.tooltip.slabpickup", "engineersdecor.tooltip.slabpickup", tooltip, flag, true); - } - - @Override - @OnlyIn(Dist.CLIENT) - @SuppressWarnings("deprecation") - public boolean skipRendering(BlockState state, BlockState adjacentBlockState, Direction side) { - return (adjacentBlockState == state) || (super.skipRendering(state, adjacentBlockState, side)); - } - - @Override - public boolean isPossibleToRespawnInThis(BlockState state) { - return false; - } - - @Override - public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType entityType) { - return false; - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter source, BlockPos pos, CollisionContext selectionContext) { - return AABBs[state.getValue(TYPE).ordinal() & 0x3]; - } - - @Override - public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) { - return getShape(state, world, pos, selectionContext); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - builder.add(TYPE, TEXTURE_VARIANT); - } - - @Override - @Nullable - public BlockState getStateForPlacement(BlockPlaceContext context) { - BlockPos pos = context.getClickedPos(); - if (context.getLevel().getBlockState(pos).getBlock() == this) - return context.getLevel().getBlockState(pos).setValue(TYPE, SlabType.DOUBLE).setValue(WATERLOGGED, false); - final int rnd = Mth.clamp((int) (Mth.getSeed(context.getClickedPos()) & 0x3), 0, 3); - final Direction face = context.getClickedFace(); - final BlockState placement_state = super.getStateForPlacement(context).setValue(TEXTURE_VARIANT, rnd); // fluid state - if (face == Direction.UP) return placement_state.setValue(TYPE, SlabType.BOTTOM); - if (face == Direction.DOWN) return placement_state.setValue(TYPE, SlabType.TOP); - if (!face.getAxis().isHorizontal()) return placement_state; - final boolean isupper = ((context.getClickLocation().y() - context.getClickedPos().getY()) > 0.5); - return placement_state.setValue(TYPE, isupper ? SlabType.TOP : SlabType.BOTTOM); - } - - @Override - @SuppressWarnings("deprecation") - public boolean canBeReplaced(BlockState state, BlockPlaceContext context) { - if (context.getItemInHand().getItem() != this.asItem()) return false; - if (!context.replacingClickedOnBlock()) return true; - final Direction face = context.getClickedFace(); - final SlabType type = state.getValue(TYPE); - if ((face == Direction.UP) && (type == SlabType.BOTTOM)) return true; - if ((face == Direction.DOWN) && (type == SlabType.TOP)) return true; - if (!face.getAxis().isHorizontal()) return false; - final boolean isupper = ((context.getClickLocation().y() - context.getClickedPos().getY()) > 0.5); - return isupper ? (type == SlabType.BOTTOM) : (type == SlabType.TOP); - } - - @Override - @SuppressWarnings("deprecation") - public BlockState rotate(BlockState state, Rotation rot) { - return state; - } - - @Override - @SuppressWarnings("deprecation") - public BlockState mirror(BlockState state, Mirror mirrorIn) { - return state; - } - - @Override - public boolean hasDynamicDropList() { - return true; - } - - @Override - public List dropList(BlockState state, Level world, BlockEntity te, boolean explosion) { - return new ArrayList<>(Collections.singletonList(new ItemStack(this.asItem(), num_slabs_contained_in_parts_[state.getValue(TYPE).ordinal() & 0x3]))); - } - - @Override - @SuppressWarnings("deprecation") - public void attack(BlockState state, Level world, BlockPos pos, Player player) { - if ((world.isClientSide) || (!with_pickup)) return; - final ItemStack stack = player.getMainHandItem(); - if (stack.isEmpty() || (Block.byItem(stack.getItem()) != this)) return; - if (stack.getCount() >= stack.getMaxStackSize()) return; - Vec3 lv = player.getLookAngle(); - Direction facing = Direction.getNearest((float) lv.x, (float) lv.y, (float) lv.z); - if ((facing != Direction.UP) && (facing != Direction.DOWN)) return; - if (state.getBlock() != this) return; - SlabType type = state.getValue(TYPE); - if (facing == Direction.DOWN) { - if (type == SlabType.DOUBLE) { - world.setBlock(pos, state.setValue(TYPE, SlabType.BOTTOM), 3); - } else { - world.removeBlock(pos, false); - } - } else if (facing == Direction.UP) { - if (type == SlabType.DOUBLE) { - world.setBlock(pos, state.setValue(TYPE, SlabType.TOP), 3); - } else { - world.removeBlock(pos, false); - } - } - if (!player.isCreative()) { - stack.grow(1); - if (player.getInventory() != null) player.getInventory().setChanged(); - } - SoundType st = this.getSoundType(state, world, pos, null); - world.playSound(player, pos, st.getPlaceSound(), SoundSource.BLOCKS, (st.getVolume() + 1f) / 2.5f, 0.9f * st.getPitch()); - } - - @Override - public boolean placeLiquid(LevelAccessor world, BlockPos pos, BlockState state, FluidState fluidState) { - return (state.getValue(TYPE) != SlabType.DOUBLE) && super.placeLiquid(world, pos, state, fluidState); - } - - @Override - public boolean canPlaceLiquid(BlockGetter world, BlockPos pos, BlockState state, Fluid fluid) { - return (state.getValue(TYPE) != SlabType.DOUBLE) && super.canPlaceLiquid(world, pos, state, fluid); - } - -} diff --git a/src/main/java/dev/zontreck/libzontreck/edlibmc/VariantWallBlock.java b/src/main/java/dev/zontreck/libzontreck/edlibmc/VariantWallBlock.java deleted file mode 100644 index 92af666..0000000 --- a/src/main/java/dev/zontreck/libzontreck/edlibmc/VariantWallBlock.java +++ /dev/null @@ -1,200 +0,0 @@ -/* - * @file VariantWallBlock.java - * @author Stefan Wilhelm (wile) - * @copyright (C) 2020 Stefan Wilhelm - * @license MIT (see https://opensource.org/licenses/MIT) - * - * Wall blocks. - */ -package dev.zontreck.libzontreck.edlibmc; - -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableMap.Builder; -import net.minecraft.core.BlockPos; -import net.minecraft.core.Direction; -import net.minecraft.network.chat.Component; -import net.minecraft.util.Mth; -import net.minecraft.world.entity.EntityType; -import net.minecraft.world.entity.SpawnPlacements; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.item.TooltipFlag; -import net.minecraft.world.item.context.BlockPlaceContext; -import net.minecraft.world.level.BlockGetter; -import net.minecraft.world.level.LevelAccessor; -import net.minecraft.world.level.LevelReader; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.level.block.FenceGateBlock; -import net.minecraft.world.level.block.WallBlock; -import net.minecraft.world.level.block.state.BlockBehaviour; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.level.block.state.StateDefinition; -import net.minecraft.world.level.block.state.properties.*; -import net.minecraft.world.level.material.FluidState; -import net.minecraft.world.level.material.Fluids; -import net.minecraft.world.level.material.PushReaction; -import net.minecraft.world.phys.shapes.CollisionContext; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; -import net.minecraftforge.api.distmarker.Dist; -import net.minecraftforge.api.distmarker.OnlyIn; - -import javax.annotation.Nullable; -import java.util.List; -import java.util.Map; - - -public class VariantWallBlock extends WallBlock implements StandardBlocks.IStandardBlock { - public static final BooleanProperty UP = BlockStateProperties.UP; - public static final EnumProperty WALL_EAST = BlockStateProperties.EAST_WALL; - public static final EnumProperty WALL_NORTH = BlockStateProperties.NORTH_WALL; - public static final EnumProperty WALL_SOUTH = BlockStateProperties.SOUTH_WALL; - public static final EnumProperty WALL_WEST = BlockStateProperties.WEST_WALL; - public static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; - public static final IntegerProperty TEXTURE_VARIANT = IntegerProperty.create("tvariant", 0, 7); - private final Map shape_voxels; - private final Map collision_shape_voxels; - private final long config; - - public VariantWallBlock(long config, BlockBehaviour.Properties builder) { - super(builder); - shape_voxels = buildWallShapes(4, 16, 4, 0, 16, 16); - collision_shape_voxels = buildWallShapes(6, 16, 5, 0, 24, 24); - this.config = config; - } - - @Override - public long config() { - return config; - } - - @Override - @OnlyIn(Dist.CLIENT) - public void appendHoverText(ItemStack stack, @Nullable BlockGetter world, List tooltip, TooltipFlag flag) { - Auxiliaries.Tooltip.addInformation(stack, world, tooltip, flag, true); - } - - private static VoxelShape combinedShape(VoxelShape pole, WallSide height, VoxelShape low, VoxelShape high) { - if (height == WallSide.TALL) return Shapes.or(pole, high); - if (height == WallSide.LOW) return Shapes.or(pole, low); - return pole; - } - - protected Map buildWallShapes(double pole_width, double pole_height, double side_width, double side_min_y, double side_max_low_y, double side_max_tall_y) { - final double px0 = 8.0 - pole_width, px1 = 8.0 + pole_width, sx0 = 8.0 - side_width, sx1 = 8.0 + side_width; - VoxelShape vp = Block.box(px0, 0, px0, px1, pole_height, px1); - VoxelShape vs1 = Block.box(sx0, side_min_y, 0, sx1, side_max_low_y, sx1); - VoxelShape vs2 = Block.box(sx0, side_min_y, sx0, sx1, side_max_low_y, 16); - VoxelShape vs3 = Block.box(0, side_min_y, sx0, sx1, side_max_low_y, sx1); - VoxelShape vs4 = Block.box(sx0, side_min_y, sx0, 16, side_max_low_y, sx1); - VoxelShape vs5 = Block.box(sx0, side_min_y, 0, sx1, side_max_tall_y, sx1); - VoxelShape vs6 = Block.box(sx0, side_min_y, sx0, sx1, side_max_tall_y, 16); - VoxelShape vs7 = Block.box(0, side_min_y, sx0, sx1, side_max_tall_y, sx1); - VoxelShape vs8 = Block.box(sx0, side_min_y, sx0, 16, side_max_tall_y, sx1); - Builder builder = ImmutableMap.builder(); - for (Boolean up : UP.getPossibleValues()) { - for (WallSide wh_east : WALL_EAST.getPossibleValues()) { - for (WallSide wh_north : WALL_NORTH.getPossibleValues()) { - for (WallSide wh_west : WALL_WEST.getPossibleValues()) { - for (WallSide wh_south : WALL_SOUTH.getPossibleValues()) { - VoxelShape shape = Shapes.empty(); - shape = combinedShape(shape, wh_east, vs4, vs8); - shape = combinedShape(shape, wh_west, vs3, vs7); - shape = combinedShape(shape, wh_north, vs1, vs5); - shape = combinedShape(shape, wh_south, vs2, vs6); - if (up) shape = Shapes.or(shape, vp); - BlockState bs = defaultBlockState().setValue(UP, up) - .setValue(WALL_EAST, wh_east) - .setValue(WALL_NORTH, wh_north) - .setValue(WALL_WEST, wh_west) - .setValue(WALL_SOUTH, wh_south); - final VoxelShape tvs = shape; - TEXTURE_VARIANT.getPossibleValues().forEach((tv) -> { - builder.put(bs.setValue(TEXTURE_VARIANT, tv).setValue(WATERLOGGED, false), tvs); - builder.put(bs.setValue(TEXTURE_VARIANT, tv).setValue(WATERLOGGED, true), tvs); - }); - } - } - } - } - } - return builder.build(); - } - - @Override - public VoxelShape getShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) { - return shape_voxels.getOrDefault(state, Shapes.block()); - } - - @Override - public VoxelShape getCollisionShape(BlockState state, BlockGetter world, BlockPos pos, CollisionContext selectionContext) { - return collision_shape_voxels.getOrDefault(state, Shapes.block()); - } - - @Override - protected void createBlockStateDefinition(StateDefinition.Builder builder) { - super.createBlockStateDefinition(builder); - builder.add(TEXTURE_VARIANT); - } - - protected boolean attachesTo(BlockState facingState, LevelReader world, BlockPos facingPos, Direction side) { - final Block block = facingState.getBlock(); - if ((block instanceof FenceGateBlock) || (block instanceof WallBlock)) return true; - final BlockState oppositeState = world.getBlockState(facingPos.relative(side, 2)); - if (!(oppositeState.getBlock() instanceof VariantWallBlock)) return false; - return facingState.isRedstoneConductor(world, facingPos) && Block.canSupportCenter(world, facingPos, side); - } - - protected WallSide selectWallHeight(LevelReader world, BlockPos pos, Direction direction) { - return WallSide.LOW; - } - - public BlockState getStateForPlacement(BlockPlaceContext context) { - LevelReader world = context.getLevel(); - BlockPos pos = context.getClickedPos(); - FluidState fs = context.getLevel().getFluidState(context.getClickedPos()); - boolean n = attachesTo(world.getBlockState(pos.north()), world, pos.north(), Direction.SOUTH); - boolean e = attachesTo(world.getBlockState(pos.east()), world, pos.east(), Direction.WEST); - boolean s = attachesTo(world.getBlockState(pos.south()), world, pos.south(), Direction.NORTH); - boolean w = attachesTo(world.getBlockState(pos.west()), world, pos.west(), Direction.EAST); - boolean not_straight = (!n || !s || e || w) && (n || s || !e || !w); - return defaultBlockState().setValue(UP, not_straight) - .setValue(WALL_NORTH, n ? selectWallHeight(world, pos, Direction.NORTH) : WallSide.NONE) - .setValue(WALL_EAST, e ? selectWallHeight(world, pos, Direction.EAST) : WallSide.NONE) - .setValue(WALL_SOUTH, s ? selectWallHeight(world, pos, Direction.SOUTH) : WallSide.NONE) - .setValue(WALL_WEST, w ? selectWallHeight(world, pos, Direction.WEST) : WallSide.NONE) - .setValue(WATERLOGGED, fs.getType() == Fluids.WATER); - } - - @Override - public BlockState updateShape(BlockState state, Direction side, BlockState facingState, LevelAccessor world, BlockPos pos, BlockPos facingPos) { - if (state.getValue(WATERLOGGED)) world.scheduleTick(pos, Fluids.WATER, Fluids.WATER.getTickDelay(world)); - if (side == Direction.DOWN) return super.updateShape(state, side, facingState, world, pos, facingPos); - boolean n = (side == Direction.NORTH) ? this.attachesTo(facingState, world, facingPos, side) : state.getValue(WALL_NORTH) != WallSide.NONE; - boolean e = (side == Direction.EAST) ? this.attachesTo(facingState, world, facingPos, side) : state.getValue(WALL_EAST) != WallSide.NONE; - boolean s = (side == Direction.SOUTH) ? this.attachesTo(facingState, world, facingPos, side) : state.getValue(WALL_SOUTH) != WallSide.NONE; - boolean w = (side == Direction.WEST) ? this.attachesTo(facingState, world, facingPos, side) : state.getValue(WALL_WEST) != WallSide.NONE; - boolean not_straight = (!n || !s || e || w) && (n || s || !e || !w); - return state.setValue(UP, not_straight) - .setValue(WALL_NORTH, n ? selectWallHeight(world, pos, Direction.NORTH) : WallSide.NONE) - .setValue(WALL_EAST, e ? selectWallHeight(world, pos, Direction.EAST) : WallSide.NONE) - .setValue(WALL_SOUTH, s ? selectWallHeight(world, pos, Direction.SOUTH) : WallSide.NONE) - .setValue(WALL_WEST, w ? selectWallHeight(world, pos, Direction.WEST) : WallSide.NONE) - .setValue(TEXTURE_VARIANT, ((int) Mth.getSeed(pos)) & 0x7); - } - - @Override - public boolean isValidSpawn(BlockState state, BlockGetter world, BlockPos pos, SpawnPlacements.Type type, @Nullable EntityType entityType) { - return false; - } - - @Override - public boolean isPossibleToRespawnInThis(BlockState state) { - return false; - } - - @Override - @SuppressWarnings("deprecation") - public PushReaction getPistonPushReaction(BlockState state) { - return PushReaction.NORMAL; - } -} diff --git a/src/main/java/dev/zontreck/libzontreck/events/ForgeEventHandlers.java b/src/main/java/dev/zontreck/libzontreck/events/ForgeEventHandlers.java index d24ffa8..56ebdf3 100644 --- a/src/main/java/dev/zontreck/libzontreck/events/ForgeEventHandlers.java +++ b/src/main/java/dev/zontreck/libzontreck/events/ForgeEventHandlers.java @@ -4,7 +4,7 @@ import dev.zontreck.ariaslib.terminal.Task; import dev.zontreck.ariaslib.util.DelayedExecutorService; import dev.zontreck.libzontreck.LibZontreck; import dev.zontreck.libzontreck.exceptions.InvalidSideException; -import dev.zontreck.libzontreck.memory.PlayerContainer; +import dev.zontreck.libzontreck.memory.player.PlayerContainer; import dev.zontreck.libzontreck.networking.ModMessages; import dev.zontreck.libzontreck.networking.packets.S2CServerAvailable; import dev.zontreck.libzontreck.networking.packets.S2CWalletInitialSyncPacket; diff --git a/src/main/java/dev/zontreck/libzontreck/memory/world/SavedBlock.java b/src/main/java/dev/zontreck/libzontreck/memory/world/SavedBlock.java index 539d890..119ed68 100644 --- a/src/main/java/dev/zontreck/libzontreck/memory/world/SavedBlock.java +++ b/src/main/java/dev/zontreck/libzontreck/memory/world/SavedBlock.java @@ -4,13 +4,13 @@ import dev.zontreck.libzontreck.api.Vector3; import dev.zontreck.libzontreck.exceptions.InvalidDeserialization; import dev.zontreck.libzontreck.vectors.WorldPosition; import net.minecraft.core.BlockPos; -import net.minecraft.core.registries.Registries; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtUtils; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.Level; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraftforge.registries.ForgeRegistries; public class SavedBlock implements Cloneable { @@ -88,7 +88,7 @@ public class SavedBlock implements Cloneable { ServerLevel level = position.getActualDimension(); - BlockState state = NbtUtils.readBlockState(level.holderLookup(Registries.BLOCK), blockState); + BlockState state = NbtUtils.readBlockState(blockState); return new PrimitiveBlock(this, state.getBlock(), state, blockEntity, position.Position.asBlockPos(), level); } diff --git a/src/main/java/dev/zontreck/libzontreck/networking/ModMessages.java b/src/main/java/dev/zontreck/libzontreck/networking/ModMessages.java index e7bbe1f..2c52022 100644 --- a/src/main/java/dev/zontreck/libzontreck/networking/ModMessages.java +++ b/src/main/java/dev/zontreck/libzontreck/networking/ModMessages.java @@ -1,7 +1,6 @@ package dev.zontreck.libzontreck.networking; import dev.zontreck.libzontreck.LibZontreck; -import dev.zontreck.libzontreck.events.RegisterPacketsEvent; import dev.zontreck.libzontreck.networking.packets.IPacket; import dev.zontreck.libzontreck.networking.packets.S2CCloseChestGUI; import dev.zontreck.libzontreck.networking.packets.S2CPlaySoundPacket; diff --git a/src/main/java/dev/zontreck/libzontreck/networking/packets/S2CWalletUpdatedPacket.java b/src/main/java/dev/zontreck/libzontreck/networking/packets/S2CWalletUpdatedPacket.java index 6d26432..0c4b3c8 100644 --- a/src/main/java/dev/zontreck/libzontreck/networking/packets/S2CWalletUpdatedPacket.java +++ b/src/main/java/dev/zontreck/libzontreck/networking/packets/S2CWalletUpdatedPacket.java @@ -6,6 +6,7 @@ import dev.zontreck.libzontreck.currency.events.WalletUpdatedEvent; import dev.zontreck.libzontreck.util.ServerUtilities; import net.minecraft.nbt.CompoundTag; import net.minecraft.network.FriendlyByteBuf; +import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.network.NetworkDirection; import net.minecraftforge.network.NetworkEvent; import net.minecraftforge.network.simple.SimpleChannel; @@ -63,8 +64,7 @@ public class S2CWalletUpdatedPacket implements IPacket return ServerUtilities.handlePacket(supplier, new Runnable() { @Override public void run() { - Bus.Post(new WalletUpdatedEvent(ID, oldBal, balance, tx)); - + MinecraftForge.EVENT_BUS.post(new WalletUpdatedEvent(ID, oldBal, balance, tx)); } }); } diff --git a/src/main/java/dev/zontreck/libzontreck/vectors/WorldPosition.java b/src/main/java/dev/zontreck/libzontreck/vectors/WorldPosition.java index 3d62956..9143a1d 100644 --- a/src/main/java/dev/zontreck/libzontreck/vectors/WorldPosition.java +++ b/src/main/java/dev/zontreck/libzontreck/vectors/WorldPosition.java @@ -38,7 +38,7 @@ public class WorldPosition implements Cloneable } public WorldPosition(ServerPlayer player) { - this(new Vector3d(player.position()), player.serverLevel()); + this(new Vector3d(player.position()), player.getLevel()); } public WorldPosition(Vector3d pos, ServerLevel lvl) {