### Format Numbers with Compact Notation and Options Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Provides examples of using NumberFormatUtil for basic, compact, and custom-formatted numbers, including energy and fluid amounts. Requires importing CompactOptions and FormatOptions. ```java import com.gtnewhorizon.gtnhlib.util.numberformatting.NumberFormatUtil; import com.gtnewhorizon.gtnhlib.util.numberformatting.options.CompactOptions; import com.gtnewhorizon.gtnhlib.util.numberformatting.options.FormatOptions; // Basic number formatting String formatted = NumberFormatUtil.formatNumber(1234567); // Output: "1,234,567" // Compact notation (K, M, B, T, Q) String compact = NumberFormatUtil.formatNumberCompact(1500000); // Output: "1.5M" String largeCompact = NumberFormatUtil.formatNumberCompact(2500000000000L); // Output: "2.5T" // Custom compact options CompactOptions options = new CompactOptions() .setDecimalPlaces(2) .setCompactThreshold(10000); String customCompact = NumberFormatUtil.formatNumberCompact(15000, options); // Output: "15K" // Energy formatting String energy = NumberFormatUtil.formatEnergy(1000000); // Output: "1,000,000 EU" String energyCompact = NumberFormatUtil.formatEnergyCompact(2500000000L); // Output: "2.5B EU" // Fluid formatting String fluid = NumberFormatUtil.formatFluid(16000); // Output: "16,000 mB" or "16,000 L" depending on config String fluidCompact = NumberFormatUtil.formatFluidCompact(1500000); // Output: "1.5M mB" // FluidStack support FluidStack waterStack = new FluidStack(FluidRegistry.WATER, 5000); String fluidAmount = NumberFormatUtil.formatFluid(waterStack); // Output: "5,000 mB" ``` -------------------------------- ### GTNH Lib Configuration System Example Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Demonstrates how to define and register a configuration class using GTNH Lib's annotation-based system. Includes basic types, nested categories, and server-synced options. Registration should occur during FML's PreInit phase. ```java import com.gtnewhorizon.gtnhlib.config.Config; import com.gtnewhorizon.gtnhlib.config.ConfigurationManager; @Config(modid = "mymod", category = "general", filename = "mymod-config") @Config.LangKeyPattern(pattern = "%mod.config.%cat.%field") public class MyModConfig { @Config.Comment("Enable advanced features") @Config.DefaultBoolean(true) public static boolean enableAdvancedFeatures; @Config.Comment("Maximum processing speed") @Config.RangeInt(min = 1, max = 100) @Config.DefaultInt(50) public static int maxSpeed; @Config.Comment("Multiplier for energy consumption") @Config.RangeFloat(min = 0.1f, max = 10.0f) @Config.DefaultFloat(1.0f) public static float energyMultiplier; @Config.Comment("List of allowed item IDs") @Config.DefaultStringList({"minecraft:diamond", "minecraft:emerald"}) public static String[] allowedItems; // Nested category for client settings @Config.Comment("Client-side rendering options") public static ClientSettings client = new ClientSettings(); public static class ClientSettings { @Config.Comment("Enable particle effects") @Config.DefaultBoolean(true) public boolean particles; @Config.Comment("Render distance multiplier") @Config.RangeInt(min = 1, max = 16) @Config.DefaultInt(8) public int renderDistance; } // Server-synced configuration @Config.Sync @Config.Comment("Server-controlled difficulty setting") @Config.DefaultInt(1) public static int difficulty; } // Registration during PreInit public void preInit(FMLPreInitializationEvent event) { try { ConfigurationManager.registerConfig(MyModConfig.class); } catch (ConfigException e) { e.printStackTrace(); } } // Saving configuration changes ConfigurationManager.save(MyModConfig.class); ``` -------------------------------- ### GTNH Lib BlockProperty and BlockState API Example Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Illustrates creating a custom BlockProperty for block states, including TileEntity interaction and registration. Also shows how to use pre-built properties and query block states from the world. ```java import com.gtnewhorizon.gtnhlib.blockstate.core.BlockProperty; import com.gtnewhorizon.gtnhlib.blockstate.core.BlockPropertyTrait; import com.gtnewhorizon.gtnhlib.blockstate.properties.DirectionBlockProperty; import com.gtnewhorizon.gtnhlib.blockstate.registry.BlockPropertyRegistry; import net.minecraftforge.common.util.ForgeDirection; // Creating a direction property backed by TileEntity DirectionBlockProperty facingProperty = new DirectionBlockProperty() { @Override public String getName() { return "facing"; } @Override public boolean hasTrait(BlockPropertyTrait trait) { return switch (trait) { case SupportsWorld, WorldMutable, SupportsStacks -> true; default -> false; }; } @Override public ForgeDirection getValue(IBlockAccess world, int x, int y, int z) { TileEntity te = world.getTileEntity(x, y, z); if (te instanceof MyMachineTile tile) { return tile.getFacing(); } return ForgeDirection.NORTH; } @Override public void setValue(World world, int x, int y, int z, ForgeDirection value) { TileEntity te = world.getTileEntity(x, y, z); if (te instanceof MyMachineTile tile) { tile.setFacing(value); world.markBlockForUpdate(x, y, z); } } @Override public ForgeDirection getValue(ItemStack stack) { return ForgeDirection.NORTH; } }; // Register property on block and its item BlockPropertyRegistry.registerBlockItemProperty(myBlock, facingProperty); // Using pre-built direction property with metadata mapping DirectionBlockProperty.AbstractDirectionBlockProperty vanillaFacing = DirectionBlockProperty.facingVanilla(0b111); // 3-bit mask // Query block state from world BlockState state = BlockPropertyRegistry.getBlockState(world, x, y, z); ForgeDirection facing = state.getValue(facingProperty); ``` -------------------------------- ### Implementing IBlockColor Directly in a Block Source: https://github.com/gtnewhorizons/gtnhlib/blob/master/models.md Implement IBlockColor directly within your block class for integrated color logic. This example shows how to return different colors based on tintIndex using a switch statement. ```java public class BlockTestTint extends Block implements IBlockColor { public BlockTestTint() { super(Material.wood); } @Override public int colorMultiplier(IBlockAccess world, int x, int y, int z, int tintIndex) { return switch(tintIndex) { case 0 -> 0xFF0000; // red case 1 -> 0x00FF00; // green case 2 -> 0x0000FF; // blue case 3 -> 0xFFFF00; // yellow case 4 -> 0xFF00FF; // magenta case 5 -> 0x00FFFF; // cyan default -> 0xFFFFFF; // white }; } @Override public int colorMultiplier(ItemStack stack, int tintIndex) { return colorMultiplier(null, 0, 0, 0, tintIndex); } } ``` -------------------------------- ### Blockstate JSON for Directional Variants Source: https://github.com/gtnewhorizons/gtnhlib/blob/master/models.md Define blockstate JSON to map property values to specific model variants. This example shows how the 'facing' property is used to select different machine models for each direction. ```json { "variants": { "facing=north": { "model": "modid:block/machine_north" }, "facing=south": { "model": "modid:block/machine_south" }, "facing=west": { "model": "modid:block/machine_west" }, "facing=east": { "model": "modid:block/machine_east" } } } ``` -------------------------------- ### Implement and Use IEnergyStorage Capability Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Demonstrates how to define an IEnergyStorage capability, implement it in a TileEntity using CapabilityProvider, and query capabilities from TileEntities and ItemStacks. ```java import com.gtnewhorizon.gtnhlib.capability.Capabilities; import com.gtnewhorizon.gtnhlib.capability.CapabilityProvider; import net.minecraftforge.common.util.ForgeDirection; // Define a capability interface public interface IEnergyStorage { int receiveEnergy(int amount, boolean simulate); int extractEnergy(int amount, boolean simulate); int getEnergyStored(); int getMaxEnergyStored(); } // Implement CapabilityProvider in a TileEntity public class TileEnergyMachine extends TileEntity implements CapabilityProvider { private final EnergyStorageImpl energyStorage = new EnergyStorageImpl(100000); @Override public T getCapability(Class capability, ForgeDirection side) { if (capability == IEnergyStorage.class) { // Only expose energy on specific sides if (side == ForgeDirection.UP || side == ForgeDirection.DOWN) { return capability.cast(energyStorage); } } return null; } } // Query capabilities from any object TileEntity te = world.getTileEntity(x, y, z); IEnergyStorage energy = Capabilities.getCapability(te, IEnergyStorage.class, ForgeDirection.UP); if (energy != null) { int received = energy.receiveEnergy(1000, false); System.out.println("Transferred " + received + " energy"); } // Query from ItemStack ItemStack stack = player.getHeldItem(); IEnergyStorage itemEnergy = Capabilities.getCapability(stack, IEnergyStorage.class); if (itemEnergy != null) { int stored = itemEnergy.getEnergyStored(); } ``` -------------------------------- ### Create Chat Components for Numbers, Fluids, and Energy Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Use custom chat components to display formatted numbers, fluid amounts, and energy values with proper localization. Ensure necessary imports are included. ```java import com.gtnewhorizon.gtnhlib.chat.customcomponents.ChatComponentNumber; import com.gtnewhorizon.gtnhlib.chat.customcomponents.ChatComponentFluid; import com.gtnewhorizon.gtnhlib.chat.customcomponents.ChatComponentEnergy; import net.minecraft.util.ChatComponentText; import net.minecraft.util.IChatComponent; // Create formatted number in chat IChatComponent message = new ChatComponentText("Stored items: ") .appendSibling(new ChatComponentNumber(1234567)) .appendSibling(new ChatComponentText(" units")); player.addChatMessage(message); // Displays: "Stored items: 1,234,567 units" // Fluid amount chat component FluidStack fluidStack = new FluidStack(FluidRegistry.LAVA, 50000); IChatComponent fluidMessage = new ChatComponentText("Tank contains: ") .appendSibling(new ChatComponentFluid(fluidStack)); player.addChatMessage(fluidMessage); // Displays: "Tank contains: 50,000 mB" // Energy chat component IChatComponent energyMessage = new ChatComponentText("Energy: ") .appendSibling(new ChatComponentEnergy(2000000000L)); player.addChatMessage(energyMessage); // Displays: "Energy: 2,000,000,000 EU" ``` -------------------------------- ### Register Client Event Handlers with Conditions Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Shows how to use @EventBusSubscriber for client-side event registration, including phase control and a condition method to enable/disable registration based on configuration. ```java import com.gtnewhorizon.gtnhlib.eventbus.EventBusSubscriber; import com.gtnewhorizon.gtnhlib.eventbus.Phase; import cpw.mods.fml.common.eventhandler.SubscribeEvent; import cpw.mods.fml.relauncher.Side; @EventBusSubscriber(side = Side.CLIENT, phase = Phase.INIT) public class ClientEventHandler { // Condition method to control registration @EventBusSubscriber.Condition public static boolean shouldRegister() { return ConfigHandler.enableClientEvents; } @SubscribeEvent public static void onRenderTick(RenderTickEvent event) { if (event.phase == Phase.END) { // Render custom overlays } } @SubscribeEvent public static void onWorldRender(RenderWorldLastEvent event) { // Custom world rendering } } ``` -------------------------------- ### Manage OpenGL Shader Programs Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Load, use, and manage OpenGL shader programs for custom rendering effects. Set uniform values and bind textures. Ensure proper cleanup. ```java import com.gtnewhorizon.gtnhlib.client.renderer.shader.ShaderProgram; import org.joml.Vector3f; // Create shader program from resource files ShaderProgram shader = new ShaderProgram( "mymod", "shaders/custom.vert", "shaders/custom.frag" ); // Use shader for rendering shader.use(); // Set uniform values int colorLoc = shader.getUniformLocation("u_Color"); GL20.glUniform4f(colorLoc, 1.0f, 0.5f, 0.0f, 1.0f); int timeLoc = shader.getUniformLocation("u_Time"); GL20.glUniform1f(timeLoc, (float) System.currentTimeMillis() / 1000.0f); // Vector uniform helpers Vector3f lightDir = new Vector3f(0.5f, 1.0f, 0.3f).normalize(); shader.glUniform3f(shader.getUniformLocation("u_LightDir"), lightDir); // Bind texture to sampler shader.bindTextureSlot("u_Texture", 0); // Render geometry... // Unbind shader ShaderProgram.unbind(); // Cleanup when done shader.close(); ``` -------------------------------- ### BlockPos Basic Usage and Iteration Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Create and manipulate BlockPos objects, including offsetting and iterating over positions within a bounding box. Pack positions to a long for efficient storage. ```java import com.gtnewhorizon.gtnhlib.blockpos.BlockPos; import net.minecraftforge.common.util.ForgeDirection; // Basic BlockPos usage BlockPos pos = new BlockPos(100, 64, -200); BlockPos above = pos.up(); BlockPos north = pos.offset(ForgeDirection.NORTH); BlockPos relative = pos.offset(5, -2, 10); // Pack position to long for efficient storage long packed = pos.asLong(); BlockPos restored = new BlockPos().set(packed); // Iterate over all positions in a box (inclusive range) BlockPos corner1 = new BlockPos(0, 60, 0); BlockPos corner2 = new BlockPos(15, 70, 15); for (BlockPos blockPos : BlockPos.getAllInBox(corner1, corner2)) { Block block = world.getBlock(blockPos.getX(), blockPos.getY(), blockPos.getZ()); if (block != Blocks.air) { // Process non-air blocks System.out.println("Found " + block + " at " + blockPos); } } ``` -------------------------------- ### Registering a BlockProperty Source: https://github.com/gtnewhorizons/gtnhlib/blob/master/models.md Register a created BlockProperty with both the block and its corresponding item. This ensures the property is recognized for both world rendering and inventory display. ```java BlockPropertyRegistry.registerProperty(block, property); BlockPropertyRegistry.registerProperty(Item.getItemFromBlock(block), property); ``` -------------------------------- ### Implementing IBlockColor Directly in a Block Class Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Implement the IBlockColor interface directly within a block class to handle color multipliers. Access tile entity data or NBT for dynamic coloring. Ensure fallback colors are provided. ```java import com.gtnewhorizon.gtnhlib.client.model.color.IBlockColor; // Implement IBlockColor directly in a block class public class BlockColoredMachine extends Block implements IBlockColor { @Override public int colorMultiplier(IBlockAccess world, int x, int y, int z, int tintIndex) { TileEntity te = world.getTileEntity(x, y, z); if (te instanceof TileColoredMachine tile) { return switch (tintIndex) { case 0 -> tile.getPrimaryColor(); case 1 -> tile.getSecondaryColor(); default -> 0xFFFFFF; }; } return 0xFFFFFF; } @Override public int colorMultiplier(ItemStack stack, int tintIndex) { NBTTagCompound nbt = stack.getTagCompound(); if (nbt != null && tintIndex == 0) { return nbt.getInteger("color"); } return 0xFFFFFF; } } ``` -------------------------------- ### Display Messages Above Hotbar with Fade Effects Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Utilize AboveHotbarHUD to display temporary messages above the player's hotbar. Control visibility duration, shadow, and fade effects. ```java import com.gtnewhorizon.gtnhlib.util.AboveHotbarHUD; // Display a simple message for 60 ticks (3 seconds) AboveHotbarHUD.renderTextAboveHotbar("Item collected!", 60, true, false); // Display with fade effect AboveHotbarHUD.renderTextAboveHotbar("Achievement unlocked!", 100, true, true); // Display without shadow, with fade AboveHotbarHUD.renderTextAboveHotbar("Warning: Low energy", 80, false, true); ``` -------------------------------- ### Creating a Direction BlockProperty Source: https://github.com/gtnewhorizons/gtnhlib/blob/master/models.md Define a custom BlockProperty to manage block states, such as direction, backed by TileEntity data. Ensure to implement the necessary traits like SupportsWorld and WorldMutable. ```java DirectionBlockProperty property = new DirectionBlockProperty() { @Override public String getName() { return "facing"; } @Override public boolean hasTrait(BlockPropertyTrait trait) { return switch (trait) { case SupportsWorld, WorldMutable, StackMutable, SupportsStacks -> true; default -> false; }; } @Override public ForgeDirection getValue(IBlockAccess world, int x, int y, int z) { TileEntity te = world.getTileEntity(x, y, z); if (te instanceof TileTestTintMul tile) { return tile.getFacing(); } return ForgeDirection.NORTH; } @Override public void setValue(World world, int x, int y, int z, ForgeDirection value) { TileEntity te = world.getTileEntity(x, y, z); if (te instanceof TileTestTintMul tile) { tile.setFacing(value); } } @Override public ForgeDirection getValue(ItemStack stack) { return ForgeDirection.NORTH; } }; ``` -------------------------------- ### Coordinate Packing Utilities Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Utilize CoordinatePacker to pack and unpack 3D coordinates into a single long value for efficient storage or transmission. Ensure coordinates are within the packable range. ```java import com.gtnewhorizon.gtnhlib.util.CoordinatePacker; long packedCoord = CoordinatePacker.pack(100, 64, -200); int x = CoordinatePacker.unpackX(packedCoord); int y = CoordinatePacker.unpackY(packedCoord); int z = CoordinatePacker.unpackZ(packedCoord); ``` -------------------------------- ### Registering External Block Color Handlers Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Implement IBlockColor to provide custom color multipliers for blocks and their item forms. Register these handlers using BlockColor.registerBlockColors. Ensure tintIndex is handled correctly. ```java import com.gtnewhorizon.gtnhlib.client.model.color.BlockColor; import com.gtnewhorizon.gtnhlib.client.model.color.IBlockColor; // Register external color handler BlockColor.registerBlockColors(new IBlockColor() { @Override public int colorMultiplier(IBlockAccess world, int x, int y, int z, int tintIndex) { if (tintIndex == 0) { // Base layer: biome-dependent grass color return world.getBiomeGenForCoords(x, z).getBiomeGrassColor(x, y, z); } else if (tintIndex == 1) { // Overlay: fixed accent color return 0x3366FF; } return 0xFFFFFF; // White (no tint) } @Override public int colorMultiplier(ItemStack stack, int tintIndex) { return tintIndex == 0 ? 0x7CFC00 : 0xFFFFFF; // Lawn green for items } }, MyModBlocks.coloredGrass, MyModBlocks.coloredLeaves); ``` -------------------------------- ### Register Common Event Handlers Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Illustrates using @EventBusSubscriber for common event registration, applicable to both client and server sides, with control over the event phase. ```java @EventBusSubscriber(phase = Phase.PRE) public class CommonEventHandler { @SubscribeEvent public static void onBlockBreak(BlockEvent.BreakEvent event) { // Handle block breaking on both sides } } ``` -------------------------------- ### Registering Block Colors with IBlockColor Source: https://github.com/gtnewhorizons/gtnhlib/blob/master/models.md Use this to register custom color multipliers for blocks. It allows defining different colors for different tint indices, applicable to both world rendering and item stacks. ```java BlockColor.registerBlockColors(new IBlockColor() { @Override public int colorMultiplier(IBlockAccess world, int x, int y, int z, int tintIndex) { // Return red for main layer, green for secondary return tintIndex == 0 ? 0xFF0000 : 0x00FF00; } @Override public int colorMultiplier(ItemStack stack, int tintIndex) { // Return blue for main layer, yellow for secondary return tintIndex == 0 ? 0x0000FF : 0xFFFF00; } }, ModBlocks.MY_CUSTOM_BLOCK); ``` -------------------------------- ### Efficient Vertex Buffer Object (VBO) Management Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Utilize VertexBuffer for efficient vertex data management in rendering. Supports static, dynamic, and stream uploads with partial drawing capabilities. Ensure proper cleanup. ```java import com.gtnewhorizon.gtnhlib.client.renderer.vbo.VertexBuffer; import com.gtnewhorizon.gtnhlib.client.renderer.vertex.VertexFormat; import org.lwjgl.opengl.GL11; import java.nio.ByteBuffer; // Define vertex format (position + color + UV) VertexFormat format = VertexFormat.builder() .addElement(VertexFormatElement.POSITION_3F) .addElement(VertexFormatElement.COLOR_4UB) .addElement(VertexFormatElement.TEX_2F) .build(); // Create vertex buffer VertexBuffer vbo = new VertexBuffer(format, GL11.GL_TRIANGLES); // Prepare vertex data ByteBuffer buffer = BufferUtils.createByteBuffer(format.getVertexSize() * vertexCount); // Fill buffer with vertex data... // Upload static geometry vbo.upload(buffer, vertexCount); // For frequently updated data vbo.uploadDynamic(buffer, vertexCount); // For single-use data vbo.uploadStream(buffer, vertexCount); // Render vbo.setupState(); vbo.draw(); vbo.cleanupState(); // Partial draw vbo.setupState(); vbo.draw(0, 100); // Draw first 100 vertices vbo.cleanupState(); // Cleanup vbo.delete(); ``` -------------------------------- ### BlockState JSON Variants Source: https://context7.com/gtnewhorizons/gtnhlib/llms.txt Define different block models based on block state properties like facing direction. Ensure all possible states are covered. ```json { "variants": { "facing=north": { "model": "mymod:block/machine_north" }, "facing=south": { "model": "mymod:block/machine_south", "y": 180 }, "facing=west": { "model": "mymod:block/machine_west", "y": 270 }, "facing=east": { "model": "mymod:block/machine_east", "y": 90 } } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.