diff options
Diffstat (limited to 'src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java')
-rw-r--r-- | src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java | 592 |
1 files changed, 592 insertions, 0 deletions
diff --git a/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java b/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java new file mode 100644 index 0000000000..f5cf261be1 --- /dev/null +++ b/src/main/java/gregtech/api/multitileentity/MultiTileEntityBlock.java @@ -0,0 +1,592 @@ +package gregtech.api.multitileentity; + +import static gregtech.api.enums.GT_Values.OFFX; +import static gregtech.api.enums.GT_Values.OFFY; +import static gregtech.api.enums.GT_Values.OFFZ; +import static gregtech.api.util.GT_Util.LAST_BROKEN_TILEENTITY; +import static gregtech.api.util.GT_Util.getTileEntity; +import static gregtech.api.util.GT_Util.setTileEntity; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import net.minecraft.block.Block; +import net.minecraft.block.BlockContainer; +import net.minecraft.block.ITileEntityProvider; +import net.minecraft.block.material.Material; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EnumCreatureType; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Blocks; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.stats.StatList; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.IIcon; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.util.StatCollector; +import net.minecraft.world.Explosion; +import net.minecraft.world.IBlockAccess; +import net.minecraft.world.World; +import net.minecraftforge.common.util.ForgeDirection; +import net.minecraftforge.event.ForgeEventFactory; + +import com.cricketcraft.chisel.api.IFacade; + +import cpw.mods.fml.common.Optional; +import cpw.mods.fml.common.registry.GameRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import gregtech.api.GregTech_API; +import gregtech.api.enums.ItemList; +import gregtech.api.enums.Textures; +import gregtech.api.interfaces.IDebugableBlock; +import gregtech.api.interfaces.tileentity.IDebugableTileEntity; +import gregtech.api.metatileentity.BaseTileEntity; +import gregtech.api.metatileentity.CoverableTileEntity; +import gregtech.api.multitileentity.interfaces.IMultiTileEntity; +import gregtech.api.objects.XSTR; +import gregtech.api.util.GT_Log; +import gregtech.api.util.GT_Util; +import gregtech.common.covers.CoverInfo; +import gregtech.common.render.GT_MultiTile_Renderer; + +/* + * MultiTileEntityBlock ported from GT6 + */ +@Optional.Interface(iface = "com.cricketcraft.chisel.api.IFacade", modid = "ChiselAPI") +public class MultiTileEntityBlock extends BlockContainer implements IDebugableBlock, ITileEntityProvider, IFacade { + + private MultiTileEntityRegistry registry; + + private static boolean LOCK = false; + + private boolean registered = false; + private boolean normalCube; + protected String internalName, toolName, materialName, modID; + + public String getName() { + return String.join( + ".", + "gt.block.multiblock", + materialName, + stepSound.soundName, + toolName, + Boolean.toString(opaque), + Boolean.toString(normalCube)); + } + + public MultiTileEntityBlock(Material material) { + super(material); + if (GregTech_API.sPreloadFinished) + throw new IllegalStateException("Blocks can only be initialized within preInit!"); + } + + public MultiTileEntityBlock tool(String toolName) { + this.toolName = toolName.toLowerCase(); + return this; + } + + public MultiTileEntityBlock sound(SoundType soundtype) { + setStepSound(soundtype); + return this; + } + + public MultiTileEntityBlock opaque(Boolean opaque) { + this.opaque = opaque; + return this; + } + + public MultiTileEntityBlock normalCube(Boolean normalCube) { + this.normalCube = normalCube; + return this; + } + + public MultiTileEntityBlock modID(String modID) { + this.modID = modID; + return this; + } + + public MultiTileEntityBlock materialName(String materialName) { + this.materialName = materialName; + return this; + } + + public MultiTileEntityBlock register() { + if (registered) throw new IllegalStateException("Block already registered " + internalName); + if (GregTech_API.sPreloadFinished) + throw new IllegalStateException("Blocks can only be initialized within preInit!"); + + registered = true; + internalName = getName(); + lightOpacity = isOpaqueCube() ? 255 : 0; + + GameRegistry.registerBlock(this, MultiTileEntityItem.class, internalName); + return this; + } + + @Override + public final void breakBlock(World world, int x, int y, int z, Block block, int metadata) { + final TileEntity tileEntity = getTileEntity(world, x, y, z, true); + if (tileEntity != null) LAST_BROKEN_TILEENTITY.set(tileEntity); + if (tileEntity == null || !tileEntity.shouldRefresh(this, block, metadata, metadata, world, x, y, z)) return; + if (tileEntity instanceof IMultiTileEntity mute) mute.onBlockBroken(); + // spotless:off + // if (aTileEntity instanceof IMTE_HasMultiBlockMachineRelevantData + // && ((IMTE_HasMultiBlockMachineRelevantData) aTileEntity).hasMultiBlockMachineRelevantData()) + // GregTech_API.causeMachineUpdate(world, x, y, z); + // spotless:on + + world.removeTileEntity(x, y, z); + super.breakBlock(world, x, y, z, block, metadata); + + } + + @Override + public ArrayList<String> getDebugInfo(EntityPlayer aPlayer, int x, int y, int z, int aLogLevel) { + final TileEntity tileEntity = aPlayer.worldObj.getTileEntity(x, y, z); + if (tileEntity instanceof IDebugableTileEntity mte) { + return mte.getDebugInfo(aPlayer, aLogLevel); + } + return new ArrayList<>(); + } + + @Override + public int getRenderType() { + return GT_MultiTile_Renderer.INSTANCE == null ? super.getRenderType() + : GT_MultiTile_Renderer.INSTANCE.getRenderId(); + } + + @Override + public final float getBlockHardness(World world, int x, int y, int z) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IMultiTileEntity ? ((IMultiTileEntity) tileEntity).getBlockHardness() : 1.0F; + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(IBlockAccess aIBlockAccess, int x, int y, int z, int ordinalSide) { + return Textures.BlockIcons.MACHINE_LV_SIDE.getIcon(); + } + + @SideOnly(Side.CLIENT) + @Override + public IIcon getIcon(int ordinalSide, int meta) { + return Textures.BlockIcons.MACHINE_LV_SIDE.getIcon(); + } + + @Override + @SuppressWarnings("unchecked") + public final void addCollisionBoxesToList(World world, int x, int y, int z, AxisAlignedBB aAABB, + List<AxisAlignedBB> aList, Entity aEntity) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity instanceof IMultiTileEntity) + ((IMultiTileEntity) tileEntity).addCollisionBoxesToList(aAABB, aList, aEntity); + else super.addCollisionBoxesToList(world, x, y, z, aAABB, aList, aEntity); + } + + @Override + public final AxisAlignedBB getCollisionBoundingBoxFromPool(World world, int x, int y, int z) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IMultiTileEntity mte ? mte.getCollisionBoundingBoxFromPool() + : tileEntity == null ? null : super.getCollisionBoundingBoxFromPool(world, x, y, z); + } + + @Override + public final AxisAlignedBB getSelectedBoundingBoxFromPool(World world, int x, int y, int z) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IMultiTileEntity mte ? mte.getSelectedBoundingBoxFromPool() + : super.getSelectedBoundingBoxFromPool(world, x, y, z); + } + + @Override + public void setBlockBoundsBasedOnState(IBlockAccess blockAccess, int x, int y, int z) { + final TileEntity tileEntity = blockAccess.getTileEntity(x, y, z); + if (tileEntity instanceof IMultiTileEntity mte) { + mte.setBlockBoundsBasedOnState(this); + return; + } + super.setBlockBoundsBasedOnState(blockAccess, x, y, z); + } + + @Override + public final boolean isOpaqueCube() { + return opaque; + } + + @Override + public final void onNeighborChange(IBlockAccess world, int x, int y, int z, int aTileX, int aTileY, int aTileZ) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + if (!LOCK) { + LOCK = true; + if (tileEntity instanceof BaseTileEntity) + ((BaseTileEntity) tileEntity).onAdjacentBlockChange(aTileX, aTileY, aTileZ); + LOCK = false; + } + } + + @Override + public void onNeighborBlockChange(World world, int x, int y, int z, Block block) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + if (!LOCK) { + LOCK = true; + if (tileEntity instanceof BaseTileEntity bte) bte.onAdjacentBlockChange(x, y, z); + LOCK = false; + } + if (tileEntity instanceof IMultiTileEntity change) change.onNeighborBlockChange(world, block); + + if (tileEntity == null) world.setBlockToAir(x, y, z); + } + + @Override + public final void onBlockAdded(World world, int x, int y, int z) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity instanceof IMultiTileEntity mte) mte.onBlockAdded(); + } + + @Override + public float getPlayerRelativeBlockHardness(EntityPlayer aPlayer, World world, int x, int y, int z) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IMultiTileEntity mte && mte.privateAccess() + && !((IMultiTileEntity) tileEntity).playerOwnsThis(aPlayer, true) ? -1.0F + : super.getPlayerRelativeBlockHardness(aPlayer, world, x, y, z); + } + + @Override + public final void onBlockClicked(World world, int x, int y, int z, EntityPlayer aPlayer) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity instanceof IMultiTileEntity mte) mte.onLeftClick(aPlayer); + else super.onBlockClicked(world, x, y, z, aPlayer); + } + + @Override + public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer aPlayer, int ordinalSide, + float aHitX, float aHitY, float aHitZ) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + if (aPlayer != null && ItemList.TC_Thaumometer.isStackEqual(aPlayer.getHeldItem(), true, true)) return false; + return tileEntity instanceof IMultiTileEntity mte + && mte.onBlockActivated(aPlayer, ForgeDirection.getOrientation(ordinalSide), aHitX, aHitY, aHitZ); + } + + @Override + public final int isProvidingWeakPower(IBlockAccess world, int x, int y, int z, int ordinalSide) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IMultiTileEntity power + ? power.isProvidingWeakPower(ForgeDirection.getOrientation(ordinalSide)) + : super.isProvidingWeakPower(world, x, y, z, ordinalSide); + } + + @Override + public final int isProvidingStrongPower(IBlockAccess world, int x, int y, int z, int ordinalSide) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IMultiTileEntity power + ? power.isProvidingStrongPower(ForgeDirection.getOrientation(ordinalSide)) + : super.isProvidingStrongPower(world, x, y, z, ordinalSide); + } + + @Override + public final boolean shouldCheckWeakPower(IBlockAccess world, int x, int y, int z, int ordinalSide) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IMultiTileEntity power + ? power.shouldCheckWeakPower(ForgeDirection.getOrientation(ordinalSide)) + : isNormalCube(world, x, y, z); + } + + @Override + public final boolean getWeakChanges(IBlockAccess world, int x, int y, int z) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IMultiTileEntity changes ? changes.getWeakChanges() + : super.getWeakChanges(world, x, y, z); + } + + @Override + public final void harvestBlock(World world, EntityPlayer aPlayer, int x, int y, int z, int meta) { + if (aPlayer == null) aPlayer = harvesters.get(); + aPlayer.addStat(StatList.mineBlockStatArray[getIdFromBlock(this)], 1); + aPlayer.addExhaustion(0.025F); + final boolean aSilkTouch = EnchantmentHelper.getSilkTouchModifier(aPlayer); + final int aFortune = EnchantmentHelper.getFortuneModifier(aPlayer); + float aChance = 1.0F; + final TileEntity tileEntity = getTileEntity(world, x, y, z, true); + + if (!(tileEntity instanceof IMultiTileEntity mte)) { + return; + } + + final ArrayList<ItemStack> tList = mte.getDrops(aFortune, aSilkTouch); + aChance = ForgeEventFactory + .fireBlockHarvesting(tList, world, this, x, y, z, meta, aFortune, aChance, aSilkTouch, aPlayer); + for (final ItemStack tStack : tList) + if (XSTR.XSTR_INSTANCE.nextFloat() <= aChance) dropBlockAsItem(world, x, y, z, tStack); + + } + + @Override + public final boolean shouldSideBeRendered(IBlockAccess world, int x, int y, int z, int ordinalSide) { + final TileEntity tileEntity = world + .getTileEntity(x - OFFX[ordinalSide], y - OFFY[ordinalSide], z - OFFZ[ordinalSide]); + return tileEntity instanceof IMultiTileEntity mte + ? mte.shouldSideBeRendered(ForgeDirection.getOrientation(ordinalSide)) + : super.shouldSideBeRendered(world, x, y, z, ordinalSide); + } + + @Override + public Block getFacade(IBlockAccess world, int x, int y, int z, int ordinalSide) { + final TileEntity tTileEntity = world.getTileEntity(x, y, z); + if (tTileEntity instanceof CoverableTileEntity tile) { + final ForgeDirection side = ForgeDirection.getOrientation(ordinalSide); + if (ordinalSide != -1) { + final Block facadeBlock = tile.getCoverInfoAtSide(side) + .getFacadeBlock(); + if (facadeBlock != null) return facadeBlock; + } else { + // we do not allow more than one type of facade per block, so no need to check every side + // see comment in gregtech.common.covers.GT_Cover_FacadeBase.isCoverPlaceable + for (final ForgeDirection tSide : ForgeDirection.VALID_DIRECTIONS) { + final Block facadeBlock = tile.getCoverInfoAtSide(tSide) + .getFacadeBlock(); + if (facadeBlock != null) { + return facadeBlock; + } + } + } + } + return Blocks.air; + } + + @Override + public int getFacadeMetadata(IBlockAccess world, int x, int y, int z, int ordinalSide) { + final TileEntity tTileEntity = world.getTileEntity(x, y, z); + if (tTileEntity instanceof CoverableTileEntity tile) { + final ForgeDirection side = ForgeDirection.getOrientation(ordinalSide); + if (ordinalSide != -1) { + final CoverInfo coverInfo = tile.getCoverInfoAtSide(side); + final Block facadeBlock = coverInfo.getFacadeBlock(); + if (facadeBlock != null) return coverInfo.getFacadeMeta(); + } else { + // we do not allow more than one type of facade per block, so no need to check every side + // see comment in gregtech.common.covers.GT_Cover_FacadeBase.isCoverPlaceable + for (final ForgeDirection tSide : ForgeDirection.VALID_DIRECTIONS) { + final CoverInfo coverInfo = tile.getCoverInfoAtSide(tSide); + final Block facadeBlock = coverInfo.getFacadeBlock(); + if (facadeBlock != null) { + return coverInfo.getFacadeMeta(); + } + } + } + } + return 0; + } + + public MultiTileEntityRegistry getRegistry() { + return registry; + } + + public void setRegistry(MultiTileEntityRegistry registry) { + this.registry = registry; + } + + public boolean isRegistered() { + return registered; + } + + @Override + protected boolean canSilkHarvest() { + return false; + } + + @Override + public final String getLocalizedName() { + return StatCollector.translateToLocal(internalName + ".name"); + } + + @Override + public final String getUnlocalizedName() { + return internalName; + } + + @Override + public final boolean onBlockEventReceived(World world, int x, int y, int z, int aID, int aData) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity == null || tileEntity.receiveClientEvent(aID, aData); + } + + @Override + public final void getSubBlocks(Item aItem, CreativeTabs aCreativeTab, List<ItemStack> aList) { + /**/ + } + + @Override + public boolean hasComparatorInputOverride() { + return true; + } + + @Override + public final int getComparatorInputOverride(World world, int x, int y, int z, int ordinalSide) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + if (tileEntity instanceof IMultiTileEntity mute) { + if (mute.hasComparatorInputOverride()) + return mute.getComparatorInputOverride(ForgeDirection.getOrientation(ordinalSide)); + else return mute.isProvidingWeakPower( + ForgeDirection.getOrientation(ordinalSide) + .getOpposite()); + } + + return super.getComparatorInputOverride(world, x, y, z, ordinalSide); + } + + @Override + public final void registerBlockIcons(IIconRegister aIconRegister) { + /* Do Nothing */ + } + + @Override + public final boolean isSideSolid(IBlockAccess world, int x, int y, int z, ForgeDirection side) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IMultiTileEntity mute ? mute.isSideSolid(side) : opaque; + } + + @Override + public boolean removedByPlayer(World world, EntityPlayer aPlayer, int x, int y, int z, boolean aWillHarvest) { + final TileEntity tileEntity = GT_Util.getTileEntity(world, x, y, z, true); + if (tileEntity != null) LAST_BROKEN_TILEENTITY.set(tileEntity); + return super.removedByPlayer(world, aPlayer, x, y, z, aWillHarvest); + } + + @Override + public int getFlammability(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return 0; + } + + @Override + public int getFireSpreadSpeed(IBlockAccess world, int x, int y, int z, ForgeDirection face) { + return GregTech_API.sMachineFlammable && (world.getBlockMetadata(x, y, z) == 0) ? 100 : 0; + } + + @Override + public boolean hasTileEntity(int meta) { + return true; + } + + @Override + public final ArrayList<ItemStack> getDrops(World world, int x, int y, int z, int aUnusableMetaData, int aFortune) { + final TileEntity tileEntity = getTileEntity(world, x, y, z, true); + if (tileEntity instanceof IMultiTileEntity mute) return mute.getDrops(aFortune, false); + return new ArrayList<>(); + } + + @Override + public boolean canCreatureSpawn(EnumCreatureType type, IBlockAccess world, int x, int y, int z) { + return false; + } + + @Override + public final float getExplosionResistance(Entity aExploder, World world, int x, int y, int z, double aExplosionX, + double aExplosionY, double aExplosionZ) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IMultiTileEntity mute + ? mute.getExplosionResistance(aExploder, aExplosionX, aExplosionY, aExplosionZ) + : 1.0F; + } + + @Override + public final void onBlockExploded(World world, int x, int y, int z, Explosion aExplosion) { + if (world.isRemote) return; + final TileEntity tileEntity = getTileEntity(world, x, y, z, true); + if (tileEntity != null) LAST_BROKEN_TILEENTITY.set(tileEntity); + if (tileEntity instanceof IMultiTileEntity mute) { + GT_Log.exp.printf( + "Explosion at : %d | %d | %d DIMID: %s due to near explosion!%n", + x, + y, + z, + world.provider.dimensionId); + mute.onExploded(aExplosion); + } else world.setBlockToAir(x, y, z); + } + + @Override + public final boolean canConnectRedstone(IBlockAccess world, int x, int y, int z, int ordinalSide) { + return true; + } + + @Override + public final boolean recolourBlock(World world, int x, int y, int z, ForgeDirection side, int color) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IMultiTileEntity mute && mute.recolourBlock(side, (byte) color); + } + + @Override + public final String getHarvestTool(int meta) { + return toolName; + } + + @Override + public int getHarvestLevel(int meta) { + return meta % 4; + } + + @Override + public final boolean isToolEffective(String toolType, int meta) { + return getHarvestTool(meta).equals(toolType); + } + + @Override + public final ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z, + EntityPlayer aPlayer) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IMultiTileEntity mte ? mte.getPickBlock(target) : null; + } + + @Override + public final ItemStack getPickBlock(MovingObjectPosition target, World world, int x, int y, int z) { + final TileEntity tileEntity = world.getTileEntity(x, y, z); + return tileEntity instanceof IMultiTileEntity mte ? mte.getPickBlock(target) : null; + } + + @Nullable + public final IMultiTileEntity receiveMultiTileEntityData(@Nonnull IBlockAccess world, int x, int y, int z, + int registryId, int aID) { + if (!(world instanceof World)) return null; + TileEntity tileEntity = world.getTileEntity(x, y, z); + + if (!(tileEntity instanceof IMultiTileEntity mute) || mute.getMultiTileEntityRegistryID() != registryId + || mute.getMultiTileEntityID() != aID) { + final MultiTileEntityRegistry tRegistry = MultiTileEntityRegistry.getRegistry(registryId); + if (tRegistry == null) return null; + + tileEntity = tRegistry.getNewTileEntity((World) world, x, y, z, aID); + if (!(tileEntity instanceof IMultiTileEntity)) return null; + + setTileEntity((World) world, x, y, z, tileEntity, false); + } + return (IMultiTileEntity) tileEntity; + } + + public void receiveCoverData(IMultiTileEntity mute, int aCover0, int aCover1, int aCover2, int aCover3, int aCover4, + int aCover5) { + boolean updated; + updated = mute.setCoverIDAtSideNoUpdate(ForgeDirection.DOWN, aCover0); + updated |= mute.setCoverIDAtSideNoUpdate(ForgeDirection.UP, aCover1); + updated |= mute.setCoverIDAtSideNoUpdate(ForgeDirection.NORTH, aCover2); + updated |= mute.setCoverIDAtSideNoUpdate(ForgeDirection.SOUTH, aCover3); + updated |= mute.setCoverIDAtSideNoUpdate(ForgeDirection.WEST, aCover4); + updated |= mute.setCoverIDAtSideNoUpdate(ForgeDirection.EAST, aCover5); + + if (updated) { + mute.issueBlockUpdate(); + } + } + + @Override + public TileEntity createNewTileEntity(World world, int meta) { + return registry.getNewTileEntity(meta); + } +} |