Added a color code to the memory card. (#3609)

Can be used to encode the stored content as a 4x2 grid of AEColors
Currently used to indicate the P2P frequency.
This commit is contained in:
yueh
2018-07-14 19:42:56 +02:00
committed by GitHub
parent 2891014cf6
commit fe4db2eb98
17 changed files with 462 additions and 77 deletions
@@ -28,7 +28,6 @@ import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.common.model.TRSRTransformation;
import appeng.api.implementations.items.IBiometricCard;
@@ -216,9 +215,9 @@ class BiometricCardBakedModel implements IBakedModel
public Pair<? extends IBakedModel, Matrix4f> handlePerspective( ItemCameraTransforms.TransformType type )
{
// Delegate to the base model if possible
if( this.baseModel instanceof IModel )
if( this.baseModel instanceof IBakedModel )
{
IBakedModel pam = (IBakedModel) this.baseModel;
IBakedModel pam = this.baseModel;
Pair<? extends IBakedModel, Matrix4f> pair = pam.handlePerspective( type );
return Pair.of( this, pair.getValue() );
}
@@ -0,0 +1,228 @@
package appeng.client.render.model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.annotation.Nullable;
import javax.vecmath.Matrix4f;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.common.collect.ImmutableList;
import org.apache.commons.lang3.tuple.Pair;
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.client.renderer.vertex.VertexFormat;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumFacing;
import net.minecraft.world.World;
import net.minecraftforge.common.model.TRSRTransformation;
import appeng.api.implementations.items.IMemoryCard;
import appeng.api.util.AEColor;
import appeng.client.render.cablebus.CubeBuilder;
import appeng.core.AELog;
class MemoryCardBakedModel implements IBakedModel
{
private static final AEColor[] DEFAULT_COLOR_CODE = new AEColor[] {
AEColor.TRANSPARENT, AEColor.TRANSPARENT, AEColor.TRANSPARENT, AEColor.TRANSPARENT,
AEColor.TRANSPARENT, AEColor.TRANSPARENT, AEColor.TRANSPARENT, AEColor.TRANSPARENT,
};
private final VertexFormat format;
private final IBakedModel baseModel;
private final TextureAtlasSprite texture;
private final AEColor[] colorCode;
private final Cache<CacheKey, MemoryCardBakedModel> modelCache;
private final ImmutableList<BakedQuad> generalQuads;
MemoryCardBakedModel( VertexFormat format, IBakedModel baseModel, TextureAtlasSprite texture )
{
this( format, baseModel, texture, DEFAULT_COLOR_CODE, createCache() );
}
private MemoryCardBakedModel( VertexFormat format, IBakedModel baseModel, TextureAtlasSprite texture, AEColor[] hash, Cache<CacheKey, MemoryCardBakedModel> modelCache )
{
this.format = format;
this.baseModel = baseModel;
this.texture = texture;
this.colorCode = hash;
this.generalQuads = ImmutableList.copyOf( this.buildGeneralQuads() );
this.modelCache = modelCache;
}
private static Cache<CacheKey, MemoryCardBakedModel> createCache()
{
return CacheBuilder.newBuilder()
.maximumSize( 100 )
.build();
}
@Override
public List<BakedQuad> getQuads( @Nullable IBlockState state, @Nullable EnumFacing side, long rand )
{
List<BakedQuad> quads = this.baseModel.getQuads( state, side, rand );
if( side != null )
{
return quads;
}
List<BakedQuad> result = new ArrayList<>( quads.size() + this.generalQuads.size() );
result.addAll( quads );
result.addAll( this.generalQuads );
return result;
}
private List<BakedQuad> buildGeneralQuads()
{
CubeBuilder builder = new CubeBuilder( this.format );
builder.setTexture( this.texture );
for( int x = 0; x < 4; x++ )
{
for( int y = 0; y < 2; y++ )
{
final AEColor color = this.colorCode[x + y * 4];
builder.setColorRGB( color.mediumVariant );
builder.addCube( 7 + x, 8 + ( 1 - y ), 7.5f, 7 + x + 1, 8 + ( 1 - y ) + 1, 8.5f );
}
}
return builder.getOutput();
}
@Override
public boolean isAmbientOcclusion()
{
return this.baseModel.isAmbientOcclusion();
}
@Override
public boolean isGui3d()
{
return this.baseModel.isGui3d();
}
@Override
public boolean isBuiltInRenderer()
{
return this.baseModel.isBuiltInRenderer();
}
@Override
public TextureAtlasSprite getParticleTexture()
{
return this.baseModel.getParticleTexture();
}
@Override
public ItemCameraTransforms getItemCameraTransforms()
{
return this.baseModel.getItemCameraTransforms();
}
@Override
public ItemOverrideList getOverrides()
{
return new ItemOverrideList( Collections.emptyList() )
{
@Override
public IBakedModel handleItemState( IBakedModel originalModel, ItemStack stack, World world, EntityLivingBase entity )
{
try
{
if( stack.getItem() instanceof IMemoryCard )
{
final IMemoryCard memoryCard = (IMemoryCard) stack.getItem();
final AEColor[] colors = memoryCard.getColorCode( stack );
return MemoryCardBakedModel.this.modelCache.get( new CacheKey( colors ),
() -> new MemoryCardBakedModel( MemoryCardBakedModel.this.format, MemoryCardBakedModel.this.baseModel, MemoryCardBakedModel.this.texture, colors, MemoryCardBakedModel.this.modelCache ) );
}
}
catch( ExecutionException e )
{
AELog.error( e );
}
return MemoryCardBakedModel.this;
}
};
}
@Override
public Pair<? extends IBakedModel, Matrix4f> handlePerspective( ItemCameraTransforms.TransformType type )
{
// Delegate to the base model if possible
if( this.baseModel instanceof IBakedModel )
{
IBakedModel pam = this.baseModel;
Pair<? extends IBakedModel, Matrix4f> pair = pam.handlePerspective( type );
return Pair.of( this, pair.getValue() );
}
return Pair.of( this, TRSRTransformation.identity().getMatrix() );
}
private static class CacheKey
{
private final AEColor[] key;
CacheKey( AEColor[] key )
{
this.key = key;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + Arrays.hashCode( this.key );
return result;
}
@Override
public boolean equals( Object obj )
{
if( this == obj )
{
return true;
}
if( obj == null )
{
return false;
}
if( this.getClass() != obj.getClass() )
{
return false;
}
CacheKey other = (CacheKey) obj;
return Arrays.equals( this.key, other.key );
}
}
}
@@ -0,0 +1,70 @@
package appeng.client.render.model;
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.client.model.ModelLoaderRegistry;
import net.minecraftforge.common.model.IModelState;
import net.minecraftforge.common.model.TRSRTransformation;
import appeng.core.AppEng;
/**
* Model wrapper for the memory card item model, which combines a base card layer with a "visual hash" of the part/tile.
*/
public class MemoryCardModel implements IModel
{
private static final ResourceLocation MODEL_BASE = new ResourceLocation( AppEng.MOD_ID, "item/memory_card" );
private static final ResourceLocation TEXTURE = new ResourceLocation( AppEng.MOD_ID, "items/memory_card_hash" );
@Override
public Collection<ResourceLocation> getDependencies()
{
return Collections.singletonList( MODEL_BASE );
}
@Override
public Collection<ResourceLocation> getTextures()
{
return Collections.singletonList( TEXTURE );
}
@Override
public IBakedModel bake( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
{
TextureAtlasSprite texture = bakedTextureGetter.apply( TEXTURE );
IBakedModel baseModel = this.getBaseModel( state, format, bakedTextureGetter );
return new MemoryCardBakedModel( format, baseModel, texture );
}
private IBakedModel getBaseModel( IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter )
{
// Load the base model
try
{
return ModelLoaderRegistry.getModel( MODEL_BASE ).bake( state, format, bakedTextureGetter );
}
catch( Exception e )
{
throw new RuntimeException( e );
}
}
@Override
public IModelState getDefaultState()
{
return TRSRTransformation.identity().toItemTransform();
}
}
@@ -56,6 +56,7 @@ import appeng.items.storage.ItemViewCell;
import appeng.items.tools.ToolBiometricCard;
import appeng.items.tools.ToolBiometricCardRendering;
import appeng.items.tools.ToolMemoryCard;
import appeng.items.tools.ToolMemoryCardRendering;
import appeng.items.tools.ToolNetworkTool;
import appeng.items.tools.powered.ToolChargedStaff;
import appeng.items.tools.powered.ToolColorApplicator;
@@ -205,7 +206,10 @@ public final class ApiItems implements IItems
.rendering( new ToolBiometricCardRendering() )
.features( AEFeature.SECURITY )
.build();
this.memoryCard = registry.item( "memory_card", ToolMemoryCard::new ).features( AEFeature.MEMORY_CARD ).build();
this.memoryCard = registry.item( "memory_card", ToolMemoryCard::new )
.rendering( new ToolMemoryCardRendering() )
.features( AEFeature.MEMORY_CARD )
.build();
this.networkTool = registry.item( "network_tool", ToolNetworkTool::new ).features( AEFeature.NETWORK_TOOL ).build();
this.cellCreative = registry.item( "creative_storage_cell", ItemCreativeStorageCell::new )
@@ -36,6 +36,7 @@ public enum TheOneProbeText
P2P_INPUT_ONE_OUTPUT,
P2P_INPUT_MANY_OUTPUTS,
P2P_OUTPUT,
P2P_FREQUENCY,
LOCKED,
UNLOCKED,
@@ -33,6 +33,7 @@ import appeng.api.parts.IPart;
import appeng.integration.modules.theoneprobe.TheOneProbeText;
import appeng.me.GridAccessException;
import appeng.parts.p2p.PartP2PTunnel;
import appeng.util.Platform;
public class P2PStateInfoProvider implements IPartProbInfoProvider
@@ -41,7 +42,6 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
private static final int STATE_UNLINKED = 0;
private static final int STATE_OUTPUT = 1;
private static final int STATE_INPUT = 2;
public static final String TAG_P2P_STATE = "p2p_state";
@Override
public void addProbeInfo( IPart part, ProbeMode mode, IProbeInfo probeInfo, EntityPlayer player, World world, IBlockState blockState, IProbeHitData data )
@@ -50,6 +50,11 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
{
final PartP2PTunnel tunnel = (PartP2PTunnel) part;
if( !tunnel.isPowered() )
{
return;
}
// The default state
int state = STATE_UNLINKED;
int outputCount = 0;
@@ -84,6 +89,11 @@ public class P2PStateInfoProvider implements IPartProbInfoProvider
probeInfo.text( getOutputText( outputCount ) );
break;
}
final short freq = tunnel.getFrequency();
final String freqTooltip = Platform.p2p().toHexString( freq );
probeInfo.text( freqTooltip );
}
}
@@ -27,6 +27,7 @@ import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.translation.I18n;
import net.minecraft.world.World;
import mcp.mobius.waila.api.IWailaConfigHandler;
@@ -36,6 +37,7 @@ import appeng.api.parts.IPart;
import appeng.core.localization.WailaText;
import appeng.me.GridAccessException;
import appeng.parts.p2p.PartP2PTunnel;
import appeng.util.Platform;
/**
@@ -48,6 +50,7 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
private static final int STATE_OUTPUT = 1;
private static final int STATE_INPUT = 2;
public static final String TAG_P2P_STATE = "p2p_state";
public static final String TAG_P2P_FREQUENCY = "p2p_frequency";
/**
* Adds state to the tooltip
@@ -86,6 +89,10 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
break;
}
}
final short freq = nbtData.getShort( TAG_P2P_FREQUENCY );
final String freqTooltip = Platform.p2p().toHexString( freq );
currentToolTip.add( I18n.translateToLocalFormatted( "gui.tooltips.appliedenergistics2.P2PFrequency", freqTooltip ) );
}
}
@@ -97,7 +104,16 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
{
if( part instanceof PartP2PTunnel )
{
PartP2PTunnel tunnel = (PartP2PTunnel) part;
final PartP2PTunnel tunnel = (PartP2PTunnel) part;
if( !tunnel.isPowered() )
{
return tag;
}
// Frquency
final short frequency = tunnel.getFrequency();
tag.setShort( TAG_P2P_FREQUENCY, frequency );
// The default state
int state = STATE_UNLINKED;
@@ -125,6 +141,7 @@ public final class P2PStateWailaDataProvider extends BasePartWailaDataProvider
state,
outputCount
} );
}
return tag;
@@ -29,6 +29,7 @@ import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.translation.I18n;
import net.minecraft.world.IBlockAccess;
import net.minecraft.world.World;
@@ -37,6 +38,7 @@ import net.minecraftforge.fml.relauncher.SideOnly;
import appeng.api.implementations.items.IMemoryCard;
import appeng.api.implementations.items.MemoryCardMessages;
import appeng.api.util.AEColor;
import appeng.core.localization.GuiText;
import appeng.core.localization.PlayerMessages;
import appeng.items.AEBaseItem;
@@ -45,6 +47,12 @@ import appeng.util.Platform;
public class ToolMemoryCard extends AEBaseItem implements IMemoryCard
{
private static final AEColor[] DEFAULT_COLOR_CODE = new AEColor[] {
AEColor.TRANSPARENT, AEColor.TRANSPARENT, AEColor.TRANSPARENT, AEColor.TRANSPARENT,
AEColor.TRANSPARENT, AEColor.TRANSPARENT, AEColor.TRANSPARENT, AEColor.TRANSPARENT,
};
public ToolMemoryCard()
{
this.setMaxStackSize( 1 );
@@ -61,6 +69,14 @@ public class ToolMemoryCard extends AEBaseItem implements IMemoryCard
{
lines.add( I18n.translateToLocal( this.getLocalizedName( data.getString( "tooltip" ) + ".name", data.getString( "tooltip" ) ) ) );
}
if( data.hasKey( "freq" ) )
{
final short freq = data.getShort( "freq" );
final String freqTooltip = TextFormatting.BOLD + Platform.p2p().toHexString( freq );
lines.add( I18n.translateToLocalFormatted( "gui.tooltips.appliedenergistics2.P2PFrequency", freqTooltip ) );
}
}
/**
@@ -114,7 +130,26 @@ public class ToolMemoryCard extends AEBaseItem implements IMemoryCard
{
o = new NBTTagCompound();
}
return (NBTTagCompound) o.copy();
return o.copy();
}
@Override
public AEColor[] getColorCode( ItemStack is )
{
final NBTTagCompound tag = this.getData( is );
if( tag.hasKey( "colorCode" ) )
{
final int[] frequency = tag.getIntArray( "colorCode" );
final AEColor[] colorArray = AEColor.values();
return new AEColor[] {
colorArray[frequency[0]], colorArray[frequency[1]], colorArray[frequency[2]], colorArray[frequency[3]],
colorArray[frequency[4]], colorArray[frequency[5]], colorArray[frequency[6]], colorArray[frequency[7]],
};
}
return DEFAULT_COLOR_CODE;
}
@Override
@@ -0,0 +1,28 @@
package appeng.items.tools;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import appeng.bootstrap.IItemRendering;
import appeng.bootstrap.ItemRenderingCustomizer;
import appeng.client.render.model.MemoryCardModel;
import appeng.core.AppEng;
public class ToolMemoryCardRendering extends ItemRenderingCustomizer
{
private static final ResourceLocation MODEL = new ResourceLocation( AppEng.MOD_ID, "builtin/memory_card" );
@Override
@SideOnly( Side.CLIENT )
public void customize( IItemRendering rendering )
{
rendering.builtInModel( "models/item/builtin/memory_card", new MemoryCardModel() );
rendering.model( new ModelResourceLocation( MODEL, "inventory" ) ).variants( MODEL );
}
}
@@ -45,6 +45,7 @@ import appeng.api.parts.IPartCollisionHelper;
import appeng.api.parts.IPartItem;
import appeng.api.parts.PartItemStack;
import appeng.api.util.AECableType;
import appeng.api.util.AEColor;
import appeng.api.util.AEPartLocation;
import appeng.core.AEConfig;
import appeng.me.GridAccessException;
@@ -363,6 +364,14 @@ public abstract class PartP2PTunnel<T extends PartP2PTunnel> extends PartBasicSt
p2pItem.writeToNBT( data );
data.setShort( "freq", this.getFrequency() );
final AEColor[] colors = Platform.p2p().toColors( this.getFrequency() );
final int[] colorCode = new int[] {
colors[0].ordinal(), colors[0].ordinal(), colors[1].ordinal(), colors[1].ordinal(),
colors[2].ordinal(), colors[2].ordinal(), colors[3].ordinal(), colors[3].ordinal(),
};
data.setIntArray( "colorCode", colorCode );
mc.setMemoryCardContents( is, type + ".name", data );
mc.notifyUser( player, MemoryCardMessages.SETTINGS_SAVED );
return true;
@@ -21,8 +21,6 @@ package appeng.util.helpers;
import com.google.common.base.Preconditions;
import net.minecraft.util.text.TextFormatting;
import appeng.api.util.AEColor;
@@ -69,22 +67,4 @@ public class P2PHelper
return String.format( "%04X", frequency );
}
public String toColorHexDigit( AEColor color )
{
return TextFormatting.fromColorIndex( color.ordinal() ) + this.toHexDigit( color );
}
public String toColorHexString( short frequency )
{
final AEColor[] colors = toColors( frequency );
final StringBuilder builder = new StringBuilder();
for( AEColor aeColor : colors )
{
builder.append( this.toColorHexDigit( aeColor ) );
}
return builder.toString();
}
}