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 javax.annotation.Nullable;
|
||||||
|
|
||||||
import net.minecraft.block.material.Material;
|
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.entity.player.EntityPlayer;
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.util.BlockRenderLayer;
|
import net.minecraft.util.BlockRenderLayer;
|
||||||
import net.minecraft.util.EnumFacing;
|
import net.minecraft.util.EnumFacing;
|
||||||
import net.minecraft.util.EnumHand;
|
import net.minecraft.util.EnumHand;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
import net.minecraft.world.IBlockAccess;
|
||||||
import net.minecraft.world.World;
|
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.api.util.AEPartLocation;
|
||||||
import appeng.block.AEBaseTileBlock;
|
import appeng.block.AEBaseTileBlock;
|
||||||
|
@ -40,6 +46,8 @@ import appeng.util.Platform;
|
||||||
public class BlockDrive extends AEBaseTileBlock
|
public class BlockDrive extends AEBaseTileBlock
|
||||||
{
|
{
|
||||||
|
|
||||||
|
public static final DriveSlotsStateProperty SLOTS_STATE = new DriveSlotsStateProperty();
|
||||||
|
|
||||||
public BlockDrive()
|
public BlockDrive()
|
||||||
{
|
{
|
||||||
super( Material.IRON );
|
super( Material.IRON );
|
||||||
|
@ -52,6 +60,29 @@ public class BlockDrive extends AEBaseTileBlock
|
||||||
return BlockRenderLayer.CUTOUT;
|
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
|
@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 )
|
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 )
|
||||||
{
|
{
|
||||||
|
|
17
src/main/java/appeng/block/storage/DriveRendering.java
Normal file
17
src/main/java/appeng/block/storage/DriveRendering.java
Normal file
|
@ -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() );
|
||||||
|
}
|
||||||
|
}
|
43
src/main/java/appeng/block/storage/DriveSlotState.java
Normal file
43
src/main/java/appeng/block/storage/DriveSlotState.java
Normal file
|
@ -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
|
||||||
|
|
||||||
|
}
|
93
src/main/java/appeng/block/storage/DriveSlotsState.java
Normal file
93
src/main/java/appeng/block/storage/DriveSlotsState.java
Normal file
|
@ -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.RayTraceResult;
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
import net.minecraftforge.client.event.ModelBakeEvent;
|
|
||||||
import net.minecraftforge.client.event.MouseEvent;
|
import net.minecraftforge.client.event.MouseEvent;
|
||||||
import net.minecraftforge.client.event.RenderLivingEvent;
|
import net.minecraftforge.client.event.RenderLivingEvent;
|
||||||
import net.minecraftforge.client.event.TextureStitchEvent;
|
import net.minecraftforge.client.event.TextureStitchEvent;
|
||||||
|
@ -356,12 +355,6 @@ public class ClientHelper extends ServerHelper
|
||||||
Minecraft.getMinecraft().effectRenderer.addEffect( fx );
|
Minecraft.getMinecraft().effectRenderer.addEffect( fx );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SubscribeEvent
|
|
||||||
public void onModelBakeEvent( final ModelBakeEvent event )
|
|
||||||
{
|
|
||||||
UVLModelLoader.INSTANCE.setLoader( event.getModelLoader() );
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public void wheelEvent( final MouseEvent me )
|
public void wheelEvent( final MouseEvent me )
|
||||||
{
|
{
|
||||||
|
|
136
src/main/java/appeng/client/render/model/DriveBakedModel.java
Normal file
136
src/main/java/appeng/client/render/model/DriveBakedModel.java
Normal file
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
97
src/main/java/appeng/client/render/model/DriveModel.java
Normal file
97
src/main/java/appeng/client/render/model/DriveModel.java
Normal file
|
@ -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 );
|
VertexFormatElement element = format.getElement( e );
|
||||||
if( element.getUsage() == VertexFormatElement.EnumUsage.POSITION )
|
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 )
|
else if( element.getUsage() == VertexFormatElement.EnumUsage.NORMAL )
|
||||||
{
|
{
|
||||||
|
@ -93,7 +93,7 @@ final class MatrixVertexTransformer extends QuadGatheringTransformer
|
||||||
parent.setTexture( texture );
|
parent.setTexture( texture );
|
||||||
}
|
}
|
||||||
|
|
||||||
private float[] transform( float[] fs )
|
private float[] transform( float[] fs, int elemCount )
|
||||||
{
|
{
|
||||||
switch( fs.length )
|
switch( fs.length )
|
||||||
{
|
{
|
||||||
|
@ -113,6 +113,10 @@ final class MatrixVertexTransformer extends QuadGatheringTransformer
|
||||||
};
|
};
|
||||||
case 4:
|
case 4:
|
||||||
Vector4f vecc = new Vector4f( fs[0], fs[1], fs[2], fs[3] );
|
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.x -= 0.5f;
|
||||||
vecc.y -= 0.5f;
|
vecc.y -= 0.5f;
|
||||||
vecc.z -= 0.5f;
|
vecc.z -= 0.5f;
|
||||||
|
|
|
@ -6,6 +6,8 @@ import java.io.Closeable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
|
@ -13,7 +15,6 @@ import java.lang.reflect.Type;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
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 Constructor<? extends IModel> vanillaModelWrapper;
|
||||||
private static final Field faceBakery;
|
private static final Field faceBakery;
|
||||||
|
private static final Object vanillaLoader;
|
||||||
|
private static final MethodHandle loaderGetter;
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
|
@ -86,6 +89,14 @@ public enum UVLModelLoader implements ICustomModelLoader
|
||||||
Class clas = Class.forName( ModelLoader.class.getName() + "$VanillaModelWrapper" );
|
Class clas = Class.forName( ModelLoader.class.getName() + "$VanillaModelWrapper" );
|
||||||
vanillaModelWrapper = clas.getDeclaredConstructor( ModelLoader.class, ResourceLocation.class, ModelBlock.class, boolean.class, ModelBlockAnimation.class );
|
vanillaModelWrapper = clas.getDeclaredConstructor( ModelLoader.class, ResourceLocation.class, ModelBlock.class, boolean.class, ModelBlockAnimation.class );
|
||||||
vanillaModelWrapper.setAccessible( true );
|
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 )
|
catch( Exception e )
|
||||||
{
|
{
|
||||||
|
@ -133,16 +144,17 @@ public enum UVLModelLoader implements ICustomModelLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
private IResourceManager resourceManager;
|
private IResourceManager resourceManager;
|
||||||
private ModelLoader loader;
|
|
||||||
|
|
||||||
public ModelLoader getLoader()
|
public ModelLoader getLoader()
|
||||||
{
|
{
|
||||||
return loader;
|
try
|
||||||
}
|
{
|
||||||
|
return (ModelLoader) loaderGetter.invoke( vanillaLoader );
|
||||||
public void setLoader( ModelLoader loader )
|
}
|
||||||
{
|
catch( Throwable throwable )
|
||||||
this.loader = loader;
|
{
|
||||||
|
throw new RuntimeException( throwable );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -73,6 +73,7 @@ import appeng.block.storage.BlockDrive;
|
||||||
import appeng.block.storage.BlockIOPort;
|
import appeng.block.storage.BlockIOPort;
|
||||||
import appeng.block.storage.BlockSkyChest;
|
import appeng.block.storage.BlockSkyChest;
|
||||||
import appeng.block.storage.BlockSkyChest.SkyChestType;
|
import appeng.block.storage.BlockSkyChest.SkyChestType;
|
||||||
|
import appeng.block.storage.DriveRendering;
|
||||||
import appeng.block.storage.SkyChestRenderingCustomizer;
|
import appeng.block.storage.SkyChestRenderingCustomizer;
|
||||||
import appeng.bootstrap.BlockRenderingCustomizer;
|
import appeng.bootstrap.BlockRenderingCustomizer;
|
||||||
import appeng.bootstrap.FeatureFactory;
|
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.spatialPylon = registry.block( "spatial_pylon", BlockSpatialPylon::new ).features( AEFeature.SpatialIO ).build();
|
||||||
this.spatialIOPort = registry.block( "spatial_ioport", BlockSpatialIOPort::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.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.chest = registry.block( "chest", BlockChest::new ).features( AEFeature.StorageCells, AEFeature.MEChest ).build();
|
||||||
this.iface = registry.block( "interface", BlockInterface::new ).build();
|
this.iface = registry.block( "interface", BlockInterface::new ).build();
|
||||||
this.cellWorkbench = registry.block( "cell_workbench", BlockCellWorkbench::new ).features( AEFeature.StorageCells ).build();
|
this.cellWorkbench = registry.block( "cell_workbench", BlockCellWorkbench::new ).features( AEFeature.StorageCells ).build();
|
||||||
|
|
|
@ -1,20 +1,5 @@
|
||||||
{
|
{
|
||||||
"variants": {
|
"variants": {
|
||||||
"facing=east": {
|
"normal": { "model": "appliedenergistics2:builtin/drive" }
|
||||||
"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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -693,8 +693,8 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"textures": {
|
"textures": {
|
||||||
"0": "blocks/BlockDriveSide",
|
"0": "blocks/drive_side",
|
||||||
"1": "blocks/BlockDriveFront",
|
"1": "blocks/drive_front",
|
||||||
"2": "blocks/BlockDrive"
|
"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 a new issue