From f3e10b18512d94b067ea8f5c900051fe76852cd6 Mon Sep 17 00:00:00 2001 From: Sebastian Hartte Date: Fri, 26 Aug 2016 13:46:52 +0200 Subject: [PATCH] Implemented drive models. Fixed issues with the UVL model loader using a null model loader (and thus crashing). --- .../java/appeng/block/storage/BlockDrive.java | 31 ++++ .../appeng/block/storage/DriveRendering.java | 17 +++ .../appeng/block/storage/DriveSlotState.java | 43 ++++++ .../appeng/block/storage/DriveSlotsState.java | 93 ++++++++++++ .../storage/DriveSlotsStateProperty.java | 50 +++++++ src/main/java/appeng/client/ClientHelper.java | 7 - .../client/render/model/DriveBakedModel.java | 136 ++++++++++++++++++ .../client/render/model/DriveModel.java | 97 +++++++++++++ .../render/model/MatrixVertexTransformer.java | 8 +- .../client/render/model/UVLModelLoader.java | 28 ++-- .../core/api/definitions/ApiBlocks.java | 7 +- .../blockstates/drive.json | 21 +-- .../models/block/drive.json | 6 +- .../models/block/drive_base.json | 77 ++++++++++ .../models/block/drive_base_depth.json | 119 +++++++++++++++ .../models/block/drive_cell_empty.json | 16 +++ .../models/block/drive_cell_full.json | 24 ++++ .../models/block/drive_cell_off.json | 15 ++ .../models/block/drive_cell_on.json | 24 ++++ .../models/block/drive_cell_types_full.json | 24 ++++ .../models/item/drive.json | 6 + .../textures/blocks/drive_bottom.png | Bin 0 -> 398 bytes .../textures/blocks/drive_cell_states.png | Bin 0 -> 182 bytes .../textures/blocks/drive_front.png | Bin 0 -> 442 bytes .../textures/blocks/drive_front_flat.png | Bin 0 -> 274 bytes .../textures/blocks/drive_side.png | Bin 0 -> 438 bytes .../textures/blocks/drive_top.png | Bin 0 -> 398 bytes 27 files changed, 810 insertions(+), 39 deletions(-) create mode 100644 src/main/java/appeng/block/storage/DriveRendering.java create mode 100644 src/main/java/appeng/block/storage/DriveSlotState.java create mode 100644 src/main/java/appeng/block/storage/DriveSlotsState.java create mode 100644 src/main/java/appeng/block/storage/DriveSlotsStateProperty.java create mode 100644 src/main/java/appeng/client/render/model/DriveBakedModel.java create mode 100644 src/main/java/appeng/client/render/model/DriveModel.java create mode 100644 src/main/resources/assets/appliedenergistics2/models/block/drive_base.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/block/drive_base_depth.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/block/drive_cell_empty.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/block/drive_cell_full.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/block/drive_cell_off.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/block/drive_cell_on.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/block/drive_cell_types_full.json create mode 100644 src/main/resources/assets/appliedenergistics2/models/item/drive.json create mode 100644 src/main/resources/assets/appliedenergistics2/textures/blocks/drive_bottom.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/blocks/drive_cell_states.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/blocks/drive_front.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/blocks/drive_front_flat.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/blocks/drive_side.png create mode 100644 src/main/resources/assets/appliedenergistics2/textures/blocks/drive_top.png diff --git a/src/main/java/appeng/block/storage/BlockDrive.java b/src/main/java/appeng/block/storage/BlockDrive.java index 221a3e660..ffe6f9d4d 100644 --- a/src/main/java/appeng/block/storage/BlockDrive.java +++ b/src/main/java/appeng/block/storage/BlockDrive.java @@ -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 ) { diff --git a/src/main/java/appeng/block/storage/DriveRendering.java b/src/main/java/appeng/block/storage/DriveRendering.java new file mode 100644 index 000000000..33d610fe0 --- /dev/null +++ b/src/main/java/appeng/block/storage/DriveRendering.java @@ -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() ); + } +} diff --git a/src/main/java/appeng/block/storage/DriveSlotState.java b/src/main/java/appeng/block/storage/DriveSlotState.java new file mode 100644 index 000000000..9c01f92fd --- /dev/null +++ b/src/main/java/appeng/block/storage/DriveSlotState.java @@ -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 . + */ + +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 + +} diff --git a/src/main/java/appeng/block/storage/DriveSlotsState.java b/src/main/java/appeng/block/storage/DriveSlotsState.java new file mode 100644 index 000000000..d97305b66 --- /dev/null +++ b/src/main/java/appeng/block/storage/DriveSlotsState.java @@ -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 . + */ + +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 ); + } +} diff --git a/src/main/java/appeng/block/storage/DriveSlotsStateProperty.java b/src/main/java/appeng/block/storage/DriveSlotsStateProperty.java new file mode 100644 index 000000000..9a5497ec1 --- /dev/null +++ b/src/main/java/appeng/block/storage/DriveSlotsStateProperty.java @@ -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 . + */ + +package appeng.block.storage; + + +import net.minecraftforge.common.property.IUnlistedProperty; + + +public class DriveSlotsStateProperty implements IUnlistedProperty +{ + @Override + public String getName() + { + return "drive_slots_state"; + } + + @Override + public boolean isValid( DriveSlotsState value ) + { + return value != null; + } + + @Override + public Class getType() + { + return DriveSlotsState.class; + } + + @Override + public String valueToString( DriveSlotsState value ) + { + return value.toString(); + } +} diff --git a/src/main/java/appeng/client/ClientHelper.java b/src/main/java/appeng/client/ClientHelper.java index 478920038..a0960a4c1 100644 --- a/src/main/java/appeng/client/ClientHelper.java +++ b/src/main/java/appeng/client/ClientHelper.java @@ -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 ) { diff --git a/src/main/java/appeng/client/render/model/DriveBakedModel.java b/src/main/java/appeng/client/render/model/DriveBakedModel.java new file mode 100644 index 000000000..8088dd20d --- /dev/null +++ b/src/main/java/appeng/client/render/model/DriveBakedModel.java @@ -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 . + */ +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 bakedCells; + + public DriveBakedModel( IBakedModel bakedBase, Map bakedCells ) + { + this.bakedBase = bakedBase; + this.bakedCells = bakedCells; + } + + @Override + public List getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand ) + { + + List 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(); + } +} diff --git a/src/main/java/appeng/client/render/model/DriveModel.java b/src/main/java/appeng/client/render/model/DriveModel.java new file mode 100644 index 000000000..347bd561d --- /dev/null +++ b/src/main/java/appeng/client/render/model/DriveModel.java @@ -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 . + */ +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 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 getDependencies() + { + return ImmutableList.builder().add( MODEL_BASE ).addAll( MODELS_CELLS.values() ).build(); + } + + @Override + public Collection getTextures() + { + return Collections.emptyList(); + } + + @Override + public IBakedModel bake( IModelState state, VertexFormat format, Function bakedTextureGetter ) + { + EnumMap 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(); + } +} diff --git a/src/main/java/appeng/client/render/model/MatrixVertexTransformer.java b/src/main/java/appeng/client/render/model/MatrixVertexTransformer.java index a4ccff204..6a8976d42 100644 --- a/src/main/java/appeng/client/render/model/MatrixVertexTransformer.java +++ b/src/main/java/appeng/client/render/model/MatrixVertexTransformer.java @@ -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; diff --git a/src/main/java/appeng/client/render/model/UVLModelLoader.java b/src/main/java/appeng/client/render/model/UVLModelLoader.java index 9cbe8f75c..16273839f 100644 --- a/src/main/java/appeng/client/render/model/UVLModelLoader.java +++ b/src/main/java/appeng/client/render/model/UVLModelLoader.java @@ -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 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 diff --git a/src/main/java/appeng/core/api/definitions/ApiBlocks.java b/src/main/java/appeng/core/api/definitions/ApiBlocks.java index 896ff258b..d5d49800a 100644 --- a/src/main/java/appeng/core/api/definitions/ApiBlocks.java +++ b/src/main/java/appeng/core/api/definitions/ApiBlocks.java @@ -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(); diff --git a/src/main/resources/assets/appliedenergistics2/blockstates/drive.json b/src/main/resources/assets/appliedenergistics2/blockstates/drive.json index 63b2bd47e..bc21ce0a5 100644 --- a/src/main/resources/assets/appliedenergistics2/blockstates/drive.json +++ b/src/main/resources/assets/appliedenergistics2/blockstates/drive.json @@ -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" } + } } \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/drive.json b/src/main/resources/assets/appliedenergistics2/models/block/drive.json index 3da8cb2ea..f93e68a30 100644 --- a/src/main/resources/assets/appliedenergistics2/models/block/drive.json +++ b/src/main/resources/assets/appliedenergistics2/models/block/drive.json @@ -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" } } \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/drive_base.json b/src/main/resources/assets/appliedenergistics2/models/block/drive_base.json new file mode 100644 index 000000000..e8ad35e7a --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/block/drive_base.json @@ -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" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/drive_base_depth.json b/src/main/resources/assets/appliedenergistics2/models/block/drive_base_depth.json new file mode 100644 index 000000000..1efc548ec --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/block/drive_base_depth.json @@ -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" } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_empty.json b/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_empty.json new file mode 100644 index 000000000..04a35f6b2 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_empty.json @@ -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] } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_full.json b/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_full.json new file mode 100644 index 000000000..6dccc2ac5 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_full.json @@ -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 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_off.json b/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_off.json new file mode 100644 index 000000000..16ac7a976 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_off.json @@ -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] } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_on.json b/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_on.json new file mode 100644 index 000000000..582390500 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_on.json @@ -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 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_types_full.json b/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_types_full.json new file mode 100644 index 000000000..1aab86dec --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/block/drive_cell_types_full.json @@ -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 } } + } + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/models/item/drive.json b/src/main/resources/assets/appliedenergistics2/models/item/drive.json new file mode 100644 index 000000000..a80e01134 --- /dev/null +++ b/src/main/resources/assets/appliedenergistics2/models/item/drive.json @@ -0,0 +1,6 @@ +{ + "parent": "appliedenergistics2:block/drive_base", + "textures": { + "front": "appliedenergistics2:blocks/drive_front_flat" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/drive_bottom.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/drive_bottom.png new file mode 100644 index 0000000000000000000000000000000000000000..6a87e174a2e43b44724edcf21803e1d38696666f GIT binary patch literal 398 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd7G?$phPQVgfdp969eo`c7&i8E|4C$JU|>*4 z_6YK2V5m}KU}$JzVEDzrz|io5fuYoZf#FpG1B2BJ1_tqhIlBUF7#J8-0(?STwbkT} z^;FFb)iqRP8yXr+_0@EBb?)&BqgKU1{tB?AKkW0JSK3%C6BBL^55 z7&r?&B8wRq_?Ce%WBZ+z`3wvU_MR?|Asp9}6GTFSf3kK2Q(VY zk#JGqac}Y9oF%2AIcJxQVTt8IozkR?`BIWg;^ag*7@VeR$yTK@d}Ux@P%UwdC`m~y zNwrEYN=+QHnuXf&^0i%GBCL2dU8LChTQy=%(P0l1_P52 zBV#KAV=Ds_T>~>K1B0(uxz{r=Fi3%H2+mI{DNig)We7;j%q!9Ja}7}_GuAWJGc+*x TQnZkPfq}u()z4*}Q$iB}WkG9Q literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/drive_cell_states.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/drive_cell_states.png new file mode 100644 index 0000000000000000000000000000000000000000..30110f56456e66bc7dc4f55bc8905c4ad079b4ae GIT binary patch literal 182 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s7BuiW)N`mv#O3D+9QW+dm z@{>{(JaZG%Q-e|yQz{EjrrIztFhqE|IEGZ*x-!X-?|=aZ^V>S1c^y~Wtul|LcrtnC zCmgntln^}BGE;E2&HaM%J5HV_40vu72QfCy;5ty9A8?s*hJnV<=EeJ@Iz jubP0l+XkKgXumA literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/drive_front.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/drive_front.png new file mode 100644 index 0000000000000000000000000000000000000000..4e9bd62a2b0eb0d54e9ae155e466957eb41861aa GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4rT@h1`S>QUNSs54@ z6p}rHd>I(3)EF2VS{N99F)%PRykKA`HDF+PmB7GYHG_dcykO3*KpO@I2IByq5LX5U z1~)q+M{9joTSH?#)r5ou4Ha1z8v`v>S#33Wc^Pq68+{#BSuIsLb!9n4S@Hk>|Jz(y zsm;K^z*rLG7tG-B>_!@hljQC0A~1CmuMPtP180FpWHAE+-!c$pY`?QIpMinF-_yl0 zMB;L5Zy;ZT0f#g9uE>%dzwd{c{M%5w#?$%I6uXX9T{#c^t(QCq{po*nBD0(F$pt$L z`=r~n_ZKWX(R65H(DPo=qt6<0-ktSq%YVKLIwr~ N22WQ%mvv4FO#mYmfk*%V literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/drive_front_flat.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/drive_front_flat.png new file mode 100644 index 0000000000000000000000000000000000000000..00287e0d127fce8d4342ec65b2052eb0832f3f47 GIT binary patch literal 274 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4kiW$h6xih%orFLBuiW)N`mv#O3D+9QW+dm z@{>{(JaZG%Q-e|yQz{EjrrIztFl_O3aSW-rl~l6X_}Aa>`pgm=jEtF2{{R2~|IhFI zhuoO+?Q7B)gFdZllQz$DnfBrPclJp$n)>_Rr2hK;UY_}4L+8Xs!51o;s$r%#N5=<9?kvo-kw>QS+n6u0F!0s z5-7nW)h?v0ES$NJrD)Q$RXQ4bBqaVB8Z=4%KiKoXfK}kz{ra9WK0Np9|FCcvFeuFl Wopvmwt%`wxfx*+&&t;ucLK6USp=ziA literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/drive_side.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/drive_side.png new file mode 100644 index 0000000000000000000000000000000000000000..6c7e4831f00092a2dd623bf67ad9459ea03435c6 GIT binary patch literal 438 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4rT@h1`S>QUNSs54@ z6p}rHd>I(3)EF2VS{N99F)%PRykKA`HDF+PmB7GYHG_dcykO3*KpO@I2Acq%5LY)l zBS&j}S6f44J=KPW1`QQi7aIdDRoUF!Tx~UZc^Pq68~v1&6klIo2L}foRaq@nIdx?@ zMOpFx|NqBGKKjhSz`&T~?d~GXvpZ%Q0|NtRfk$L90|VbO5N2$@vofE7fx+L?#W6(U za%ztwUxNY9;h+UAh6%F&>vcr8=S(ZwxP~E(O=stP(Hkts*EJnb6q(UgtoKUwNjsOk ztJrpj8C>$*?zJs{0s_+ z8kkub7<|3Ty`F)AK?-C;aDG}zd16s2LqK9?UWuNcYluRbv7V`(p@G4dqJ<0$3=E#G KelF{r5}E+&YkM&O literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/appliedenergistics2/textures/blocks/drive_top.png b/src/main/resources/assets/appliedenergistics2/textures/blocks/drive_top.png new file mode 100644 index 0000000000000000000000000000000000000000..7ec66578158e7a321dc0d6e99aeaeb072c4130f4 GIT binary patch literal 398 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd7G?$phPQVgfdp969eo`c7&i8E|4C$JU|>*4 z_6YK2V5m}KU}$JzVEDzrz|io5fuYoZf#FpG1B2BJ1_tqhIlBUF7#J8-0(?STwbkT} z^;FFb)iqRP8yXr+_0?9aSYf8Gs--Gxp|5JBtM>o@|J_V-oD2*Mj7i?^F5L3hj~rlN zVBjq9h%9Dc;9Ca5jO}+;<})xb*n7G-hHzX@P7nzR3JM7dN((4tWOi?xU}8{^9?)no zN5Vyc$GydabC#5fW=X8yj#A5mI;BY&^Q9!0#L0&g8n8glbfGSe#I8VpQA zjEt=ejI9hzbPdd`3=F