### Hint Particle API Example Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Spawns visual hint particles to guide players. Use StructureLibAPI.startHinting() and endHinting() to group particles. ```java import com.gtnewhorizon.structurelib.StructureLibAPI; public class HintParticleExample { public void spawnHints(World world, int x, int y, int z) { // Start a hint batch (for hologram grouping) StructureLibAPI.startHinting(world); // Spawn hint from block texture StructureLibAPI.hintParticle(world, x, y, z, Blocks.iron_block, 0); // Spawn hint with custom tint (RGBA, 0-255) short[] redTint = {255, 100, 100, 255}; StructureLibAPI.hintParticleTinted(world, x, y+1, z, Blocks.stone, 0, redTint); // End the batch StructureLibAPI.endHinting(world); } public void markError(EntityPlayer player, World world, int x, int y, int z) { // Mark a hint particle as errored (changes color to indicate problem) boolean updated = StructureLibAPI.markHintParticleError(player, world, x, y, z); } public void updateTint(EntityPlayer player, World world, int x, int y, int z) { // Update existing hint particle color short[] newTint = {100, 255, 100, 255}; // green StructureLibAPI.updateHintParticleTint(player, world, x, y, z, newTint); } } ``` -------------------------------- ### Hint Particle API Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Provides methods for spawning visual hint particles to guide players in placing blocks. ```APIDOC ## Hint Particle API The `StructureLibAPI` provides methods for spawning visual hint particles that show players where to place blocks. ### Spawn Hints #### `hintParticle(World world, int x, int y, int z, Block block, int meta)` Spawns a hint particle using the texture of the specified block. #### `hintParticleTinted(World world, int x, int y, int z, Block block, int meta, short[] tint)` Spawns a hint particle with a custom tint (RGBA, 0-255). ### Batching Hints #### `startHinting(World world)` Starts a batch of hint particles, useful for grouping holograms. #### `endHinting(World world)` Ends the current batch of hint particles. ### Error Handling #### `markHintParticleError(EntityPlayer player, World world, int x, int y, int z)` Marks a hint particle as errored, changing its color to indicate a problem. - **Return Value**: `boolean` - `true` if the particle was updated, `false` otherwise. ### Tint Updates #### `updateHintParticleTint(EntityPlayer player, World world, int x, int y, int z, short[] newTint)` Updates the color of an existing hint particle. ### Example Usage ```java import com.gtnewhorizon.structurelib.StructureLibAPI; public class HintParticleExample { public void spawnHints(World world, int x, int y, int z) { // Start a hint batch (for hologram grouping) StructureLibAPI.startHinting(world); // Spawn hint from block texture StructureLibAPI.hintParticle(world, x, y, z, Blocks.iron_block, 0); // Spawn hint with custom tint (RGBA, 0-255) short[] redTint = {255, 100, 100, 255}; StructureLibAPI.hintParticleTinted(world, x, y+1, z, Blocks.stone, 0, redTint); // End the batch StructureLibAPI.endHinting(world); } public void markError(EntityPlayer player, World world, int x, int y, int z) { // Mark a hint particle as errored (changes color to indicate problem) boolean updated = StructureLibAPI.markHintParticleError(player, world, x, y, z); } public void updateTint(EntityPlayer player, World world, int x, int y, int z) { // Update existing hint particle color short[] newTint = {100, 255, 100, 255}; // green StructureLibAPI.updateHintParticleTint(player, world, x, y, z, newTint); } } ``` ``` -------------------------------- ### Survival Auto-Build Example Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Implements survival auto-building by consuming items from player inventory. Requires implementing ISurvivalConstructable. ```java import com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable; import com.gtnewhorizon.structurelib.structure.IItemSource; import com.gtnewhorizon.structurelib.structure.ISurvivalBuildEnvironment; public class SurvivalBuildableMachine extends TileEntity implements ISurvivalConstructable { private static final IStructureDefinition STRUCTURE = IStructureDefinition.builder() .addShape("main", new String[][] { { "CCC", "C~C", "CCC" }, { "CCC", "C-C", "CCC" }, { "CCC", "CCC", "CCC" } }) .addElement('C', ofBlock(Blocks.iron_block, 0)) .build(); @Override public void construct(ItemStack stackSize, boolean hintsOnly) { STRUCTURE.buildOrHints(this, stackSize, "main", getWorldObj(), ExtendedFacing.of(ForgeDirection.NORTH), xCoord, yCoord, zCoord, 1, 1, 0, hintsOnly); } @Override public int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) { // Returns: -1 if complete, otherwise count of placed elements return STRUCTURE.survivalBuild( this, stackSize, "main", getWorldObj(), ExtendedFacing.of(ForgeDirection.NORTH), xCoord, yCoord, zCoord, 1, 1, 0, // offset A, B, C elementBudget, // max elements to place this tick env, // contains IItemSource and EntityPlayer true // check after place ); } @Override public String[] getStructureDescription(ItemStack stackSize) { return new String[] { "3x3x3 iron block structure", "Controller in center of middle layer" }; } } ``` -------------------------------- ### Constructable Interfaces Source: https://github.com/gtnewhorizons/structurelib/blob/master/src/main/javadoc/overview.html Interfaces for implementing autoplacing and particle emitting in creative and survival modes. ```APIDOC ## Constructable Interfaces - **`com.gtnewhorizon.structurelib.alignment.constructable.IConstructable`** - Interface for tile entities that support creative autoplacing and hint particle emitting. - Typically requires a backing `IStructureDefinition` and utilizes its `build()` or `hints()` methods. - **`com.gtnewhorizon.structurelib.alignment.constructable.ISurvivalConstructable`** - An enhancement over `IConstructable` for tile entities that also support survival autoplacing. - Requires a backing `IStructureDefinition` and utilizes its `survivalBuild()` method. - **`com.gtnewhorizon.structurelib.alignment.constructable.IConstructableProvider`** - Interface for tile entities that delegate constructable or survival constructable functionality to another class. - Primarily used to support gregtech meta tile entity systems. - Returns null if the delegate does not exist. ``` -------------------------------- ### Channel System for Multi-Tier Hints Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Registers channel descriptions and items for multi-tier hints. Use withChannel and ofBlocksTiered for structure elements. ```java import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; import static com.gtnewhorizon.structurelib.structure.StructureUtility.*; public class ChannelExample { // Register channel descriptions (call during mod init) public static void registerChannels() { StructureLibAPI.registerChannelDescription( "coil_tier", // channel name "mymod", // mod id "mymod.channel.coil" // localization key ); // Register items for channel values StructureLibAPI.registerChannelItem( "coil_tier", "mymod", 1, new ItemStack(Items.iron_ingot) ); StructureLibAPI.registerChannelItem( "coil_tier", "mymod", 2, new ItemStack(Items.gold_ingot) ); } // Use channel in structure element private static final IStructureElement CHANNELED = withChannel( "coil_tier", ofBlocksTiered( (block, meta) -> block == Blocks.iron_block ? 1 : block == Blocks.gold_block ? 2 : null, Arrays.asList( Pair.of(Blocks.iron_block, 0), Pair.of(Blocks.gold_block, 0) ), -1, (t, tier) -> t.tier = tier, t -> t.tier ) ); ``` -------------------------------- ### Channel System for Multi-Tier Hints Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Allows different hint variations based on trigger item stack size, useful for showing different tier options. ```APIDOC ## Channel System for Multi-Tier Hints The channel system allows different hint variations based on trigger item stack size, useful for showing different tier options. ### Registering Channel Descriptions Call this during mod initialization. #### `StructureLibAPI.registerChannelDescription(String channelName, String modId, String localizationKey)` Registers a description for a channel. - **channelName**: The unique name of the channel. - **modId**: The ID of the mod registering the channel. - **localizationKey**: The localization key for the channel's display name. ### Registering Items for Channel Values #### `StructureLibAPI.registerChannelItem(String channelName, String modId, int tier, ItemStack itemStack)` Associates an item stack with a specific tier within a channel. - **channelName**: The name of the channel. - **modId**: The ID of the mod registering the item. - **tier**: The tier value associated with the item. - **itemStack**: The `ItemStack` representing this tier. ### Using Channels in Structure Elements Use the `withChannel` helper to create channel-aware structure elements. ```java import com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor; import static com.gtnewhorizon.structurelib.structure.StructureUtility.*; public class ChannelExample { // Register channel descriptions (call during mod init) public static void registerChannels() { StructureLibAPI.registerChannelDescription( "coil_tier", // channel name "mymod", // mod id "mymod.channel.coil" // localization key ); // Register items for channel values StructureLibAPI.registerChannelItem( "coil_tier", "mymod", 1, new ItemStack(Items.iron_ingot) ); StructureLibAPI.registerChannelItem( "coil_tier", "mymod", 2, new ItemStack(Items.gold_ingot) ); } // Use channel in structure element private static final IStructureElement CHANNELED = withChannel( "coil_tier", ofBlocksTiered( (block, meta) -> block == Blocks.iron_block ? 1 : block == Blocks.gold_block ? 2 : null, Arrays.asList( Pair.of(Blocks.iron_block, 0), Pair.of(Blocks.gold_block, 0) ), -1, (t, tier) -> t.tier = tier, t -> t.tier ) ); } ``` ``` -------------------------------- ### PartitionBy with Map Lookup Source: https://context7.com/gtnewhorizons/structurelib/llms.txt The `partitionBy()` method allows selecting an element based on a key extracted from the tile, using a map for lookups. A default fallback element is provided for unmapped keys. ```java .addElement('D', partitionBy( tile -> tile.mode, // key extractor ImmutableMap.of( 0, ofBlock(Blocks.stone, 0), 1, ofBlock(Blocks.iron_block, 0), 2, ofBlock(Blocks.gold_block, 0) ), ofBlock(Blocks.dirt, 0) // default fallback )) ``` -------------------------------- ### Inventory and Alignment Utilities Source: https://github.com/gtnewhorizons/structurelib/blob/master/src/main/javadoc/overview.html Utilities for inventory management and alignment frameworks. ```APIDOC ## Inventory and Alignment Utilities - **`com.gtnewhorizon.structurelib.util.InventoryUtility`** - Backs the standard implementations of `com.gtnewhorizon.structurelib.structure.IItemSource`. - Allows registration of new inventory providers or extractors for survival auto-placing. - **`com.gtnewhorizon.structurelib.alignment.IAlignmentProvider`, `com.gtnewhorizon.structurelib.alignment.IAlignment`, `com.gtnewhorizon.structurelib.alignment.IAlignmentLimits`** - Interfaces used for implementing rotation logic. - Provide a framework for rotating blocks. - Can be skipped if rotation is handled through `ExtendedFacing` or other means. ``` -------------------------------- ### Deferred Element Instantiation Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Use `defer()` to recompute element configuration every time it's accessed. This is suitable for elements whose properties change dynamically based on runtime state. ```java .addElement('C', defer(tile -> { return tile.mode == 0 ? ofBlock(Blocks.stone, 0) : ofBlock(Blocks.brick_block, 0); })) ``` -------------------------------- ### Register Channel Descriptions via IMC Source: https://github.com/gtnewhorizons/structurelib/blob/master/src/main/javadoc/overview.html Use this method to register channel descriptions for your mod. It requires sending an IMC message to 'structurelib' with the 'register_channel' action and an NBTCompound containing channel names and their localization keys. ```java NBTTagCompound command = new NBTTagCompound(); NBTTagList tags = new NBTTagList(); String[] channels = {"channel_1", "channel_2"}; for (String channel : channels) { NBTTagCompound tag = new NBTTagCompound(); tag.setString("Channel", channel); tag.setString("Description", "channels.my_mod." + channel); tags.appendTag(tag); } command.setTag("Channels", tags); FMLInterModComms.sendMessage("structurelib", "register_channel", command); ``` -------------------------------- ### Survival Auto-Build Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Enables automatic structure construction in survival mode by consuming items from player inventory. ```APIDOC ## Survival Auto-Build The `survivalBuild()` method enables automatic structure construction in survival mode by consuming items from player inventory. ### Method `survivalConstruct` ### Parameters - **stackSize** (ItemStack) - The stack of items to use for construction. - **elementBudget** (int) - The maximum number of elements to place this tick. - **env** (ISurvivalBuildEnvironment) - The environment containing item sources and the player. ### Return Value - **int**: -1 if complete, otherwise the count of placed elements. ### Example Usage (within a TileEntity implementing ISurvivalConstructable) ```java @Override public int survivalConstruct(ItemStack stackSize, int elementBudget, ISurvivalBuildEnvironment env) { // Returns: -1 if complete, otherwise count of placed elements return STRUCTURE.survivalBuild( this, stackSize, "main", getWorldObj(), ExtendedFacing.of(ForgeDirection.NORTH), xCoord, yCoord, zCoord, 1, 1, 0, // offset A, B, C elementBudget, // max elements to place this tick env, // contains IItemSource and EntityPlayer true // check after place ); } ``` ### Structure Description ```java @Override public String[] getStructureDescription(ItemStack stackSize) { return new String[] { "3x3x3 iron block structure", "Controller in center of middle layer" }; } ``` ``` -------------------------------- ### Add StructureLib Dependency (Gradle) Source: https://github.com/gtnewhorizons/structurelib/blob/master/README.md Add this to your build.gradle file to include StructureLib as a dependency. Replace 'master-SNAPSHOT' with a specific commit hash or tag for stability. ```groovy dependencies { compile "com.github.GTNewHorizons:StructureLib:master-SNAPSHOT:deobf" } repositories { maven { name = "jitpack.io" url = "https://jitpack.io" } } ``` -------------------------------- ### Structure Elements with ofBlock Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Use ofBlock() and its variants to define structure elements that accept specific block and metadata combinations, with options for hint blocks. ```java import static com.gtnewhorizon.structurelib.structure.StructureUtility.*; // Basic: accept iron block with meta 0 IStructureElement ironElement = ofBlock(Blocks.iron_block, 0); // Accept iron block, but show gold block as hint for building guide IStructureElement ironWithGoldHint = ofBlock( Blocks.iron_block, 0, // accepted block Blocks.gold_block, 0 // hint block shown in hologram ); // Accept any meta value of a block IStructureElement anyWool = ofBlockAnyMeta(Blocks.wool); // Accept any meta, show specific meta as hint IStructureElement woolHint = ofBlockAnyMeta(Blocks.wool, Blocks.wool, 14); // red wool hint // Multiple blocks with same meta per block Map casings = new HashMap<>(); casings.put(Blocks.stone, 0); casings.put(Blocks.cobblestone, 0); IStructureElement multiBlock = ofBlocksFlat(casings, Blocks.stone, 0); ``` -------------------------------- ### StructureLib API Core Utilities Source: https://github.com/gtnewhorizons/structurelib/blob/master/src/main/javadoc/overview.html Core utility class for implementing new IStructureElements and handling rotation. ```APIDOC ## StructureLib API Core Utilities - **`com.gtnewhorizon.structurelib.StructureLibAPI`** - Contains low-level utilities essential for implementing new `com.gtnewhorizon.structurelib.structure.IStructureElement`. - Also provides methods necessary for implementing rotation logic. - **Important:** If a method with the same name exists in other classes, prioritize using methods from `StructureLibAPI` to ensure compatibility and abstraction. ``` -------------------------------- ### Structure Utility and Standard Elements Source: https://github.com/gtnewhorizons/structurelib/blob/master/src/main/javadoc/overview.html Information about StructureUtility, which provides standard IStructureElements for basic block handling and composition. ```APIDOC ## Structure Utility - **`com.gtnewhorizon.structurelib.structure.StructureUtility`** - This class serves as a standard library for `com.gtnewhorizon.structurelib.structure.IStructureElement`. - It contains elements for basic block handling and for composing these basic elements into more complex structures. ``` -------------------------------- ### Register Channel Indicator Items via IMC Source: https://github.com/gtnewhorizons/structurelib/blob/master/src/main/javadoc/overview.html Register indicator items for channels by sending an IMC message to 'structurelib' with the 'register_channel_item' action. This involves an NBTCompound containing a list of items, each with its ItemStack and associated channel information (name and value). ```java NBTTagCompound command = new NBTTagCompound(); NBTTagList items = new NBTTagList(); int[] metas = {0, 1, 2}; for (int meta : metas) { NBTTagCompound tag = new NBTTagCompound(); tag.setTag("Item", new ItemStack(Blocks.sandstone, 1, meta).writeToNBT(new NBTTagCompound())); NBTTagList channels = new NBTTagList(); NBTTagCompound channel = new NBTTagCompound(); channel.setString("Channel", "sandstone"); channel.setInteger("Value", meta + 1); channels.appendTag(channel); tag.setTag("Channels", channels); items.appendTag(tag); } command.setTag("Items", items); FMLInterModComms.sendMessage("structurelib", "register_channel_item", command); ``` -------------------------------- ### Custom Block Validation with `ofBlockAdder` Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Implement custom logic for block validation using `ofBlockAdder`. This is useful when simple block matching is insufficient, allowing you to define specific acceptance criteria and maintain state like counts. ```java import com.gtnewhorizon.structurelib.structure.adders.IBlockAdder; import com.gtnewhorizon.structurelib.structure.adders.ITileAdder; public class CustomValidationMachine extends TileEntity { private int hatchCount = 0; private static final IStructureDefinition STRUCTURE = IStructureDefinition.builder() .addShape("main", new String[][] { { "AAA", "AHA", "AAA" } }) .addElement('A', ofBlock(Blocks.stone, 0)) // Custom block adder with complex logic .addElement('H', ofBlockAdder( (tile, block, meta) -> { // Accept hoppers or chests, count them if (block == Blocks.hopper || block == Blocks.chest) { tile.hatchCount++; return true; } return false; }, Blocks.hopper, 0 // hint block for preview )) .build(); // For tile entity validation private static final IStructureElement TILE_ELEMENT = ofTileAdder( (tile, tileEntity) -> { if (tileEntity instanceof TileEntityChest) { // Custom validation on tile entity return ((TileEntityChest) tileEntity).numPlayersUsing == 0; } return false; }, Blocks.chest, 0 // hint ); // For specific tile entity class private static final IStructureElement SPECIFIC_TILE = ofSpecificTileAdder( (tile, chest) -> chest.getSizeInventory() > 0, TileEntityChest.class, Blocks.chest, 0 ); } ``` -------------------------------- ### Structure Definition and Elements Source: https://github.com/gtnewhorizons/structurelib/blob/master/src/main/javadoc/overview.html Details on IStructureDefinition for multi-block structures and IStructureElement for defining accepted blocks. ```APIDOC ## StructureLib API Overview This API provides classes and interfaces for defining and managing multi-block structures. ### Key API Classes - **`com.gtnewhorizon.structurelib.structure.IStructureDefinition`** - Represents the structure definition for a multi-block. Each multi-block will have one instance of this interface. - **`com.gtnewhorizon.structurelib.structure.IStructureElement`** - Defines which blocks are accepted for a structure. Used in conjunction with `IStructureDefinition`. ``` -------------------------------- ### Multi-channel Input Structure Element Source: https://github.com/gtnewhorizons/structurelib/blob/master/src/main/javadoc/overview.html Implement a structure element that requires both facing and arbitrary meta tile entity input. It uses the master channel for facing and the 'id' channel for meta tile entity ID. Ensure the item taken matches the filter criteria. ```java import com.gtnewhorizon.structurelib.structure.IStructureElement; public class MyHatchElement implements IStructureElement { //... @Override public PlaceResult survivalPlaceBlock( Object o, World world, int x, int y, int z, ItemStack trigger, IItemSource s, EntityPlayerMP actor, Consumer chatter) { if (shouldSkip(o, world, x, y, z)) return PlaceResult.SKIP; if (!StructureLibAPI.isBlockTriviallyReplaceable(world, x, y, z, actor)) return PlaceResult.REJECT; ItemStack taken = s.takeOne(filterByID(ChannelDataAccessor.getChannelData(trigger, "id")).andThen(filterByFacing(trigger.stackSize))); if (taken == null) return PlaceResult.REJECT; return StructureUtility.survivalPlaceBlock(taken, ItemStackPredicate.NBTMode.IGNORE, null, true, world, x, y, z, s, actor); } } ``` -------------------------------- ### Element Pass/Fail Callbacks Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Use `onElementPass()` and `onElementFail()` to execute callbacks when an element check passes or fails, respectively. These are useful for logging or triggering side effects. ```java private static final IStructureElement WITH_CALLBACK = onElementPass( tile -> System.out.println("Element check passed!"), ofBlock(Blocks.stone, 0) ); ``` ```java private static final IStructureElement ON_FAIL = onElementFail( tile -> System.out.println("Element check failed!"), ofBlock(Blocks.obsidian, 0) ); ``` -------------------------------- ### Lazy Element Instantiation Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Employ `lazy()` for elements whose configuration is computed only once upon first access. This is efficient when element properties are static after the first use. ```java .addElement('A', lazy(() -> ofBlock(Blocks.stone, 0))) ``` ```java .addElement('B', lazy(tile -> { if (tile.mode == 1) return ofBlock(Blocks.gold_block, 0); return ofBlock(Blocks.iron_block, 0); })) ``` -------------------------------- ### Conditional Element Activation Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Use `onlyIf()` to activate an element only when a specific condition is met. The condition is provided as a tile-based predicate. ```java private static final IStructureElement CONDITIONAL = onlyIf( tile -> tile.advancedMode, ofBlock(Blocks.diamond_block, 0) ); ``` -------------------------------- ### Define Multiblock Structure with Builder Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Use IStructureDefinition.builder() to define a multiblock structure by mapping characters to specific blocks and elements. The addShape() method defines the 3D layout, and addElement() binds characters to block requirements. ```java import static com.gtnewhorizon.structurelib.structure.StructureUtility.*; public class MyMultiblockMachine extends TileEntity implements IConstructable { private static final IStructureDefinition STRUCTURE = IStructureDefinition.builder() .addShape("main", new String[][] { // Layer 0 (bottom) - 'C' is casing, 'H' is hatch, '~' is controller { "CCC", "CHC", "CCC" }, // Layer 1 (middle) { "C~C", "C-C", "CCC" }, // Layer 2 (top) { "CCC", "CCC", "CCC" } }) .addElement('C', ofBlock(Blocks.iron_block, 0)) .addElement('H', ofBlock(Blocks.hopper, 0)) .build(); @Override public void construct(ItemStack stackSize, boolean hintsOnly) { STRUCTURE.buildOrHints(this, stackSize, "main", getWorldObj(), ExtendedFacing.of(ForgeDirection.NORTH), xCoord, yCoord, zCoord, 1, 1, 0, // offset A, B, C from controller position hintsOnly); } } ``` -------------------------------- ### Generate Structure Definition Code Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Use `getPseudoJavaCode()` to generate structure definition code from an in-world structure. Specify world, facing, base position, offsets, a tile entity classifier, size, and transpose option. Returns a string representation of the structure. ```java import com.gtnewhorizon.structurelib.structure.StructureUtility; public class StructureScanner { public String scanStructure(World world, int baseX, int baseY, int baseZ) { return StructureUtility.getPseudoJavaCode( world, ExtendedFacing.NORTH_NORMAL_NONE, baseX, baseY, baseZ, // base position 0, 0, 0, // base offset A, B, C tileEntity -> { // tile entity classifier if (tileEntity instanceof TileEntityChest) return "chest"; return null; // use default class name }, 5, 5, 5, // size A, B, C false // transpose output ); // Returns string like: // Blocks: // A -> ofBlock...(tile.stone, 0, ...); // B -> ofBlock...(tile.chest, 0, ...); // // Offsets: 0 0 0 // // Normal Scan: // new String[][]{{ // "AAA", // "ABA", // "AAA" // }} } } ``` -------------------------------- ### Structure Element Definition with Channels Source: https://github.com/gtnewhorizons/structurelib/blob/master/src/main/javadoc/overview.html Define structure elements for different parts of a multi-block structure, assigning specific channels like 'casing', 'pipe', and 'coil' to different components. This allows for modular design and clear separation of concerns within the structure. ```java .addElement('a', shellStructureElement()) .addElement('b', withChannel("casing", machineCasingStructureElement())) .addElement('c', withChannel("pipe", pipeCasingStructureElement())) .addElement('d', withChannel("coil", coilStructureElement())) ``` -------------------------------- ### ExtendedFacing for Orientation Source: https://context7.com/gtnewhorizons/structurelib/llms.txt The `ExtendedFacing` enum manages all 96 possible orientations, combining direction, rotation, and flip. It's used for structure placement and validation. ```java import com.gtnewhorizon.structurelib.alignment.enumerable.ExtendedFacing; import com.gtnewhorizon.structurelib.alignment.enumerable.Rotation; import com.gtnewhorizon.structurelib.alignment.enumerable.Flip; import net.minecraftforge.common.util.ForgeDirection; public class OrientedMachine extends TileEntity { private ExtendedFacing facing = ExtendedFacing.DEFAULT; public void setFacing(ForgeDirection direction, Rotation rotation, Flip flip) { facing = ExtendedFacing.of(direction, rotation, flip); } public void rotateFacing() { facing = facing.with(facing.getRotation().next()); } public void flipFacing() { facing = facing.getOppositeFlip(); } // Convert relative (A,B,C) offset to world (X,Y,Z) public int[] getWorldOffset(int a, int b, int c) { int[] abc = {a, b, c}; int[] xyz = new int[3]; facing.getWorldOffset(abc, xyz); return xyz; } // Check structure with current orientation public boolean checkStructure(IStructureDefinition structure) { return structure.check(this, "main", getWorldObj(), facing, xCoord, yCoord, zCoord, 1, 1, 0, false); } } ``` -------------------------------- ### Element Chaining with OR Logic Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Use `ofChain()` to create OR logic between elements, allowing any of the specified blocks to satisfy the condition. This is useful for accepting multiple block types. ```java import static com.gtnewhorizon.structurelib.structure.StructureUtility.*; public class ConditionalStructure extends TileEntity { private boolean advancedMode = false; private static final IStructureDefinition STRUCTURE = IStructureDefinition.builder() .addShape("main", new String[][] { { "AAA", "A~A", "AAA" } }) // Chain: accepts glass OR iron block (first match wins) .addElement('A', ofChain( ofBlock(Blocks.glass, 0), ofBlock(Blocks.iron_block, 0), ofBlock(Blocks.gold_block, 0) )) .build(); // Conditional element - only validates in advanced mode private static final IStructureElement CONDITIONAL = onlyIf( tile -> tile.advancedMode, ofBlock(Blocks.diamond_block, 0) ); // With callbacks on success/failure private static final IStructureElement WITH_CALLBACK = onElementPass( tile -> System.out.println("Element check passed!"), ofBlock(Blocks.stone, 0) ); private static final IStructureElement ON_FAIL = onElementFail( tile -> System.out.println("Element check failed!"), ofBlock(Blocks.obsidian, 0) ); } ``` -------------------------------- ### Structure Events Source: https://github.com/gtnewhorizons/structurelib/blob/master/src/main/javadoc/overview.html Represents events related to structure manipulation. ```APIDOC ## Structure Events - **`com.gtnewhorizon.structurelib.StructureEvent`** - This class is related to events triggered during structure operations. ``` -------------------------------- ### Check Multiblock Structure Validity Source: https://context7.com/gtnewhorizons/structurelib/llms.txt The check() method validates if the blocks in the world match the defined structure. It can optionally support checking unloaded chunks. ```java public class MultiblockController extends TileEntity { private static final IStructureDefinition STRUCTURE = IStructureDefinition.builder() .addShape("reactor", transpose(new String[][] { { "AAA", "ABA", "AAA" }, { "A~A", "B-B", "AAA" }, { "AAA", "ABA", "AAA" } })) .addElement('A', ofBlock(Blocks.stone, 0)) .addElement('B', ofBlock(Blocks.glass, 0)) .build(); private boolean isStructureComplete = false; public boolean checkStructure() { isStructureComplete = STRUCTURE.check( this, // context object "reactor", // piece name getWorldObj(), // world ExtendedFacing.of(getFacing()), // orientation xCoord, yCoord, zCoord, // base position 1, 1, 1, // offset A, B, C false // don't force check unloaded chunks ); return isStructureComplete; } } ``` -------------------------------- ### Channel Data Accessor Source: https://github.com/gtnewhorizons/structurelib/blob/master/src/main/javadoc/overview.html Accessor class for channel data held on a trigger item. ```APIDOC ## Channel Data Accessor - **`com.gtnewhorizon.structurelib.alignment.constructable.ChannelDataAccessor`** - Contains accessors for channel data stored on a trigger item. - Refer to the [channels](#channels) section for more information. ``` -------------------------------- ### Tiered Block Element with `ofBlocksTiered` Source: https://context7.com/gtnewhorizons/structurelib/llms.txt Use `ofBlocksTiered` to define structure elements that can be one of several block types, each corresponding to a different tier. The tier is determined by a provided extractor function, and setter/getter functions manage the tier state within the tile entity. ```java import org.apache.commons.lang3.tuple.Pair; public class TieredMachine extends TileEntity { private int coilTier = -1; // -1 means not set private static final IStructureDefinition STRUCTURE = IStructureDefinition.builder() .addShape("main", new String[][] { { "CCC", "C~C", "CCC" } }) .addElement('C', ofBlocksTiered( // Tier extractor: returns tier from block, null if invalid (block, meta) -> { if (block == Blocks.iron_block) return 1; if (block == Blocks.gold_block) return 2; if (block == Blocks.diamond_block) return 3; return null; // reject unknown blocks }, // List of (block, meta) pairs for each tier (for hints) Arrays.asList( Pair.of(Blocks.iron_block, 0), Pair.of(Blocks.gold_block, 0), Pair.of(Blocks.diamond_block, 0) ), -1, // notSet value - returned by getter when no tier determined (tile, tier) -> tile.coilTier = tier, // setter tile -> tile.coilTier // getter )) .build(); public boolean checkStructure() { coilTier = -1; // Reset before check boolean valid = STRUCTURE.check(this, "main", getWorldObj(), ExtendedFacing.of(getFacing()), xCoord, yCoord, zCoord, 1, 0, 0, false); if (valid && coilTier > 0) { System.out.println("Structure valid with tier: " + coilTier); } return valid; } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.