package mhfc.net.common.util;
import java.util.List;
import java.util.Objects;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import mhfc.net.common.item.ItemColor;
import mhfc.net.common.util.SubTypedItem.SubTypeEnum;
import net.minecraft.block.Block;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
import net.minecraft.util.MathHelper;
/**
* A util interface to describes blocks and items that store part of their actual "value" in the meta-information of
* each Block/ItemStack.
*
*
* @author WorldSEnder
*
* @param <I>
* The underlying item type
* @param <T>
* The enum-type used to enumerate all subtypes
*/
public class SubTypedItem<I, T extends Enum<T> & SubTypeEnum<I>> {
public static interface SubTypeEnum<I> {
/**
* The name of this sub item.
*
* @return
*/
public String getName();
/**
* The texture to be used for this subitem.
*
* @return
*/
public String getTexPath();
/**
* Gets the base item of this sub-item
*
* @return
*/
public I getBaseItem();
/**
* Gets the meta data associated with this subitem.
*
* @return
*/
public int ordinal();
public default ItemColor getColor() {
return ItemColor.WHITE;
}
}
/**
* A quick and dirty way to reuse the same texture path for multiple textures. Used for trees as they have different
* paths for the top and sides of leave blocks.
*
* @author WorldSEnder
*
*/
public static interface TexturePathModificator {
public String modify(String texPath);
}
private static TexturePathModificator PASSTHROUGH = texPath -> texPath;
public static ItemStack fromSubBlock(SubTypeEnum<Block> subBlock, int size) {
return new ItemStack(subBlock.getBaseItem(), size, subBlock.ordinal());
}
public static ItemStack fromSubItem(SubTypeEnum<Item> subItem, int size) {
return new ItemStack(subItem.getBaseItem(), size, subItem.ordinal());
}
private final Class<T> clazzToken;
private final T[] values;
@SideOnly(Side.CLIENT)
private IIcon[] textures;
private TexturePathModificator modifier;
public SubTypedItem(Class<T> enumClazz) {
this(enumClazz, null);
}
public SubTypedItem(Class<T> enumClazz, TexturePathModificator modifier) {
this.clazzToken = Objects.requireNonNull(enumClazz);
// Cache the value, getEnumConstants() doesn't and can not safely
this.values = clazzToken.getEnumConstants();
this.modifier = modifier == null ? SubTypedItem.PASSTHROUGH : modifier;
}
@SideOnly(Side.CLIENT)
public IIcon[] getIcons() {
return textures;
}
@SideOnly(Side.CLIENT)
public void registerIcons(IIconRegister regIcon) {
textures = new IIcon[values.length];
for (int i = 0; i < values.length; i++) {
textures[i] = regIcon.registerIcon(modifier.modify(values[i].getTexPath()));
}
}
@SideOnly(Side.CLIENT)
public void getSubItems(Item block, List<ItemStack> list) {
for (int i = 0; i < values.length;) {
T value = values[i++];
list.add(new ItemStack(block, 1, value.ordinal()));
}
}
public T getSubType(ItemStack stack) {
int clumpedMeta = MathHelper.clamp_int(stack.getItemDamage(), 0, values.length);
return values[clumpedMeta];
}
}