Applied-Energistics-2-tiler.../src/main/java/appeng/facade/FacadePart.java

307 lines
10 KiB
Java
Raw Normal View History

2014-11-14 12:02:52 +01:00
/*
* This file is part of Applied Energistics 2.
* Copyright (c) 2013 - 2015, AlgorithmX2, All rights reserved.
2014-11-14 12:02:52 +01:00
*
* Applied Energistics 2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Applied Energistics 2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Applied Energistics 2. If not, see <http://www.gnu.org/licenses/lgpl>.
*/
package appeng.facade;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import javax.annotation.Nullable;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3i;
import net.minecraft.world.IBlockAccess;
import net.minecraftforge.common.model.TRSRTransformation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
2015-06-18 20:10:37 +02:00
import appeng.api.AEApi;
import appeng.api.client.BakingPipeline;
import appeng.api.parts.IBoxProvider;
import appeng.api.parts.IFacadeContainer;
import appeng.api.parts.IFacadePart;
2014-09-20 22:20:53 +02:00
import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartHost;
2015-06-16 02:44:59 +02:00
import appeng.api.util.AEPartLocation;
import appeng.client.render.model.ModelsCache;
import appeng.client.render.model.pipeline.MatVecApplicator;
import appeng.client.render.model.pipeline.ParentQuads;
import appeng.client.render.model.pipeline.StatePosRecolorator;
import appeng.client.render.model.pipeline.TypeTransformer;
import appeng.core.AppEng;
import appeng.integration.IntegrationRegistry;
import appeng.integration.IntegrationType;
import appeng.integration.abstraction.IBuildCraftTransport;
import appeng.util.Platform;
public class FacadePart implements IFacadePart, IBoxProvider
{
private final ItemStack facade;
private final AEPartLocation side;
private int thickness = 2;
2015-09-30 14:24:40 +02:00
public FacadePart( final ItemStack facade, final AEPartLocation side )
{
if( facade == null )
2015-04-29 02:30:53 +02:00
{
throw new IllegalArgumentException( "Facade Part constructed on null item." );
2015-04-29 02:30:53 +02:00
}
this.facade = facade.copy();
this.facade.stackSize = 1;
this.side = side;
}
2015-09-30 14:24:40 +02:00
public static boolean isFacade( final ItemStack is )
{
return is.getItem() instanceof IFacadeItem;
}
@Override
public ItemStack getItemStack()
{
2014-12-29 15:13:47 +01:00
return this.facade;
}
@Override
2015-09-30 14:24:40 +02:00
public void getBoxes( final IPartCollisionHelper ch, final Entity e )
{
if( e instanceof EntityLivingBase )
{
2014-09-21 01:23:44 +02:00
// prevent weird snag behavior
ch.addBox( 0.0, 0.0, 14, 16.0, 16.0, 16.0 );
}
else
{
// the box is 15.9 for transition planes to pick up collision events.
ch.addBox( 0.0, 0.0, 14, 16.0, 16.0, 15.9 );
}
}
@Override
2015-06-18 20:10:37 +02:00
public AEPartLocation getSide()
{
return this.side;
}
@Override
public AxisAlignedBB getPrimaryBox()
{
return Platform.getPrimaryBox( this.side, this.thickness );
}
@Override
public Item getItem()
{
2015-09-30 14:24:40 +02:00
final ItemStack is = this.getTexture();
if( is == null )
{
return null;
}
return is.getItem();
}
@Override
public int getItemDamage()
{
2015-09-30 14:24:40 +02:00
final ItemStack is = this.getTexture();
if( is == null )
{
return 0;
}
return is.getItemDamage();
}
@Override
public boolean notAEFacade()
{
return !( this.facade.getItem() instanceof IFacadeItem );
}
@Override
2015-09-30 14:24:40 +02:00
public void setThinFacades( final boolean useThinFacades )
{
this.thickness = useThinFacades ? 1 : 2;
}
@Override
public boolean isTransparent()
{
if( AEApi.instance().partHelper().getCableRenderMode().transparentFacades )
{
return true;
}
2015-09-30 14:24:40 +02:00
final ItemStack is = this.getTexture();
final Block blk = Block.getBlockFromItem( is.getItem() );
return !blk.isOpaqueCube( blk.getDefaultState() );
}
@Nullable
private ItemStack getTexture()
{
final Item maybeFacade = this.facade.getItem();
// AE Facade
if( maybeFacade instanceof IFacadeItem )
{
2015-09-30 14:24:40 +02:00
final IFacadeItem facade = (IFacadeItem) maybeFacade;
return facade.getTextureItem( this.facade );
}
else if( IntegrationRegistry.INSTANCE.isEnabled( IntegrationType.BuildCraftTransport ) )
{
final IBuildCraftTransport bc = (IBuildCraftTransport) IntegrationRegistry.INSTANCE.getInstance( IntegrationType.BuildCraftTransport );
return bc.getTextureForFacade( this.facade );
}
return null;
}
2015-09-30 14:24:40 +02:00
private EnumSet<AEPartLocation> calculateFaceOpenFaces( final IBlockAccess blockAccess, final IFacadeContainer fc, final BlockPos pos, final AEPartLocation side )
{
2015-09-30 14:24:40 +02:00
final EnumSet<AEPartLocation> out = EnumSet.of( side, side.getOpposite() );
final IFacadePart facade = fc.getFacade( side );
2015-09-30 14:24:40 +02:00
for( final AEPartLocation it : AEPartLocation.SIDE_LOCATIONS )
{
2015-06-16 02:44:59 +02:00
if( !out.contains( it ) && this.hasAlphaDiff( blockAccess.getTileEntity( pos.offset( it.getFacing() ) ), side, facade ) )
{
out.add( it );
}
}
2015-06-16 02:44:59 +02:00
if( out.contains( AEPartLocation.UP ) && ( side.xOffset != 0 || side.zOffset != 0 ) )
{
2015-09-30 14:24:40 +02:00
final IFacadePart fp = fc.getFacade( AEPartLocation.UP );
if( fp != null && ( fp.isTransparent() == facade.isTransparent() ) )
2015-04-29 02:30:53 +02:00
{
2015-06-16 02:44:59 +02:00
out.remove( AEPartLocation.UP );
2015-04-29 02:30:53 +02:00
}
}
2015-06-16 02:44:59 +02:00
if( out.contains( AEPartLocation.DOWN ) && ( side.xOffset != 0 || side.zOffset != 0 ) )
{
2015-09-30 14:24:40 +02:00
final IFacadePart fp = fc.getFacade( AEPartLocation.DOWN );
if( fp != null && ( fp.isTransparent() == facade.isTransparent() ) )
2015-04-29 02:30:53 +02:00
{
2015-06-16 02:44:59 +02:00
out.remove( AEPartLocation.DOWN );
2015-04-29 02:30:53 +02:00
}
}
2015-06-16 02:44:59 +02:00
if( out.contains( AEPartLocation.SOUTH ) && ( side.xOffset != 0 ) )
{
2015-09-30 14:24:40 +02:00
final IFacadePart fp = fc.getFacade( AEPartLocation.SOUTH );
if( fp != null && ( fp.isTransparent() == facade.isTransparent() ) )
2015-04-29 02:30:53 +02:00
{
2015-06-16 02:44:59 +02:00
out.remove( AEPartLocation.SOUTH );
2015-04-29 02:30:53 +02:00
}
}
2015-06-16 02:44:59 +02:00
if( out.contains( AEPartLocation.NORTH ) && ( side.xOffset != 0 ) )
{
2015-09-30 14:24:40 +02:00
final IFacadePart fp = fc.getFacade( AEPartLocation.NORTH );
if( fp != null && ( fp.isTransparent() == facade.isTransparent() ) )
2015-04-29 02:30:53 +02:00
{
2015-06-16 02:44:59 +02:00
out.remove( AEPartLocation.NORTH );
2015-04-29 02:30:53 +02:00
}
}
/*
2015-06-16 02:44:59 +02:00
* if ( out.contains( AEPartLocation.EAST ) && (side.offsetZ != 0) ) { IFacadePart fp = fc.getFacade(
* AEPartLocation.EAST ); if ( fp != null && (fp.isTransparent() == facade.isTransparent()) ) out.remove(
* AEPartLocation.EAST ); }
* if ( out.contains( AEPartLocation.WEST ) && (side.offsetZ != 0) ) { IFacadePart fp = fc.getFacade(
* AEPartLocation.WEST ); if ( fp != null && (fp.isTransparent() == facade.isTransparent()) ) out.remove(
* AEPartLocation.WEST ); }
* if ( out.contains( AEPartLocation.NORTH ) && (side.offsetY != 0) ) { IFacadePart fp = fc.getFacade(
* AEPartLocation.NORTH ); if ( fp != null && (fp.isTransparent() == facade.isTransparent()) ) out.remove(
* AEPartLocation.NORTH ); }
* if ( out.contains( AEPartLocation.SOUTH ) && (side.offsetY != 0) ) { IFacadePart fp = fc.getFacade(
* AEPartLocation.SOUTH ); if ( fp != null && (fp.isTransparent() == facade.isTransparent()) ) out.remove(
* AEPartLocation.SOUTH ); }
* if ( out.contains( AEPartLocation.EAST ) && (side.offsetY != 0) ) { IFacadePart fp = fc.getFacade(
* AEPartLocation.EAST ); if ( fp != null && (fp.isTransparent() == facade.isTransparent()) ) out.remove(
* AEPartLocation.EAST ); }
* if ( out.contains( AEPartLocation.WEST ) && (side.offsetY != 0) ) { IFacadePart fp = fc.getFacade(s
2015-06-16 02:44:59 +02:00
* AEPartLocation.WEST ); if ( fp != null && (fp.isTransparent() == facade.isTransparent()) ) out.remove(
* AEPartLocation.WEST ); }
*/
return out;
}
2015-09-30 14:24:40 +02:00
private boolean hasAlphaDiff( final TileEntity tileEntity, final AEPartLocation side, final IFacadePart facade )
{
if( tileEntity instanceof IPartHost )
{
2015-09-30 14:24:40 +02:00
final IPartHost ph = (IPartHost) tileEntity;
final IFacadePart fp = ph.getFacadeContainer().getFacade( side );
return fp == null || ( fp.isTransparent() != facade.isTransparent() );
}
return true;
}
@Override
2015-09-30 14:24:40 +02:00
public void getBoxes( final IPartCollisionHelper bch )
{
this.getBoxes( bch, null );
}
@Override
@SideOnly( Side.CLIENT )
public List<BakedQuad> getOrBakeQuads( IPartHost host, BakingPipeline<BakedQuad, BakedQuad> rotatingPipeline, IBlockState state, EnumFacing side, long rand )
{
List<BakedQuad> elements = new ArrayList();
elements.addAll( rotatingPipeline.pipe( ModelsCache.INSTANCE.getOrLoadBakedModel( new ResourceLocation( AppEng.MOD_ID, "part/cable_facade" ) ).getQuads( state, side, rand ), null, state, getSide().getFacing(), rand ) );
ItemStack titem = getTexture();
if( titem != null && titem.getItem() != null && Block.getBlockFromItem( titem.getItem() ) != null )
{
Block tblock = Block.getBlockFromItem( titem.getItem() );
IBlockState tstate = tblock.getStateFromMeta( titem.getItem().getMetadata( titem.getItemDamage() ) );
Vec3i s = getSide().getFacing().getDirectionVec();
Vector3f scale = new Vector3f( s.getX() == 0 ? 0.9999f : 0.125f, s.getY() == 0 ? 0.9999f : 0.125f, s.getZ() == 0 ? 0.9999f : 0.125f );
Vector3f trans = new Vector3f( s.getX() * 3.5f, s.getY() * 3.5f, s.getZ() * 3.5f );
elements.addAll( new BakingPipeline( new ParentQuads(), TypeTransformer.quads2vecs, new MatVecApplicator( TRSRTransformation.toVecmath( new Matrix4f().scale( scale ).translate( trans ) ), true ), new StatePosRecolorator( host.getTile().getWorld(), host.getLocation().getPos(), tstate ), TypeTransformer.vecs2quads ).pipe( new ArrayList<>(), Minecraft.getMinecraft().getBlockRendererDispatcher().getModelForState( tstate ), tstate, side, rand ) );
}
return elements;
}
}