From 2891014cf68db6dda93b3b1bb4cfb08cb561b18b Mon Sep 17 00:00:00 2001 From: fscan Date: Sat, 14 Jul 2018 17:05:07 +0200 Subject: [PATCH] P2P tunnel frequency color indicators (#3610) --- src/api/java/appeng/api/parts/IPart.java | 10 + .../appeng/api/parts/IPartBakedModel.java | 15 + .../render/cablebus/CableBusBakedModel.java | 11 +- .../render/cablebus/CableBusRenderState.java | 10 +- .../P2PTunnelFrequencyBakedModel.java | 142 +++ .../cablebus/P2PTunnelFrequencyModel.java | 43 + .../appeng/items/parts/ItemPartRendering.java | 4 + .../java/appeng/parts/CableBusContainer.java | 2 + src/main/java/appeng/parts/p2p/P2PModels.java | 8 +- .../java/appeng/parts/p2p/PartP2PTunnel.java | 39 +- .../models/part/p2p/p2p_tunnel_base.json | 913 +++++++++++++++++- .../textures/parts/p2p_tunnel_frequency.png | Bin 0 -> 2799 bytes 12 files changed, 1143 insertions(+), 54 deletions(-) create mode 100644 src/api/java/appeng/api/parts/IPartBakedModel.java create mode 100644 src/main/java/appeng/client/render/cablebus/P2PTunnelFrequencyBakedModel.java create mode 100644 src/main/java/appeng/client/render/cablebus/P2PTunnelFrequencyModel.java create mode 100644 src/main/resources/assets/appliedenergistics2/textures/parts/p2p_tunnel_frequency.png diff --git a/src/api/java/appeng/api/parts/IPart.java b/src/api/java/appeng/api/parts/IPart.java index 7e6f9819d..530bb7073 100644 --- a/src/api/java/appeng/api/parts/IPart.java +++ b/src/api/java/appeng/api/parts/IPart.java @@ -355,4 +355,14 @@ public interface IPart extends IBoxProvider, ICustomCableConnection return null; } + /** + * Flag to be passed to the renderer. + * + * @return flag or null + */ + default Long getRenderFlag() + { + return null; + } + } \ No newline at end of file diff --git a/src/api/java/appeng/api/parts/IPartBakedModel.java b/src/api/java/appeng/api/parts/IPartBakedModel.java new file mode 100644 index 000000000..6444fc91d --- /dev/null +++ b/src/api/java/appeng/api/parts/IPartBakedModel.java @@ -0,0 +1,15 @@ + +package appeng.api.parts; + + +import java.util.List; + +import javax.annotation.Nullable; + +import net.minecraft.client.renderer.block.model.BakedQuad; + + +public interface IPartBakedModel +{ + List getPartQuads( @Nullable Long partFlags, long rand ); +} diff --git a/src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java b/src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java index 9bfe79a8d..ee46d86c9 100644 --- a/src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java +++ b/src/main/java/appeng/client/render/cablebus/CableBusBakedModel.java @@ -44,6 +44,7 @@ import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.MinecraftForgeClient; import net.minecraftforge.common.property.IExtendedBlockState; +import appeng.api.parts.IPartBakedModel; import appeng.api.parts.IPartModel; import appeng.api.util.AECableType; import appeng.api.util.AEColor; @@ -119,7 +120,15 @@ public class CableBusBakedModel implements IBakedModel throw new IllegalStateException( "Trying to use an unregistered part model: " + model ); } - List partQuads = bakedModel.getQuads( state, null, rand ); + List partQuads; + if( bakedModel instanceof IPartBakedModel ) + { + partQuads = ( (IPartBakedModel) bakedModel ).getPartQuads( renderState.getPartFlags().get( facing ), rand ); + } + else + { + partQuads = bakedModel.getQuads( state, null, rand ); + } // Rotate quads accordingly QuadRotator rotator = new QuadRotator(); diff --git a/src/main/java/appeng/client/render/cablebus/CableBusRenderState.java b/src/main/java/appeng/client/render/cablebus/CableBusRenderState.java index 1f6bbc3f3..cbd5690a8 100644 --- a/src/main/java/appeng/client/render/cablebus/CableBusRenderState.java +++ b/src/main/java/appeng/client/render/cablebus/CableBusRenderState.java @@ -74,6 +74,8 @@ public class CableBusRenderState // facades on this cable bus private List boundingBoxes = new ArrayList<>(); + private EnumMap partFlags = new EnumMap<>( EnumFacing.class ); + public CableCoreType getCoreType() { return this.coreType; @@ -154,6 +156,11 @@ public class CableBusRenderState return this.boundingBoxes; } + public EnumMap getPartFlags() + { + return this.partFlags; + } + @Override public int hashCode() { @@ -166,6 +173,7 @@ public class CableBusRenderState result = prime * result + ( ( this.channelsOnSide == null ) ? 0 : this.channelsOnSide.hashCode() ); result = prime * result + ( ( this.connectionTypes == null ) ? 0 : this.connectionTypes.hashCode() ); result = prime * result + ( ( this.coreType == null ) ? 0 : this.coreType.hashCode() ); + result = prime * result + ( ( this.partFlags == null ) ? 0 : this.partFlags.hashCode() ); return result; } @@ -190,7 +198,7 @@ public class CableBusRenderState return this.cableColor == other.cableColor && this.cableType == other.cableType && this.coreType == other.coreType && Objects .equals( this.attachmentConnections, other.attachmentConnections ) && Objects.equals( this.cableBusAdjacent, other.cableBusAdjacent ) && Objects.equals( this.channelsOnSide, other.channelsOnSide ) && Objects.equals( this.connectionTypes, - other.connectionTypes ); + other.connectionTypes ) && Objects.equals( this.partFlags, other.partFlags ); } } diff --git a/src/main/java/appeng/client/render/cablebus/P2PTunnelFrequencyBakedModel.java b/src/main/java/appeng/client/render/cablebus/P2PTunnelFrequencyBakedModel.java new file mode 100644 index 000000000..7faa91ae4 --- /dev/null +++ b/src/main/java/appeng/client/render/cablebus/P2PTunnelFrequencyBakedModel.java @@ -0,0 +1,142 @@ + +package appeng.client.render.cablebus; + + +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ExecutionException; + +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; + +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.ItemOverrideList; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.renderer.vertex.VertexFormat; +import net.minecraft.util.EnumFacing; + +import appeng.api.parts.IPartBakedModel; +import appeng.api.util.AEColor; +import appeng.util.Platform; + + +public class P2PTunnelFrequencyBakedModel implements IBakedModel, IPartBakedModel +{ + private final VertexFormat format; + private final TextureAtlasSprite texture; + + private final static Cache> modelCache = CacheBuilder.newBuilder().maximumSize( 100 ).build(); + + private static final int[][] QUAD_OFFSETS = new int[][] { + { 4, 10, 2 }, + { 10, 10, 2 }, + { 4, 4, 2 }, + { 10, 4, 2 } + }; + + public P2PTunnelFrequencyBakedModel( final VertexFormat format, final TextureAtlasSprite texture ) + { + this.format = format; + this.texture = texture; + } + + @Override + public List getPartQuads( Long partFlags, long rand ) + { + try + { + return modelCache.get( partFlags, () -> + { + short frequency = 0; + boolean active = false; + if( partFlags != null ) + { + frequency = (short) ( partFlags.longValue() & 0xffffL ); + active = ( partFlags.longValue() & 0x10000L ) != 0; + } + return getQuadsForFrequency( frequency, active ); + } ); + } + catch( ExecutionException e ) + { + return Collections.emptyList(); + } + } + + @Override + public List getQuads( IBlockState state, EnumFacing side, long rand ) + { + if( side != null ) + { + return Collections.emptyList(); + } + return getPartQuads( null, rand ); + } + + private List getQuadsForFrequency( final short frequency, final boolean active ) + { + final AEColor[] colors = Platform.p2p().toColors( frequency ); + final CubeBuilder cb = new CubeBuilder( this.format ); + + cb.setTexture( this.texture ); + cb.useStandardUV(); + cb.setRenderFullBright( active ); + + for( int i = 0; i < 4; ++i ) + { + final int[] offs = QUAD_OFFSETS[i]; + for( int j = 0; j < 4; ++j ) + { + final AEColor c = colors[j]; + if( active ) + { + cb.setColorRGB( c.dye.getColorValue() ); + } + else + { + final float cv[] = c.dye.getColorComponentValues(); + cb.setColorRGB( cv[0] * 0.5f, cv[1] * 0.5f, cv[2] * 0.5f ); + } + + final int startx = j % 2; + final int starty = 1 - j / 2; + + cb.addCube( offs[0] + startx, offs[1] + starty, offs[2], offs[0] + startx + 1, offs[1] + starty + 1, offs[2] + 1 ); + } + + } + return cb.getOutput(); + } + + @Override + public boolean isAmbientOcclusion() + { + return false; + } + + @Override + public boolean isGui3d() + { + return false; + } + + @Override + public boolean isBuiltInRenderer() + { + return true; + } + + @Override + public TextureAtlasSprite getParticleTexture() + { + return this.texture; + } + + @Override + public ItemOverrideList getOverrides() + { + return ItemOverrideList.NONE; + } +} diff --git a/src/main/java/appeng/client/render/cablebus/P2PTunnelFrequencyModel.java b/src/main/java/appeng/client/render/cablebus/P2PTunnelFrequencyModel.java new file mode 100644 index 000000000..6e6fcb927 --- /dev/null +++ b/src/main/java/appeng/client/render/cablebus/P2PTunnelFrequencyModel.java @@ -0,0 +1,43 @@ + +package appeng.client.render.cablebus; + + +import java.util.Collection; +import java.util.Collections; +import java.util.function.Function; + +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.common.model.IModelState; + +import appeng.core.AppEng; + + +public class P2PTunnelFrequencyModel implements IModel +{ + private static final ResourceLocation TEXTURE = new ResourceLocation( AppEng.MOD_ID, "parts/p2p_tunnel_frequency" ); + + @Override + public Collection getTextures() + { + return Collections.singletonList( TEXTURE ); + } + + @Override + public IBakedModel bake( IModelState state, VertexFormat format, Function bakedTextureGetter ) + { + try + { + final TextureAtlasSprite texture = bakedTextureGetter.apply( TEXTURE ); + return new P2PTunnelFrequencyBakedModel( format, texture ); + } + catch( Exception e ) + { + throw new RuntimeException( e ); + } + } + +} diff --git a/src/main/java/appeng/items/parts/ItemPartRendering.java b/src/main/java/appeng/items/parts/ItemPartRendering.java index 9672ca07e..50f31642d 100644 --- a/src/main/java/appeng/items/parts/ItemPartRendering.java +++ b/src/main/java/appeng/items/parts/ItemPartRendering.java @@ -34,6 +34,7 @@ import appeng.api.util.AEColor; import appeng.bootstrap.IItemRendering; import appeng.bootstrap.ItemRenderingCustomizer; import appeng.client.render.StaticItemColor; +import appeng.client.render.cablebus.P2PTunnelFrequencyModel; import appeng.core.AppEng; import appeng.core.features.registries.PartModels; import appeng.parts.automation.PlaneConnections; @@ -128,6 +129,9 @@ public class ItemPartRendering extends ItemRenderingCustomizer } + // base p2p model with frequency + rendering.builtInModel( "models/part/builtin/p2p_tunnel_frequency", new P2PTunnelFrequencyModel() ); + List partResourceLocs = modelNames.stream() .map( name -> new ResourceLocation( AppEng.MOD_ID, name ) ) .collect( Collectors.toList() ); diff --git a/src/main/java/appeng/parts/CableBusContainer.java b/src/main/java/appeng/parts/CableBusContainer.java index 0a1e9507b..645a58db5 100644 --- a/src/main/java/appeng/parts/CableBusContainer.java +++ b/src/main/java/appeng/parts/CableBusContainer.java @@ -1247,6 +1247,8 @@ public class CableBusContainer extends CableBusStorage implements AEMultiTile, I continue; } + renderState.getPartFlags().put( facing, part.getRenderFlag() ); + // This will add the part's bounding boxes to the render state, which is required for facades final AEPartLocation loc = AEPartLocation.fromFacing( facing ); final IPartCollisionHelper bch = new BusCollisionHelper( renderState.getBoundingBoxes(), loc, null, true ); diff --git a/src/main/java/appeng/parts/p2p/P2PModels.java b/src/main/java/appeng/parts/p2p/P2PModels.java index fc5b96a84..6bc8060ce 100644 --- a/src/main/java/appeng/parts/p2p/P2PModels.java +++ b/src/main/java/appeng/parts/p2p/P2PModels.java @@ -38,6 +38,7 @@ class P2PModels public static final ResourceLocation MODEL_STATUS_OFF = new ResourceLocation( AppEng.MOD_ID, "part/p2p/p2p_tunnel_status_off" ); public static final ResourceLocation MODEL_STATUS_ON = new ResourceLocation( AppEng.MOD_ID, "part/p2p/p2p_tunnel_status_on" ); public static final ResourceLocation MODEL_STATUS_HAS_CHANNEL = new ResourceLocation( AppEng.MOD_ID, "part/p2p/p2p_tunnel_status_has_channel" ); + public static final ResourceLocation MODEL_FREQUENCY = new ResourceLocation( AppEng.MOD_ID, "part/builtin/p2p_tunnel_frequency" ); private final IPartModel modelsOff; private final IPartModel modelsOn; @@ -46,9 +47,10 @@ class P2PModels public P2PModels( String frontModelPath ) { ResourceLocation frontModel = new ResourceLocation( AppEng.MOD_ID, frontModelPath ); - this.modelsOff = new PartModel( MODEL_STATUS_OFF, frontModel ); - this.modelsOn = new PartModel( MODEL_STATUS_ON, frontModel ); - this.modelsHasChannel = new PartModel( MODEL_STATUS_HAS_CHANNEL, frontModel ); + + this.modelsOff = new PartModel( MODEL_STATUS_OFF, MODEL_FREQUENCY, frontModel ); + this.modelsOn = new PartModel( MODEL_STATUS_ON, MODEL_FREQUENCY, frontModel ); + this.modelsHasChannel = new PartModel( MODEL_STATUS_HAS_CHANNEL, MODEL_FREQUENCY, frontModel ); } public IPartModel getModel( boolean hasPower, boolean hasChannel ) diff --git a/src/main/java/appeng/parts/p2p/PartP2PTunnel.java b/src/main/java/appeng/parts/p2p/PartP2PTunnel.java index e93484e16..91a9e3679 100644 --- a/src/main/java/appeng/parts/p2p/PartP2PTunnel.java +++ b/src/main/java/appeng/parts/p2p/PartP2PTunnel.java @@ -19,10 +19,13 @@ package appeng.parts.p2p; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.Optional; +import io.netty.buffer.ByteBuf; + import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; @@ -134,7 +137,7 @@ public abstract class PartP2PTunnel extends PartBasicSt { super.readFromNBT( data ); this.setOutput( data.getBoolean( "output" ) ); - this.setFrequency( data.getShort( "freq" ) ); + this.freq = data.getShort( "freq" ); } @Override @@ -145,6 +148,22 @@ public abstract class PartP2PTunnel extends PartBasicSt data.setShort( "freq", this.getFrequency() ); } + @Override + public boolean readFromStream( ByteBuf data ) throws IOException + { + final boolean c = super.readFromStream( data ); + final short oldf = this.freq; + this.freq = data.readShort(); + return c || oldf != this.freq; + } + + @Override + public void writeToStream( ByteBuf data ) throws IOException + { + super.writeToStream( data ); + data.writeShort( getFrequency() ); + } + @Override public float getCableConnectionLength( AECableType cable ) { @@ -381,7 +400,12 @@ public abstract class PartP2PTunnel extends PartBasicSt public void setFrequency( final short freq ) { + final short oldf = this.freq; this.freq = freq; + if( oldf != this.freq ) + { + this.getHost().markForUpdate(); + } } public boolean isOutput() @@ -393,4 +417,17 @@ public abstract class PartP2PTunnel extends PartBasicSt { this.output = output; } + + @Override + public Long getRenderFlag() + { + long ret = Short.toUnsignedLong( this.getFrequency() ); + + if( this.isActive() && this.isPowered() ) + { + ret |= 0x10000L; + } + + return ret; + } } diff --git a/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_base.json b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_base.json index cbae9e42b..ded4e49a1 100644 --- a/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_base.json +++ b/src/main/resources/assets/appliedenergistics2/models/part/p2p/p2p_tunnel_base.json @@ -3,32 +3,628 @@ "front": "appliedenergistics2:items/part/p2p_tunnel_front", "sides": "appliedenergistics2:parts/p2p_tunnel_sides", "back": "appliedenergistics2:items/part/p2p_tunnel_back", - "back2": "appliedenergistics2:items/part/p2p_tunnel_back2", - "particle": "appliedenergistics2:items/part/p2p_tunnel_back" + "particle": "appliedenergistics2:items/part/p2p_tunnel_back", + "back2": "appliedenergistics2:items/part/p2p_tunnel_back2" }, "elements": [ { "from": [ - 2, - 2, + 4, + 4, 0 ], "to": [ - 14, - 14, + 12, + 12, 2 ], "faces": { "north": { + "uv": [ + 4, + 4, + 12, + 12 + ], "texture": "#type" } } }, + { + "from": [ + 6, + 5, + 3 + ], + "to": [ + 10, + 11, + 4 + ], + "faces": { + "east": { + "uv": [ + 12, + 5, + 13, + 11 + ], + "texture": "#back2" + }, + "south": { + "uv": [ + 6, + 5, + 10, + 11 + ], + "texture": "#back2" + }, + "west": { + "uv": [ + 3, + 5, + 4, + 11 + ], + "texture": "#back2" + }, + "up": { + "uv": [ + 6, + 3, + 10, + 4 + ], + "texture": "#back2" + }, + "down": { + "uv": [ + 6, + 12, + 10, + 13 + ], + "texture": "#back2" + } + } + }, + { + "from": [ + 5, + 6, + 3 + ], + "to": [ + 6, + 10, + 4 + ], + "faces": { + "east": { + "uv": [ + 12, + 6, + 13, + 10 + ], + "texture": "#back2" + }, + "south": { + "uv": [ + 5, + 6, + 6, + 10 + ], + "texture": "#back2" + }, + "west": { + "uv": [ + 3, + 6, + 4, + 10 + ], + "texture": "#back2" + }, + "up": { + "uv": [ + 5, + 3, + 6, + 4 + ], + "texture": "#back2" + }, + "down": { + "uv": [ + 5, + 12, + 6, + 13 + ], + "texture": "#back2" + } + } + }, + { + "from": [ + 10, + 6, + 3 + ], + "to": [ + 11, + 10, + 4 + ], + "faces": { + "east": { + "uv": [ + 12, + 6, + 13, + 10 + ], + "texture": "#back2" + }, + "south": { + "uv": [ + 10, + 6, + 11, + 10 + ], + "texture": "#back2" + }, + "west": { + "uv": [ + 3, + 6, + 4, + 10 + ], + "texture": "#back2" + }, + "up": { + "uv": [ + 10, + 3, + 11, + 4 + ], + "texture": "#back2" + }, + "down": { + "uv": [ + 10, + 12, + 11, + 13 + ], + "texture": "#back2" + } + } + }, + { + "from": [ + 6, + 4, + 2 + ], + "to": [ + 10, + 6, + 3 + ], + "faces": { + "east": { + "uv": [ + 13, + 10, + 14, + 12 + ], + "texture": "#sides" + }, + "south": { + "uv": [ + 6, + 10, + 10, + 12 + ], + "texture": "#back" + }, + "west": { + "uv": [ + 2, + 10, + 3, + 12 + ], + "texture": "#sides" + }, + "up": { + "uv": [ + 6, + 2, + 10, + 3 + ], + "texture": "#sides" + }, + "down": { + "uv": [ + 6, + 13, + 10, + 14 + ], + "texture": "#sides" + } + } + }, + { + "from": [ + 4, + 6, + 2 + ], + "to": [ + 12, + 10, + 3 + ], + "faces": { + "east": { + "uv": [ + 13, + 6, + 14, + 10 + ], + "texture": "#sides" + }, + "south": { + "uv": [ + 4, + 6, + 12, + 10 + ], + "texture": "#back" + }, + "west": { + "uv": [ + 2, + 6, + 3, + 10 + ], + "texture": "#sides" + }, + "up": { + "uv": [ + 4, + 2, + 12, + 3 + ], + "texture": "#sides" + }, + "down": { + "uv": [ + 4, + 13, + 12, + 14 + ], + "texture": "#sides" + } + } + }, + { + "from": [ + 6, + 10, + 2 + ], + "to": [ + 10, + 12, + 3 + ], + "faces": { + "east": { + "uv": [ + 13, + 4, + 14, + 6 + ], + "texture": "#sides" + }, + "south": { + "uv": [ + 6, + 4, + 10, + 6 + ], + "texture": "#back" + }, + "west": { + "uv": [ + 2, + 4, + 3, + 6 + ], + "texture": "#sides" + }, + "up": { + "uv": [ + 6, + 2, + 10, + 3 + ], + "texture": "#sides" + }, + "down": { + "uv": [ + 6, + 13, + 10, + 14 + ], + "texture": "#sides" + } + } + }, + { + "from": [ + 3, + 12, + 2 + ], + "to": [ + 13, + 13, + 3 + ], + "faces": { + "east": { + "uv": [ + 13, + 3, + 14, + 4 + ], + "texture": "#sides" + }, + "south": { + "uv": [ + 3, + 3, + 13, + 4 + ], + "texture": "#back" + }, + "west": { + "uv": [ + 2, + 3, + 3, + 4 + ], + "texture": "#sides" + }, + "up": { + "uv": [ + 3, + 2, + 13, + 3 + ], + "texture": "#sides" + }, + "down": { + "uv": [ + 3, + 13, + 13, + 14 + ], + "texture": "#sides" + } + } + }, + { + "from": [ + 12, + 4, + 2 + ], + "to": [ + 13, + 12, + 3 + ], + "faces": { + "east": { + "uv": [ + 13, + 4, + 14, + 12 + ], + "texture": "#sides" + }, + "south": { + "uv": [ + 12, + 4, + 13, + 12 + ], + "texture": "#back" + }, + "west": { + "uv": [ + 2, + 4, + 3, + 12 + ], + "texture": "#sides" + }, + "up": { + "uv": [ + 12, + 2, + 13, + 3 + ], + "texture": "#sides" + }, + "down": { + "uv": [ + 12, + 13, + 13, + 14 + ], + "texture": "#sides" + } + } + }, + { + "from": [ + 3, + 4, + 2 + ], + "to": [ + 4, + 12, + 3 + ], + "faces": { + "east": { + "uv": [ + 13, + 4, + 14, + 12 + ], + "texture": "#sides" + }, + "south": { + "uv": [ + 3, + 4, + 4, + 12 + ], + "texture": "#back" + }, + "west": { + "uv": [ + 2, + 4, + 3, + 12 + ], + "texture": "#sides" + }, + "up": { + "uv": [ + 3, + 2, + 4, + 3 + ], + "texture": "#sides" + }, + "down": { + "uv": [ + 3, + 13, + 4, + 14 + ], + "texture": "#sides" + } + } + }, + { + "from": [ + 3, + 3, + 2 + ], + "to": [ + 13, + 4, + 3 + ], + "faces": { + "east": { + "uv": [ + 13, + 12, + 14, + 13 + ], + "texture": "#sides" + }, + "south": { + "uv": [ + 3, + 12, + 13, + 13 + ], + "texture": "#back" + }, + "west": { + "uv": [ + 2, + 12, + 3, + 13 + ], + "texture": "#sides" + }, + "up": { + "uv": [ + 3, + 2, + 13, + 3 + ], + "texture": "#sides" + }, + "down": { + "uv": [ + 3, + 13, + 13, + 14 + ], + "texture": "#sides" + } + } + }, { "from": [ 2, 2, - 0 + 1 ], "to": [ 14, @@ -37,111 +633,332 @@ ], "faces": { "north": { + "uv": [ + 2, + 2, + 14, + 14 + ], "texture": "#front" }, + "east": { + "uv": [ + 14, + 2, + 15, + 14 + ], + "texture": "#sides" + }, "south": { + "uv": [ + 2, + 2, + 14, + 14 + ], "texture": "#back" }, "west": { - "texture": "#sides" - }, - "east": { + "uv": [ + 1, + 2, + 2, + 14 + ], "texture": "#sides" }, "up": { + "uv": [ + 2, + 1, + 14, + 2 + ], "texture": "#sides" }, "down": { + "uv": [ + 2, + 14, + 14, + 15 + ], "texture": "#sides" } } }, { "from": [ - 3, - 3, - 2 + 2, + 12, + 0 ], "to": [ - 13, - 13, - 3 + 14, + 14, + 1 ], "faces": { + "north": { + "uv": [ + 2, + 2, + 14, + 4 + ], + "texture": "#front" + }, + "east": { + "uv": [ + 15, + 2, + 16, + 4 + ], + "texture": "#sides" + }, "south": { + "uv": [ + 2, + 2, + 14, + 4 + ], "texture": "#back" }, "west": { - "texture": "#sides" - }, - "east": { + "uv": [ + 0, + 2, + 1, + 4 + ], "texture": "#sides" }, "up": { + "uv": [ + 2, + 0, + 14, + 1 + ], "texture": "#sides" }, "down": { + "uv": [ + 2, + 15, + 14, + 16 + ], "texture": "#sides" } } }, { "from": [ - 6, - 5, - 3 + 2, + 2, + 0 ], "to": [ - 10, - 11, - 4 + 14, + 4, + 1 ], "faces": { - "south": { - "texture": "#back2" - }, - "west": { - "texture": "#back2" + "north": { + "uv": [ + 2, + 12, + 14, + 14 + ], + "texture": "#front" }, "east": { - "texture": "#back2" + "uv": [ + 15, + 12, + 16, + 14 + ], + "texture": "#sides" + }, + "south": { + "uv": [ + 2, + 12, + 14, + 14 + ], + "texture": "#back" + }, + "west": { + "uv": [ + 0, + 12, + 1, + 14 + ], + "texture": "#sides" }, "up": { - "texture": "#back2" + "uv": [ + 2, + 0, + 14, + 1 + ], + "texture": "#sides" }, "down": { - "texture": "#back2" + "uv": [ + 2, + 15, + 14, + 16 + ], + "texture": "#sides" } } }, { "from": [ - 5, - 6, - 3 + 12, + 4, + 0 ], "to": [ - 11, - 10, - 4 + 14, + 12, + 1 ], "faces": { - "south": { - "texture": "#back2" - }, - "west": { - "texture": "#back2" + "north": { + "uv": [ + 2, + 4, + 4, + 12 + ], + "texture": "#front" }, "east": { - "texture": "#back2" + "uv": [ + 15, + 4, + 16, + 12 + ], + "texture": "#sides" + }, + "south": { + "uv": [ + 12, + 4, + 14, + 12 + ], + "texture": "#back" + }, + "west": { + "uv": [ + 0, + 4, + 1, + 12 + ], + "texture": "#sides" }, "up": { - "texture": "#back2" + "uv": [ + 12, + 0, + 14, + 1 + ], + "texture": "#sides" }, "down": { - "texture": "#back2" + "uv": [ + 12, + 15, + 14, + 16 + ], + "texture": "#sides" + } + } + }, + { + "from": [ + 2, + 4, + 0 + ], + "to": [ + 4, + 12, + 1 + ], + "faces": { + "north": { + "uv": [ + 12, + 4, + 14, + 12 + ], + "texture": "#front" + }, + "east": { + "uv": [ + 15, + 4, + 16, + 12 + ], + "texture": "#sides" + }, + "south": { + "uv": [ + 2, + 4, + 4, + 12 + ], + "texture": "#back" + }, + "west": { + "uv": [ + 0, + 4, + 1, + 12 + ], + "texture": "#sides" + }, + "up": { + "uv": [ + 2, + 0, + 4, + 1 + ], + "texture": "#sides" + }, + "down": { + "uv": [ + 2, + 15, + 4, + 16 + ], + "texture": "#sides" } } } ] -} +} \ No newline at end of file diff --git a/src/main/resources/assets/appliedenergistics2/textures/parts/p2p_tunnel_frequency.png b/src/main/resources/assets/appliedenergistics2/textures/parts/p2p_tunnel_frequency.png new file mode 100644 index 0000000000000000000000000000000000000000..59ad3036f5ad50a2f8dc331a18a79f02a3cfefc9 GIT binary patch literal 2799 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 literal 0 HcmV?d00001