package gregtech.api.util; import com.gtnewhorizon.structurelib.StructureLibAPI; import com.gtnewhorizon.structurelib.structure.IStructureElement; import com.gtnewhorizon.structurelib.structure.IStructureElementNoPlacement; import gregtech.api.GregTech_API; import gregtech.api.enums.HeatingCoilLevel; import gregtech.api.interfaces.IHeatingCoil; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.common.blocks.GT_Block_Casings5; import net.minecraft.block.Block; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.world.World; import java.util.function.BiConsumer; import java.util.function.BiPredicate; import java.util.function.Function; import static com.gtnewhorizon.structurelib.StructureLibAPI.HINT_BLOCK_META_GENERIC_11; public class GT_StructureUtility { private GT_StructureUtility() { throw new AssertionError("Not instantiable"); } public static IStructureElementNoPlacement ofHatchAdder(IGT_HatchAdder IGT_HatchAdder, int textureIndex, int dots) { return ofHatchAdder(IGT_HatchAdder, textureIndex, StructureLibAPI.getBlockHint(), dots - 1); } public static IStructureElementNoPlacement ofHatchAdder(IGT_HatchAdder IGT_HatchAdder, int textureIndex, Block hintBlock, int hintMeta) { if (IGT_HatchAdder == null || hintBlock == null) { throw new IllegalArgumentException(); } return new IStructureElementNoPlacement() { @Override public boolean check(T t, World world, int x, int y, int z) { TileEntity tileEntity = world.getTileEntity(x, y, z); return tileEntity instanceof IGregTechTileEntity && IGT_HatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) textureIndex); } @Override public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { StructureLibAPI.hintParticle(world, x, y, z, hintBlock, hintMeta); return true; } }; } public static IStructureElement ofHatchAdderOptional(IGT_HatchAdder IGT_HatchAdder, int textureIndex, int dots, Block placeCasing, int placeCasingMeta) { return ofHatchAdderOptional(IGT_HatchAdder, textureIndex, StructureLibAPI.getBlockHint(), dots - 1, placeCasing, placeCasingMeta); } public static IStructureElement ofHatchAdderOptional(IGT_HatchAdder IGT_HatchAdder, int textureIndex, Block hintBlock, int hintMeta, Block placeCasing, int placeCasingMeta) { if (IGT_HatchAdder == null || hintBlock == null) { throw new IllegalArgumentException(); } return new IStructureElement() { @Override public boolean check(T t, World world, int x, int y, int z) { TileEntity tileEntity = world.getTileEntity(x, y, z); Block worldBlock = world.getBlock(x, y, z); return (tileEntity instanceof IGregTechTileEntity && IGT_HatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) textureIndex)) || (worldBlock == placeCasing && worldBlock.getDamageValue(world, x, y, z) == placeCasingMeta); } @Override public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { StructureLibAPI.hintParticle(world, x, y, z, hintBlock, hintMeta); return true; } @Override public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { world.setBlock(x, y, z, placeCasing, placeCasingMeta, 2); return true; } }; } /** * Assume all coils accepted. * @see #ofCoil(BiPredicate, Function) */ public static IStructureElement ofCoil(BiConsumer heatingCoilSetter, Function heatingCoilGetter) { return ofCoil((t, l) -> { heatingCoilSetter.accept(t, l); return true; }, heatingCoilGetter); } /** * Heating coil structure element. * @param heatingCoilSetter Notify the controller of this new coil. * Got called exactly once per coil. * Might be called less times if structure test fails. * If the setter returns false then it assumes the coil is rejected. * @param heatingCoilGetter Get the current heating level. Null means no coil recorded yet. */ public static IStructureElement ofCoil(BiPredicate heatingCoilSetter, Function heatingCoilGetter) { if (heatingCoilSetter == null || heatingCoilGetter == null) { throw new IllegalArgumentException(); } return new IStructureElement() { @Override public boolean check(T t, World world, int x, int y, int z) { Block block = world.getBlock(x, y, z); if (!(block instanceof IHeatingCoil)) return false; HeatingCoilLevel existingLevel = heatingCoilGetter.apply(t), newLevel = ((IHeatingCoil) block).getCoilHeat(world.getBlockMetadata(x, y, z)); if (existingLevel == null || existingLevel == HeatingCoilLevel.None) { return heatingCoilSetter.test(t, newLevel); } else { return newLevel == existingLevel; } } @Override public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { StructureLibAPI.hintParticle(world, x, y, z, GregTech_API.sBlockCasings5, getMeta(trigger)); return true; } private int getMeta(ItemStack trigger) { return GT_Block_Casings5.getMetaFromCoilHeat(HeatingCoilLevel.getFromTier((byte) Math.min(HeatingCoilLevel.size(), Math.max(0, trigger.stackSize)))); } @Override public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { return world.setBlock(x, y, z, GregTech_API.sBlockCasings5, getMeta(trigger), 3); } }; } }