Implemented drive models. Fixed issues with the UVL model loader using a null model loader (and thus crashing).
This commit is contained in:
parent
576923a2f2
commit
f3e10b1851
|
@ -22,13 +22,19 @@ package appeng.block.storage;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.block.material.Material;
|
||||
import net.minecraft.block.state.BlockStateContainer;
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.util.BlockRenderLayer;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraft.util.EnumHand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.world.IBlockAccess;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.common.property.ExtendedBlockState;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
import net.minecraftforge.common.property.IUnlistedProperty;
|
||||
|
||||
import appeng.api.util.AEPartLocation;
|
||||
import appeng.block.AEBaseTileBlock;
|
||||
|
@ -40,6 +46,8 @@ import appeng.util.Platform;
|
|||
public class BlockDrive extends AEBaseTileBlock
|
||||
{
|
||||
|
||||
public static final DriveSlotsStateProperty SLOTS_STATE = new DriveSlotsStateProperty();
|
||||
|
||||
public BlockDrive()
|
||||
{
|
||||
super( Material.IRON );
|
||||
|
@ -52,6 +60,29 @@ public class BlockDrive extends AEBaseTileBlock
|
|||
return BlockRenderLayer.CUTOUT;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BlockStateContainer createBlockState()
|
||||
{
|
||||
return new ExtendedBlockState( this, getAEStates(), new IUnlistedProperty[] {
|
||||
SLOTS_STATE,
|
||||
FORWARD,
|
||||
UP
|
||||
} );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBlockState getExtendedState( IBlockState state, IBlockAccess world, BlockPos pos )
|
||||
{
|
||||
TileDrive te = getTileEntity( world, pos );
|
||||
if( te == null )
|
||||
{
|
||||
return super.getExtendedState( state, world, pos );
|
||||
}
|
||||
|
||||
IExtendedBlockState extState = (IExtendedBlockState) super.getExtendedState( state, world, pos );
|
||||
return extState.withProperty( SLOTS_STATE, DriveSlotsState.fromChestOrDrive( te ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActivated( final World w, final BlockPos pos, final EntityPlayer p, final EnumHand hand, final @Nullable ItemStack heldItem, final EnumFacing side, final float hitX, final float hitY, final float hitZ )
|
||||
{
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package appeng.block.storage;
|
||||
|
||||
|
||||
import appeng.bootstrap.BlockRenderingCustomizer;
|
||||
import appeng.bootstrap.IBlockRendering;
|
||||
import appeng.bootstrap.IItemRendering;
|
||||
import appeng.client.render.model.DriveModel;
|
||||
|
||||
|
||||
public class DriveRendering extends BlockRenderingCustomizer
|
||||
{
|
||||
@Override
|
||||
public void customize( IBlockRendering rendering, IItemRendering itemRendering )
|
||||
{
|
||||
rendering.builtInModel( "models/block/builtin/drive", new DriveModel() );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* 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.block.storage;
|
||||
|
||||
|
||||
/**
|
||||
* Describes the different states a single slot of a BlockDrive can be in in terms of rendering.
|
||||
*/
|
||||
public enum DriveSlotState
|
||||
{
|
||||
|
||||
// No cell in slot
|
||||
EMPTY,
|
||||
|
||||
// Cell in slot, but unpowered
|
||||
OFFLINE,
|
||||
|
||||
// Online and free space
|
||||
ONLINE,
|
||||
|
||||
// Types full, space left
|
||||
TYPES_FULL,
|
||||
|
||||
// Completely full
|
||||
FULL
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* 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.block.storage;
|
||||
|
||||
|
||||
import appeng.api.implementations.tiles.IChestOrDrive;
|
||||
|
||||
|
||||
/**
|
||||
* Contains the full information about what the state of the slots in a BlockDrive is.
|
||||
*/
|
||||
public class DriveSlotsState
|
||||
{
|
||||
|
||||
private final DriveSlotState[] slots;
|
||||
|
||||
private DriveSlotsState( DriveSlotState[] slots )
|
||||
{
|
||||
this.slots = slots;
|
||||
}
|
||||
|
||||
public DriveSlotState getState( int index )
|
||||
{
|
||||
if( index >= slots.length )
|
||||
{
|
||||
return DriveSlotState.EMPTY;
|
||||
}
|
||||
return slots[index];
|
||||
}
|
||||
|
||||
public int getSlotCount()
|
||||
{
|
||||
return slots.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an array that describes the state of each slot in this drive or chest.
|
||||
*/
|
||||
public static DriveSlotsState fromChestOrDrive( IChestOrDrive chestOrDrive )
|
||||
{
|
||||
DriveSlotState[] slots = new DriveSlotState[chestOrDrive.getCellCount()];
|
||||
for( int i = 0; i < chestOrDrive.getCellCount(); i++ )
|
||||
{
|
||||
if( !chestOrDrive.isPowered() )
|
||||
{
|
||||
if( chestOrDrive.getCellStatus( i ) != 0 )
|
||||
{
|
||||
slots[i] = DriveSlotState.OFFLINE;
|
||||
}
|
||||
else
|
||||
{
|
||||
slots[i] = DriveSlotState.EMPTY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch( chestOrDrive.getCellStatus( i ) )
|
||||
{
|
||||
default:
|
||||
case 0:
|
||||
slots[i] = DriveSlotState.EMPTY;
|
||||
break;
|
||||
case 1:
|
||||
slots[i] = DriveSlotState.ONLINE;
|
||||
break;
|
||||
case 2:
|
||||
slots[i] = DriveSlotState.TYPES_FULL;
|
||||
break;
|
||||
case 3:
|
||||
slots[i] = DriveSlotState.FULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return new DriveSlotsState( slots );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* 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.block.storage;
|
||||
|
||||
|
||||
import net.minecraftforge.common.property.IUnlistedProperty;
|
||||
|
||||
|
||||
public class DriveSlotsStateProperty implements IUnlistedProperty<DriveSlotsState>
|
||||
{
|
||||
@Override
|
||||
public String getName()
|
||||
{
|
||||
return "drive_slots_state";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid( DriveSlotsState value )
|
||||
{
|
||||
return value != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<DriveSlotsState> getType()
|
||||
{
|
||||
return DriveSlotsState.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String valueToString( DriveSlotsState value )
|
||||
{
|
||||
return value.toString();
|
||||
}
|
||||
}
|
|
@ -41,7 +41,6 @@ import net.minecraft.util.ResourceLocation;
|
|||
import net.minecraft.util.math.RayTraceResult;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraftforge.client.event.ModelBakeEvent;
|
||||
import net.minecraftforge.client.event.MouseEvent;
|
||||
import net.minecraftforge.client.event.RenderLivingEvent;
|
||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||
|
@ -356,12 +355,6 @@ public class ClientHelper extends ServerHelper
|
|||
Minecraft.getMinecraft().effectRenderer.addEffect( fx );
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onModelBakeEvent( final ModelBakeEvent event )
|
||||
{
|
||||
UVLModelLoader.INSTANCE.setLoader( event.getModelLoader() );
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void wheelEvent( final MouseEvent me )
|
||||
{
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* 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.client.render.model;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.vecmath.Matrix4f;
|
||||
import javax.vecmath.Vector3f;
|
||||
|
||||
import net.minecraft.block.state.IBlockState;
|
||||
import net.minecraft.client.renderer.block.model.BakedQuad;
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
||||
import net.minecraft.client.renderer.block.model.ItemOverrideList;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.util.EnumFacing;
|
||||
import net.minecraftforge.client.model.pipeline.UnpackedBakedQuad;
|
||||
import net.minecraftforge.common.property.IExtendedBlockState;
|
||||
|
||||
import appeng.block.storage.BlockDrive;
|
||||
import appeng.block.storage.DriveSlotState;
|
||||
import appeng.block.storage.DriveSlotsState;
|
||||
|
||||
|
||||
public class DriveBakedModel implements IBakedModel
|
||||
{
|
||||
private final IBakedModel bakedBase;
|
||||
private final Map<DriveSlotState, IBakedModel> bakedCells;
|
||||
|
||||
public DriveBakedModel( IBakedModel bakedBase, Map<DriveSlotState, IBakedModel> bakedCells )
|
||||
{
|
||||
this.bakedBase = bakedBase;
|
||||
this.bakedCells = bakedCells;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
|
||||
{
|
||||
|
||||
List<BakedQuad> result = new ArrayList<>();
|
||||
|
||||
result.addAll( bakedBase.getQuads( state, side, rand ) );
|
||||
|
||||
if( side == null && state instanceof IExtendedBlockState )
|
||||
{
|
||||
IExtendedBlockState extState = (IExtendedBlockState) state;
|
||||
DriveSlotsState slotsState = extState.getValue( BlockDrive.SLOTS_STATE );
|
||||
|
||||
for( int row = 0; row < 5; row++ )
|
||||
{
|
||||
for( int col = 0; col < 2; col++ )
|
||||
{
|
||||
DriveSlotState slotState = slotsState.getState( row * 2 + col );
|
||||
|
||||
IBakedModel bakedCell = bakedCells.get( slotState );
|
||||
|
||||
Matrix4f transform = new Matrix4f();
|
||||
transform.setIdentity();
|
||||
|
||||
// Position this drive model copy at the correct slot. The transform is based on the
|
||||
// cell-model being in slot 0,0 at the top left of the drive.
|
||||
float xOffset = -col * 7 / 16.0f;
|
||||
float yOffset = -row * 3 / 16.0f;
|
||||
|
||||
transform.setTranslation( new Vector3f( xOffset, yOffset, 0 ) );
|
||||
|
||||
MatrixVertexTransformer transformer = new MatrixVertexTransformer( transform );
|
||||
for( BakedQuad bakedQuad : bakedCell.getQuads( state, null, rand ) )
|
||||
{
|
||||
UnpackedBakedQuad.Builder builder = new UnpackedBakedQuad.Builder( bakedQuad.getFormat() );
|
||||
transformer.setParent( builder );
|
||||
transformer.setVertexFormat( builder.getVertexFormat() );
|
||||
bakedQuad.pipe( transformer );
|
||||
result.add( builder.build() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAmbientOcclusion()
|
||||
{
|
||||
return bakedBase.isAmbientOcclusion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGui3d()
|
||||
{
|
||||
return bakedBase.isGui3d();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBuiltInRenderer()
|
||||
{
|
||||
return bakedBase.isGui3d();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextureAtlasSprite getParticleTexture()
|
||||
{
|
||||
return bakedBase.getParticleTexture();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemCameraTransforms getItemCameraTransforms()
|
||||
{
|
||||
return bakedBase.getItemCameraTransforms();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemOverrideList getOverrides()
|
||||
{
|
||||
return bakedBase.getOverrides();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* This file is part of Applied Energistics 2.
|
||||
* Copyright (c) 2013 - 2014, AlgorithmX2, All rights reserved.
|
||||
*
|
||||
* 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.client.render.model;
|
||||
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import net.minecraft.client.renderer.block.model.IBakedModel;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.renderer.vertex.VertexFormat;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.client.model.IModel;
|
||||
import net.minecraftforge.client.model.ModelLoaderRegistry;
|
||||
import net.minecraftforge.common.model.IModelState;
|
||||
import net.minecraftforge.common.model.TRSRTransformation;
|
||||
|
||||
import appeng.block.storage.DriveSlotState;
|
||||
|
||||
|
||||
public class DriveModel implements IModel
|
||||
{
|
||||
|
||||
private static final ResourceLocation MODEL_BASE = new ResourceLocation( "appliedenergistics2:block/drive_base" );
|
||||
|
||||
private static final Map<DriveSlotState, ResourceLocation> MODELS_CELLS = ImmutableMap.of(
|
||||
DriveSlotState.EMPTY, new ResourceLocation( "appliedenergistics2:block/drive_cell_empty" ),
|
||||
DriveSlotState.OFFLINE, new ResourceLocation( "appliedenergistics2:block/drive_cell_off" ),
|
||||
DriveSlotState.ONLINE, new ResourceLocation( "appliedenergistics2:block/drive_cell_on" ),
|
||||
DriveSlotState.TYPES_FULL, new ResourceLocation( "appliedenergistics2:block/drive_cell_types_full" ),
|
||||
DriveSlotState.FULL, new ResourceLocation( "appliedenergistics2:block/drive_cell_full" )
|
||||
);
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getDependencies()
|
||||
{
|
||||
return ImmutableList.<ResourceLocation>builder().add( MODEL_BASE ).addAll( MODELS_CELLS.values() ).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ResourceLocation> getTextures()
|
||||
{
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBakedModel bake( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
|
||||
{
|
||||
EnumMap<DriveSlotState, IBakedModel> cellModels = new EnumMap<>( DriveSlotState.class );
|
||||
|
||||
// Load the base model and the model for each cell state.
|
||||
IModel baseModel;
|
||||
try
|
||||
{
|
||||
baseModel = ModelLoaderRegistry.getModel( MODEL_BASE );
|
||||
for( DriveSlotState slotState : MODELS_CELLS.keySet() )
|
||||
{
|
||||
IModel model = ModelLoaderRegistry.getModel( MODELS_CELLS.get( slotState ) );
|
||||
cellModels.put( slotState, model.bake( state, format, bakedTextureGetter ) );
|
||||
}
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
throw new RuntimeException( e );
|
||||
}
|
||||
|
||||
IBakedModel bakedBase = baseModel.bake( state, format, bakedTextureGetter );
|
||||
return new DriveBakedModel( bakedBase, cellModels );
|
||||
}
|
||||
|
||||
@Override
|
||||
public IModelState getDefaultState()
|
||||
{
|
||||
return TRSRTransformation.identity();
|
||||
}
|
||||
}
|
|
@ -55,7 +55,7 @@ final class MatrixVertexTransformer extends QuadGatheringTransformer
|
|||
VertexFormatElement element = format.getElement( e );
|
||||
if( element.getUsage() == VertexFormatElement.EnumUsage.POSITION )
|
||||
{
|
||||
parent.put( e, transform( quadData[e][v] ) );
|
||||
parent.put( e, transform( quadData[e][v], element.getElementCount() ) );
|
||||
}
|
||||
else if( element.getUsage() == VertexFormatElement.EnumUsage.NORMAL )
|
||||
{
|
||||
|
@ -93,7 +93,7 @@ final class MatrixVertexTransformer extends QuadGatheringTransformer
|
|||
parent.setTexture( texture );
|
||||
}
|
||||
|
||||
private float[] transform( float[] fs )
|
||||
private float[] transform( float[] fs, int elemCount )
|
||||
{
|
||||
switch( fs.length )
|
||||
{
|
||||
|
@ -113,6 +113,10 @@ final class MatrixVertexTransformer extends QuadGatheringTransformer
|
|||
};
|
||||
case 4:
|
||||
Vector4f vecc = new Vector4f( fs[0], fs[1], fs[2], fs[3] );
|
||||
// Otherwise all translation is lost
|
||||
if (elemCount == 3) {
|
||||
vecc.w = 1;
|
||||
}
|
||||
vecc.x -= 0.5f;
|
||||
vecc.y -= 0.5f;
|
||||
vecc.z -= 0.5f;
|
||||
|
|
|
@ -6,6 +6,8 @@ import java.io.Closeable;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
@ -13,7 +15,6 @@ import java.lang.reflect.Type;
|
|||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
|
@ -72,6 +73,8 @@ public enum UVLModelLoader implements ICustomModelLoader
|
|||
|
||||
private static final Constructor<? extends IModel> vanillaModelWrapper;
|
||||
private static final Field faceBakery;
|
||||
private static final Object vanillaLoader;
|
||||
private static final MethodHandle loaderGetter;
|
||||
|
||||
static
|
||||
{
|
||||
|
@ -86,6 +89,14 @@ public enum UVLModelLoader implements ICustomModelLoader
|
|||
Class clas = Class.forName( ModelLoader.class.getName() + "$VanillaModelWrapper" );
|
||||
vanillaModelWrapper = clas.getDeclaredConstructor( ModelLoader.class, ResourceLocation.class, ModelBlock.class, boolean.class, ModelBlockAnimation.class );
|
||||
vanillaModelWrapper.setAccessible( true );
|
||||
|
||||
Class<?> vanillaLoaderClass = Class.forName( ModelLoader.class.getName() + "$VanillaLoader" );
|
||||
Field instanceField = vanillaLoaderClass.getField( "INSTANCE" );
|
||||
// Static field
|
||||
vanillaLoader = instanceField.get( null );
|
||||
Field loaderField = vanillaLoaderClass.getDeclaredField( "loader" );
|
||||
loaderField.setAccessible( true );
|
||||
loaderGetter = MethodHandles.lookup().unreflectGetter( loaderField );
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
|
@ -133,16 +144,17 @@ public enum UVLModelLoader implements ICustomModelLoader
|
|||
}
|
||||
|
||||
private IResourceManager resourceManager;
|
||||
private ModelLoader loader;
|
||||
|
||||
public ModelLoader getLoader()
|
||||
{
|
||||
return loader;
|
||||
}
|
||||
|
||||
public void setLoader( ModelLoader loader )
|
||||
{
|
||||
this.loader = loader;
|
||||
try
|
||||
{
|
||||
return (ModelLoader) loaderGetter.invoke( vanillaLoader );
|
||||
}
|
||||
catch( Throwable throwable )
|
||||
{
|
||||
throw new RuntimeException( throwable );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -73,6 +73,7 @@ import appeng.block.storage.BlockDrive;
|
|||
import appeng.block.storage.BlockIOPort;
|
||||
import appeng.block.storage.BlockSkyChest;
|
||||
import appeng.block.storage.BlockSkyChest.SkyChestType;
|
||||
import appeng.block.storage.DriveRendering;
|
||||
import appeng.block.storage.SkyChestRenderingCustomizer;
|
||||
import appeng.bootstrap.BlockRenderingCustomizer;
|
||||
import appeng.bootstrap.FeatureFactory;
|
||||
|
@ -270,7 +271,11 @@ public final class ApiBlocks implements IBlocks
|
|||
this.spatialPylon = registry.block( "spatial_pylon", BlockSpatialPylon::new ).features( AEFeature.SpatialIO ).build();
|
||||
this.spatialIOPort = registry.block( "spatial_ioport", BlockSpatialIOPort::new ).features( AEFeature.SpatialIO ).build();
|
||||
this.controller = registry.block( "controller", BlockController::new ).features( AEFeature.Channels ).build();
|
||||
this.drive = registry.block( "drive", BlockDrive::new ).features( AEFeature.StorageCells, AEFeature.MEDrive ).build();
|
||||
this.drive = registry.block( "drive", BlockDrive::new )
|
||||
.features( AEFeature.StorageCells, AEFeature.MEDrive )
|
||||
.useCustomItemModel()
|
||||
.rendering( new DriveRendering() )
|
||||
.build();
|
||||
this.chest = registry.block( "chest", BlockChest::new ).features( AEFeature.StorageCells, AEFeature.MEChest ).build();
|
||||
this.iface = registry.block( "interface", BlockInterface::new ).build();
|
||||
this.cellWorkbench = registry.block( "cell_workbench", BlockCellWorkbench::new ).features( AEFeature.StorageCells ).build();
|
||||
|
|
|
@ -1,20 +1,5 @@
|
|||
{
|
||||
"variants": {
|
||||
"facing=east": {
|
||||
"model": "appliedenergistics2:drive",
|
||||
"y": 270
|
||||
},
|
||||
"facing=north": {
|
||||
"model": "appliedenergistics2:drive",
|
||||
"y": 180
|
||||
},
|
||||
"facing=south": {
|
||||
"model": "appliedenergistics2:drive",
|
||||
"y": 0
|
||||
},
|
||||
"facing=west": {
|
||||
"model": "appliedenergistics2:drive",
|
||||
"y": 90
|
||||
}
|
||||
}
|
||||
"variants": {
|
||||
"normal": { "model": "appliedenergistics2:builtin/drive" }
|
||||
}
|
||||
}
|
|
@ -693,8 +693,8 @@
|
|||
}
|
||||
],
|
||||
"textures": {
|
||||
"0": "blocks/BlockDriveSide",
|
||||
"1": "blocks/BlockDriveFront",
|
||||
"2": "blocks/BlockDrive"
|
||||
"0": "blocks/drive_side",
|
||||
"1": "blocks/drive_front",
|
||||
"2": "blocks/drive_top"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
{
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"side": "appliedenergistics2:blocks/drive_side",
|
||||
"bottom": "appliedenergistics2:blocks/drive_bottom",
|
||||
"top": "appliedenergistics2:blocks/drive_top",
|
||||
"front": "appliedenergistics2:blocks/drive_front",
|
||||
"inner": "appliedenergistics2:blocks/drive_bottom"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Right Side Panel",
|
||||
"from": [ 0.0, 1.0, 0.0 ],
|
||||
"to": [ 2.0, 15.0, 16.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" },
|
||||
"east": { "texture": "#inner" },
|
||||
"south": { "texture": "#side" },
|
||||
"west": { "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Left Side Panel",
|
||||
"from": [ 14.0, 1.0, 0.0 ],
|
||||
"to": [ 16.0, 15.0, 16.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" },
|
||||
"east": { "texture": "#side" },
|
||||
"south": { "texture": "#side" },
|
||||
"west": { "texture": "#inner" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Back Panel",
|
||||
"from": [ 2.0, 1.0, 8.0 ],
|
||||
"to": [ 14.0, 15.0, 16.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#inner" },
|
||||
"south": { "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bottom Panel",
|
||||
"from": [ 0.0, 0.0, 0.0 ],
|
||||
"to": [ 16.0, 1.0, 16.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" },
|
||||
"east": { "texture": "#side" },
|
||||
"south": { "texture": "#side" },
|
||||
"west": { "texture": "#side" },
|
||||
"up": { "texture": "#inner" },
|
||||
"down": { "texture": "#bottom" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top Panel",
|
||||
"from": [ 0.0, 15.0, 0.0 ],
|
||||
"to": [ 16.0, 16.0, 16.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" },
|
||||
"east": { "texture": "#side" },
|
||||
"south": { "texture": "#side" },
|
||||
"west": { "texture": "#side" },
|
||||
"up": { "texture": "#top" },
|
||||
"down": { "texture": "#inner" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Front Panel",
|
||||
"from": [ 2.0, 1.0, 0.0 ],
|
||||
"to": [ 14.0, 15.0, 8.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
{
|
||||
"parent": "block/block",
|
||||
"textures": {
|
||||
"side": "appliedenergistics2:blocks/drive_side",
|
||||
"bottom": "appliedenergistics2:blocks/drive_bottom",
|
||||
"top": "appliedenergistics2:blocks/drive_top",
|
||||
"front": "appliedenergistics2:blocks/drive_front",
|
||||
"inner": "appliedenergistics2:blocks/drive_bottom"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Right Side Panel",
|
||||
"from": [ 0.0, 1.0, 0.0 ],
|
||||
"to": [ 2.0, 15.0, 16.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" },
|
||||
"east": { "texture": "#inner" },
|
||||
"south": { "texture": "#side" },
|
||||
"west": { "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Left Side Panel",
|
||||
"from": [ 14.0, 1.0, 0.0 ],
|
||||
"to": [ 16.0, 15.0, 16.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" },
|
||||
"east": { "texture": "#side" },
|
||||
"south": { "texture": "#side" },
|
||||
"west": { "texture": "#inner" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Back Panel",
|
||||
"from": [ 2.0, 1.0, 8.0 ],
|
||||
"to": [ 14.0, 15.0, 16.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#inner" },
|
||||
"south": { "texture": "#side" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Bottom Panel",
|
||||
"from": [ 0.0, 0.0, 0.0 ],
|
||||
"to": [ 16.0, 1.0, 16.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" },
|
||||
"east": { "texture": "#side" },
|
||||
"south": { "texture": "#side" },
|
||||
"west": { "texture": "#side" },
|
||||
"up": { "texture": "#inner" },
|
||||
"down": { "texture": "#bottom" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Top Panel",
|
||||
"from": [ 0.0, 15.0, 0.0 ],
|
||||
"to": [ 16.0, 16.0, 16.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" },
|
||||
"east": { "texture": "#side" },
|
||||
"south": { "texture": "#side" },
|
||||
"west": { "texture": "#side" },
|
||||
"up": { "texture": "#top" },
|
||||
"down": { "texture": "#inner" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Middle Strut",
|
||||
"from": [ 7.0, 1.0, 0.0 ],
|
||||
"to": [ 9.0, 15.0, 8.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" },
|
||||
"east": { "texture": "#inner" },
|
||||
"west": { "texture": "#inner" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Separator",
|
||||
"from": [ 2.0, 3.0, 1.0 ],
|
||||
"to": [ 14.0, 4.0, 8.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" },
|
||||
"up": { "texture": "#inner" },
|
||||
"down": { "texture": "#inner" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Separator",
|
||||
"from": [ 2.0, 6.0, 1.0 ],
|
||||
"to": [ 14.0, 7.0, 8.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" },
|
||||
"up": { "texture": "#inner" },
|
||||
"down": { "texture": "#inner" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Separator",
|
||||
"from": [ 2.0, 9.0, 1.0 ],
|
||||
"to": [ 14.0, 10.0, 8.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" },
|
||||
"up": { "texture": "#inner" },
|
||||
"down": { "texture": "#inner" }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Separator",
|
||||
"from": [ 2.0, 12.0, 1.0 ],
|
||||
"to": [ 14.0, 13.0, 8.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front" },
|
||||
"up": { "texture": "#inner" },
|
||||
"down": { "texture": "#inner" }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"uvlMarker": true,
|
||||
"textures": {
|
||||
"front": "appliedenergistics2:blocks/drive_cell_states"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Cell Backdrop",
|
||||
"from": [ 9.0, 13.0, 0.0 ],
|
||||
"to": [ 14.0, 15.0, 1.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front", "uv": [0, 10, 5, 12] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"uvlMarker": true,
|
||||
"textures": {
|
||||
"front": "appliedenergistics2:blocks/drive_cell_states"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Cell Backdrop",
|
||||
"from": [ 9.0, 13.0, 0.0 ],
|
||||
"to": [ 14.0, 15.0, 1.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front", "uv": [0, 8, 5, 10] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cell Light",
|
||||
"from": [ 9.0, 13.0, 0.0 ],
|
||||
"to": [ 14.0, 15.0, 1.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front", "uv": [0, 6, 5, 8], "uvlightmap": { "sky": 0.007, "block": 0.007 } }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"textures": {
|
||||
"front": "appliedenergistics2:blocks/drive_cell_states"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Cell",
|
||||
"from": [ 9.0, 13.0, 0.0 ],
|
||||
"to": [ 14.0, 15.0, 1.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front", "uv": [0, 0, 5, 2] }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"uvlMarker": true,
|
||||
"textures": {
|
||||
"front": "appliedenergistics2:blocks/drive_cell_states"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Cell Backdrop",
|
||||
"from": [ 9.0, 13.0, 0.0 ],
|
||||
"to": [ 14.0, 15.0, 1.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front", "uv": [0, 8, 5, 10] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cell Light",
|
||||
"from": [ 9.0, 13.0, 0.0 ],
|
||||
"to": [ 14.0, 15.0, 1.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front", "uv": [0, 2, 5, 4], "uvlightmap": { "sky": 0.007, "block": 0.007 } }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"uvlMarker": true,
|
||||
"textures": {
|
||||
"front": "appliedenergistics2:blocks/drive_cell_states"
|
||||
},
|
||||
"elements": [
|
||||
{
|
||||
"name": "Cell Backdrop",
|
||||
"from": [ 9.0, 13.0, 0.0 ],
|
||||
"to": [ 14.0, 15.0, 1.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front", "uv": [0, 8, 5, 10] }
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Cell Light",
|
||||
"from": [ 9.0, 13.0, 0.0 ],
|
||||
"to": [ 14.0, 15.0, 1.0 ],
|
||||
"faces": {
|
||||
"north": { "texture": "#front", "uv": [0, 4, 5, 6], "uvlightmap": { "sky": 0.007, "block": 0.007 } }
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"parent": "appliedenergistics2:block/drive_base",
|
||||
"textures": {
|
||||
"front": "appliedenergistics2:blocks/drive_front_flat"
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 398 B |
Binary file not shown.
After Width: | Height: | Size: 182 B |
Binary file not shown.
After Width: | Height: | Size: 442 B |
Binary file not shown.
After Width: | Height: | Size: 274 B |
Binary file not shown.
After Width: | Height: | Size: 438 B |
Binary file not shown.
After Width: | Height: | Size: 398 B |
Loading…
Reference in New Issue