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.enums.Materials; import gregtech.api.enums.OrePrefixes; import gregtech.api.interfaces.IHeatingCoil; import gregtech.api.interfaces.tileentity.IGregTechTileEntity; import gregtech.api.metatileentity.BaseMetaPipeEntity; import gregtech.api.metatileentity.implementations.GT_MetaPipeEntity_Frame; import gregtech.common.blocks.GT_Block_Casings5; import net.minecraft.block.Block; import net.minecraft.init.Items; import net.minecraft.item.ItemBlock; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.IIcon; import net.minecraft.world.World; import java.util.Arrays; import java.util.function.BiConsumer; import java.util.function.BiPredicate; import java.util.function.Function; public class GT_StructureUtility { private GT_StructureUtility() { throw new AssertionError("Not instantiable"); } public static IStructureElementNoPlacement ofHatchAdder(IGT_HatchAdder aHatchAdder, int aTextureIndex, int aDots) { return ofHatchAdder(aHatchAdder, aTextureIndex, StructureLibAPI.getBlockHint(), aDots - 1); } public static IStructureElement ofFrame(Materials aFrameMaterial) { if (aFrameMaterial == null) throw new IllegalArgumentException(); return new IStructureElement() { private IIcon[] mIcons; @Override public boolean check(T t, World world, int x, int y, int z) { TileEntity tBase = world.getTileEntity(x, y, z); if (tBase instanceof BaseMetaPipeEntity) { BaseMetaPipeEntity tPipeBase = (BaseMetaPipeEntity) tBase; if (tPipeBase.isInvalidTileEntity()) return false; if (tPipeBase.getMetaTileEntity() instanceof GT_MetaPipeEntity_Frame) return aFrameMaterial == ((GT_MetaPipeEntity_Frame) tPipeBase.getMetaTileEntity()).mMaterial; } return false; } @Override public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { if (mIcons == null) { mIcons = new IIcon[6]; Arrays.fill(mIcons, aFrameMaterial.mIconSet.mTextures[OrePrefixes.frameGt.mTextureIndex].getIcon()); } StructureLibAPI.hintParticleTinted(world, x, y, z, mIcons, aFrameMaterial.mRGBa); return true; } @Override public boolean placeBlock(T t, World world, int x, int y, int z, ItemStack trigger) { ItemStack tFrameStack = GT_OreDictUnificator.get(OrePrefixes.frameGt, aFrameMaterial, 1); if (tFrameStack.getItem() instanceof ItemBlock) { ItemBlock tFrameStackItem = (ItemBlock) tFrameStack.getItem(); return tFrameStackItem.placeBlockAt(tFrameStack, null, world, x, y, z, 6, 0, 0, 0, Items.feather.getDamage(tFrameStack)); } return false; } }; } public static IStructureElementNoPlacement ofHatchAdder(IGT_HatchAdder aHatchAdder, int aTextureIndex, Block aHintBlock, int aHintMeta) { if (aHatchAdder == null || aHintBlock == 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 && aHatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) aTextureIndex); } @Override public boolean spawnHint(T t, World world, int x, int y, int z, ItemStack trigger) { StructureLibAPI.hintParticle(world, x, y, z, aHintBlock, aHintMeta); return true; } }; } public static IStructureElement ofHatchAdderOptional(IGT_HatchAdder aHatchAdder, int textureIndex, int dots, Block placeCasing, int placeCasingMeta) { return ofHatchAdderOptional(aHatchAdder, textureIndex, StructureLibAPI.getBlockHint(), dots - 1, placeCasing, placeCasingMeta); } public static IStructureElement ofHatchAdderOptional(IGT_HatchAdder aHatchAdder, int aTextureIndex, Block aHintBlock, int hintMeta, Block placeCasing, int placeCasingMeta) { if (aHatchAdder == null || aHintBlock == 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 && aHatchAdder.apply(t, (IGregTechTileEntity) tileEntity, (short) aTextureIndex)) || (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, aHintBlock, 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 aHeatingCoilSetter, Function aHeatingCoilGetter) { return ofCoil((t, l) -> { aHeatingCoilSetter.accept(t, l); return true; }, aHeatingCoilGetter); } /** * Heating coil structure element. * @param aHeatingCoilSetter 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 aHeatingCoilGetter Get the current heating level. Null means no coil recorded yet. */ public static IStructureElement ofCoil(BiPredicate aHeatingCoilSetter, Function aHeatingCoilGetter) { if (aHeatingCoilSetter == null || aHeatingCoilGetter == 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 = aHeatingCoilGetter.apply(t), newLevel = ((IHeatingCoil) block).getCoilHeat(world.getBlockMetadata(x, y, z)); if (existingLevel == null || existingLevel == HeatingCoilLevel.None) { return aHeatingCoilSetter.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) { // -4 to skip unimplemented tiers return GT_Block_Casings5.getMetaFromCoilHeat(HeatingCoilLevel.getFromTier((byte) Math.min(HeatingCoilLevel.getMaxTier() - 4, Math.max(0, trigger.stackSize - 1)))); } @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); } }; } }