Java tutorial
package com.builtbroken.icbm.content.launcher.silo; import com.builtbroken.icbm.api.missile.ICustomMissileRender; import com.builtbroken.icbm.api.modules.IMissile; import com.builtbroken.icbm.client.Assets; import com.builtbroken.icbm.content.crafting.missile.casing.MissileCasings; import com.builtbroken.icbm.content.launcher.TileAbstractLauncher; import com.builtbroken.jlib.data.vector.IPos3D; import com.builtbroken.mc.api.items.ISimpleItemRenderer; import com.builtbroken.mc.api.tile.multiblock.IMultiTile; import com.builtbroken.mc.api.tile.multiblock.IMultiTileHost; import com.builtbroken.mc.core.registry.implement.IPostInit; import com.builtbroken.mc.lib.transform.region.Cube; import com.builtbroken.mc.lib.transform.vector.Pos; import com.builtbroken.mc.prefab.inventory.InventoryUtility; import com.builtbroken.mc.prefab.tile.Tile; import com.builtbroken.mc.prefab.tile.multiblock.EnumMultiblock; import com.builtbroken.mc.prefab.tile.multiblock.MultiBlockHelper; import cpw.mods.fml.client.FMLClientHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.block.material.Material; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.item.ItemStack; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.AxisAlignedBB; import net.minecraft.util.IIcon; import net.minecraftforge.client.IItemRenderer; import net.minecraftforge.common.util.ForgeDirection; import org.lwjgl.opengl.GL11; import java.util.HashMap; /** * 7 block tall silo tube that requires a user to build a casing to contain the missile. * * @see <a href="https://github.com/BuiltBrokenModding/VoltzEngine/blob/development/license.md">License</a> for what you can and can't do with the code. * Created by Dark(DarkGuardsman, Robert) on 2/23/2016. */ public class TileStandardSilo extends TileAbstractLauncher implements ISimpleItemRenderer, IMultiTileHost, IPostInit { public static HashMap<IPos3D, String> tileMapCache = new HashMap(); static { tileMapCache.put(new Pos(0, 1, 0), EnumMultiblock.TILE.getName()); tileMapCache.put(new Pos(0, 2, 0), EnumMultiblock.TILE.getName()); tileMapCache.put(new Pos(0, 3, 0), EnumMultiblock.TILE.getName()); tileMapCache.put(new Pos(0, 4, 0), EnumMultiblock.TILE.getName()); tileMapCache.put(new Pos(0, 5, 0), EnumMultiblock.TILE.getName()); tileMapCache.put(new Pos(0, 6, 0), EnumMultiblock.TILE.getName()); } private boolean _destroyingStructure = false; public TileStandardSilo() { super("standardsilo", Material.iron, 1); this.itemBlock = ItemBlockStandardSilo.class; this.isOpaque = false; this.renderNormalBlock = false; this.renderTileEntity = true; } @Override public void onPostInit() { } @Override public boolean canAcceptMissile(IMissile missile) { return super.canAcceptMissile(missile) && missile.getMissileSize() == MissileCasings.STANDARD.ordinal(); } @Override public Tile newTile() { return new TileStandardSilo(); } @SideOnly(Side.CLIENT) public IIcon getIcon() { return Blocks.iron_block.getIcon(0, 0); } @Override @SideOnly(Side.CLIENT) public void registerIcons(IIconRegister iconRegister) { //We have no icons to register } @Override public String getInventoryName() { return "tile.icbm:standardSilo.container"; } @Override public void renderInventoryItem(IItemRenderer.ItemRenderType type, ItemStack itemStack, Object... data) { GL11.glTranslatef(-0.5f, -0.5f, -0.5f); GL11.glScaled(.8f, .8f, .8f); FMLClientHandler.instance().getClient().renderEngine.bindTexture(Assets.SMALL_SILO_TEXTURE); GL11.glColor3f(1.0f, 0f, 0f); Assets.SMALL_SILO_MODEL.renderOnly("Group_001", "Component_1_001"); } @SideOnly(Side.CLIENT) public AxisAlignedBB getRenderBoundingBox() { return new Cube(0, 0, 0, 1, 7, 1).add(x(), y(), z()).toAABB(); } @Override @SideOnly(Side.CLIENT) public void renderDynamic(Pos pos, float frame, int pass) { //Render launcher GL11.glPushMatrix(); GL11.glTranslatef(pos.xf(), pos.yf(), pos.zf() + 1); FMLClientHandler.instance().getClient().renderEngine.bindTexture(Assets.STANDARD_SILO_TEXTURE); Assets.STANDARD_SILO_MODEL.renderAll(); GL11.glPopMatrix(); //Render missile if (getMissile() != null) { GL11.glPushMatrix(); GL11.glTranslatef(pos.xf() + 0.5f, pos.yf() + 2.75f, pos.zf() + 0.5f); //TODO rotate if (getMissile() instanceof ICustomMissileRender) { ((ICustomMissileRender) getMissile()).renderMissileInWorld(0, 0, frame); } GL11.glPopMatrix(); } } @Override public void firstTick() { super.firstTick(); MultiBlockHelper.buildMultiBlock(world(), this, true, true); } @Override public void onMultiTileAdded(IMultiTile tileMulti) { if (tileMulti instanceof TileEntity) { if (tileMapCache.containsKey(new Pos(this).sub(new Pos((TileEntity) tileMulti)))) { tileMulti.setHost(this); } } } @Override public boolean onMultiTileBroken(IMultiTile tileMulti, Object source, boolean harvest) { if (!_destroyingStructure && tileMulti instanceof TileEntity) { Pos pos = new Pos((TileEntity) tileMulti).sub(new Pos(this)); if (tileMapCache.containsKey(pos)) { MultiBlockHelper.destroyMultiBlockStructure(this, harvest, true, true); return true; } } return false; } @Override public boolean canPlaceBlockAt() { return super.canPlaceBlockAt() && world().getBlock(xi(), yi() + 1, zi()).isReplaceable(world(), xi(), yi() + 1, zi()) && world().getBlock(xi(), yi() + 2, zi()).isReplaceable(world(), xi(), yi() + 2, zi()); } @Override public boolean canPlaceBlockOnSide(ForgeDirection side) { return side == ForgeDirection.UP && canPlaceBlockAt(); } @Override public boolean removeByPlayer(EntityPlayer player, boolean willHarvest) { MultiBlockHelper.destroyMultiBlockStructure(this, false, true, false); if (willHarvest && getMissileItem() != null) { InventoryUtility.dropItemStack(toLocation(), getMissileItem()); setInventorySlotContents(0, null); } return super.removeByPlayer(player, willHarvest); } @Override public void onTileInvalidate(IMultiTile tileMulti) { } @Override public boolean onMultiTileActivated(IMultiTile tile, EntityPlayer player, int side, IPos3D hit) { return this.onPlayerRightClick(player, side, new Pos(hit)); } @Override public void onMultiTileClicked(IMultiTile tile, EntityPlayer player) { } @Override public HashMap<IPos3D, String> getLayoutOfMultiBlock() { return tileMapCache; } }