/**
* This class was created by <Vazkii>. It's distributed as
* part of the Botania Mod. Get the Source Code in github:
* https://github.com/Vazkii/Botania
*
* Botania is Open Source and distributed under the
* Botania License: http://botaniamod.net/license.php
*
* File Created @ [Jan 31, 2014, 3:02:58 PM (GMT)]
*/
package vazkii.botania.common.item.lens;
import java.awt.Color;
import java.util.List;
import javax.annotation.Nonnull;
import net.minecraft.client.resources.I18n;
import net.minecraft.creativetab.CreativeTabs;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.projectile.EntityThrowable;
import net.minecraft.item.EnumDyeColor;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.NonNullList;
import net.minecraft.util.math.RayTraceResult;
import net.minecraftforge.fml.common.registry.GameRegistry;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.minecraftforge.oredict.RecipeSorter;
import net.minecraftforge.oredict.RecipeSorter.Category;
import vazkii.botania.api.internal.IManaBurst;
import vazkii.botania.api.mana.BurstProperties;
import vazkii.botania.api.mana.ICompositableLens;
import vazkii.botania.api.mana.ILens;
import vazkii.botania.api.mana.ILensControl;
import vazkii.botania.api.mana.IManaReceiver;
import vazkii.botania.api.mana.IManaSpreader;
import vazkii.botania.api.mana.ITinyPlanetExcempt;
import vazkii.botania.client.core.handler.ModelHandler;
import vazkii.botania.common.Botania;
import vazkii.botania.common.core.helper.ItemNBTHelper;
import vazkii.botania.common.crafting.recipe.CompositeLensRecipe;
import vazkii.botania.common.crafting.recipe.LensDyeingRecipe;
import vazkii.botania.common.item.ItemMod;
import vazkii.botania.common.lib.LibItemNames;
public class ItemLens extends ItemMod implements ILensControl, ICompositableLens, ITinyPlanetExcempt {
public static final int SUBTYPES = 24;
public static final int NORMAL = 0,
SPEED = 1,
POWER = 2,
TIME = 3,
EFFICIENCY = 4,
BOUNCE = 5,
GRAVITY = 6,
MINE = 7,
DAMAGE = 8,
PHANTOM = 9,
MAGNET = 10,
EXPLOSIVE = 11,
INFLUENCE = 12,
WEIGHT = 13,
PAINT = 14,
FIRE = 15,
PISTON = 16,
LIGHT = 17,
WARP = 18,
REDIRECT = 19,
FIREWORK = 20,
FLARE = 21,
MESSENGER = 22,
TRIPWIRE = 23;
public static final int STORM = 5000;
private static final int PROP_NONE = 0,
PROP_POWER = 1,
PROP_ORIENTATION = 1 << 1,
PROP_TOUCH = 1 << 2,
PROP_INTERACTION = 1 << 3,
PROP_DAMAGE = 1 << 4,
PROP_CONTROL = 1 << 5;
private static final int[] props = new int[SUBTYPES];
private static final Lens[] lenses = new Lens[SUBTYPES];
private static final Lens fallbackLens = new Lens();
private static final Lens stormLens = new LensStorm();
static {
setProps(NORMAL, PROP_NONE);
setProps(SPEED, PROP_NONE);
setProps(POWER, PROP_POWER);
setProps(TIME, PROP_NONE);
setProps(EFFICIENCY, PROP_NONE);
setProps(BOUNCE, PROP_TOUCH);
setProps(GRAVITY, PROP_ORIENTATION);
setProps(MINE, PROP_TOUCH | PROP_INTERACTION);
setProps(DAMAGE, PROP_DAMAGE);
setProps(PHANTOM, PROP_TOUCH);
setProps(MAGNET, PROP_ORIENTATION);
setProps(EXPLOSIVE, PROP_DAMAGE | PROP_TOUCH | PROP_INTERACTION);
setProps(INFLUENCE, PROP_NONE);
setProps(WEIGHT, PROP_TOUCH | PROP_INTERACTION);
setProps(PAINT, PROP_TOUCH | PROP_INTERACTION);
setProps(FIRE, PROP_DAMAGE | PROP_TOUCH | PROP_INTERACTION);
setProps(PISTON, PROP_TOUCH | PROP_INTERACTION);
setProps(LIGHT, PROP_TOUCH | PROP_INTERACTION);
setProps(WARP, PROP_NONE);
setProps(REDIRECT, PROP_TOUCH | PROP_INTERACTION);
setProps(FIREWORK, PROP_TOUCH);
setProps(FLARE, PROP_CONTROL);
setProps(MESSENGER, PROP_POWER);
setProps(TRIPWIRE, PROP_CONTROL);
setLens(NORMAL, fallbackLens);
setLens(SPEED, new LensSpeed());
setLens(POWER, new LensPower());
setLens(TIME, new LensTime());
setLens(EFFICIENCY, new LensEfficiency());
setLens(BOUNCE, new LensBounce());
setLens(GRAVITY, new LensGravity());
setLens(MINE, new LensMine());
setLens(DAMAGE, new LensDamage());
setLens(PHANTOM, new LensPhantom());
setLens(MAGNET, new LensMagnet());
setLens(EXPLOSIVE, new LensExplosive());
setLens(INFLUENCE, new LensInfluence());
setLens(WEIGHT, new LensWeight());
setLens(PAINT, new LensPaint());
setLens(FIRE, new LensFire());
setLens(PISTON, new LensPiston());
setLens(LIGHT, new LensLight());
setLens(WARP, new LensWarp());
setLens(REDIRECT, new LensRedirect());
setLens(FIREWORK, new LensFirework());
setLens(FLARE, new LensFlare());
setLens(MESSENGER, new LensMessenger());
setLens(TRIPWIRE, new LensTripwire());
}
private static final String TAG_COLOR = "color";
private static final String TAG_COMPOSITE_LENS = "compositeLens";
public ItemLens() {
super(LibItemNames.LENS);
setMaxStackSize(1);
setHasSubtypes(true);
GameRegistry.addRecipe(new CompositeLensRecipe());
GameRegistry.addRecipe(new LensDyeingRecipe());
RecipeSorter.register("botania:compositeLens", CompositeLensRecipe.class, Category.SHAPELESS, "");
RecipeSorter.register("botania:lensDying", LensDyeingRecipe.class, Category.SHAPELESS, "");
}
@Override
@SideOnly(Side.CLIENT)
public void getSubItems(@Nonnull Item item, CreativeTabs tab, NonNullList<ItemStack> stacks) {
for(int i = 0; i < SUBTYPES; i++)
stacks.add(new ItemStack(item, 1, i));
}
@Nonnull
@Override
public String getUnlocalizedName(ItemStack par1ItemStack) {
return "item." + LibItemNames.LENS_NAMES[Math.min(SUBTYPES - 1, par1ItemStack.getItemDamage())];
}
@SideOnly(Side.CLIENT)
@Override
public void addInformation(ItemStack par1ItemStack, EntityPlayer player, List<String> stacks, boolean par4) {
int storedColor = getStoredColor(par1ItemStack);
if(storedColor != -1)
stacks.add(I18n.format("botaniamisc.color", I18n.format("botania.color" + storedColor)));
}
private String getItemShortTermName(ItemStack stack) {
return net.minecraft.util.text.translation.I18n.translateToLocal(stack.getUnlocalizedName().replaceAll("item.", "item.botania:") + ".short");
}
@Nonnull
@Override
public String getItemStackDisplayName(@Nonnull ItemStack stack) {
ItemStack compositeLens = getCompositeLens(stack);
if(compositeLens.isEmpty())
return super.getItemStackDisplayName(stack);
return String.format(net.minecraft.util.text.translation.I18n.translateToLocal("item.botania:compositeLens.name"), getItemShortTermName(stack), getItemShortTermName(compositeLens));
}
@Override
public void apply(ItemStack stack, BurstProperties props) {
int storedColor = getStoredColor(stack);
if(storedColor != -1)
props.color = getLensColor(stack);
getLens(stack.getItemDamage()).apply(stack, props);
ItemStack compositeLens = getCompositeLens(stack);
if(!compositeLens.isEmpty() && compositeLens.getItem() instanceof ILens)
((ILens) compositeLens.getItem()).apply(compositeLens, props);
}
@Override
public boolean collideBurst(IManaBurst burst, RayTraceResult pos, boolean isManaBlock, boolean dead, ItemStack stack) {
EntityThrowable entity = (EntityThrowable) burst;
dead = getLens(stack.getItemDamage()).collideBurst(burst, entity, pos, isManaBlock, dead, stack);
ItemStack compositeLens = getCompositeLens(stack);
if(!compositeLens.isEmpty() && compositeLens.getItem() instanceof ILens)
dead = ((ILens) compositeLens.getItem()).collideBurst(burst, pos, isManaBlock, dead, compositeLens);
return dead;
}
@Override
public void updateBurst(IManaBurst burst, ItemStack stack) {
EntityThrowable entity = (EntityThrowable) burst;
int storedColor = getStoredColor(stack);
if(storedColor == 16 && entity.world.isRemote)
burst.setColor(getLensColor(stack));
getLens(stack.getItemDamage()).updateBurst(burst, entity, stack);
ItemStack compositeLens = getCompositeLens(stack);
if(!compositeLens.isEmpty() && compositeLens.getItem() instanceof ILens)
((ILens) compositeLens.getItem()).updateBurst(burst, compositeLens);
}
@Override
public int getLensColor(ItemStack stack) {
int storedColor = getStoredColor(stack);
if(storedColor == -1)
return 0xFFFFFF;
if(storedColor == 16)
return Color.HSBtoRGB(Botania.proxy.getWorldElapsedTicks() * 2 % 360 / 360F, 1F, 1F);
return EnumDyeColor.byMetadata(storedColor).getMapColor().colorValue;
}
public static int getStoredColor(ItemStack stack) {
return ItemNBTHelper.getInt(stack, TAG_COLOR, -1);
}
public static void setLensColor(ItemStack stack, int color) {
ItemNBTHelper.setInt(stack, TAG_COLOR, color);
}
@Override
public boolean doParticles(IManaBurst burst, ItemStack stack) {
return true;
}
public static void setProps(int lens, int props_) {
props[lens] = props_;
}
public static void setLens(int index, Lens lens) {
lenses[index] = lens;
}
public static boolean isBlacklisted(ItemStack lens1, ItemStack lens2) {
ICompositableLens item1 = (ICompositableLens) lens1.getItem();
ICompositableLens item2 = (ICompositableLens) lens2.getItem();
return (item1.getProps(lens1) & item2.getProps(lens2)) != 0;
}
public static Lens getLens(int index) {
if(index == STORM)
return stormLens;
Lens lens = lenses[index];
return lens == null ? fallbackLens : lens;
}
@Override
public boolean canCombineLenses(ItemStack sourceLens, ItemStack compositeLens) {
ICompositableLens sourceItem = (ICompositableLens) sourceLens.getItem();
ICompositableLens compositeItem = (ICompositableLens) compositeLens.getItem();
if(sourceItem == compositeItem && sourceLens.getItemDamage() == compositeLens.getItemDamage())
return false;
if(!sourceItem.isCombinable(sourceLens) || !compositeItem.isCombinable(compositeLens))
return false;
if(isBlacklisted(sourceLens, compositeLens))
return false;
return true;
}
@Override
public ItemStack getCompositeLens(ItemStack stack) {
NBTTagCompound cmp = ItemNBTHelper.getCompound(stack, TAG_COMPOSITE_LENS, true);
if(cmp == null)
return ItemStack.EMPTY;
else return new ItemStack(cmp);
}
@Override
public ItemStack setCompositeLens(ItemStack sourceLens, ItemStack compositeLens) {
if(!compositeLens.isEmpty()) {
NBTTagCompound cmp = compositeLens.writeToNBT(new NBTTagCompound());
ItemNBTHelper.setCompound(sourceLens, TAG_COMPOSITE_LENS, cmp);
}
return sourceLens;
}
@Override
public int getManaToTransfer(IManaBurst burst, EntityThrowable entity, ItemStack stack, IManaReceiver receiver) {
if(stack.getItemDamage() >= lenses.length)
return 0;
return lenses[stack.getItemDamage()].getManaToTransfer(burst, entity, stack, receiver);
}
@Override
public boolean shouldPull(ItemStack stack) {
return stack.getItemDamage() != STORM;
}
@Override
public boolean isControlLens(ItemStack stack) {
return (getProps(stack) & PROP_CONTROL) != 0;
}
@Override
public boolean allowBurstShooting(ItemStack stack, IManaSpreader spreader, boolean redstone) {
return lenses[stack.getItemDamage()].allowBurstShooting(stack, spreader, redstone);
}
@Override
public void onControlledSpreaderTick(ItemStack stack, IManaSpreader spreader, boolean redstone) {
lenses[stack.getItemDamage()].onControlledSpreaderTick(stack, spreader, redstone);
}
@Override
public void onControlledSpreaderPulse(ItemStack stack, IManaSpreader spreader, boolean redstone) {
lenses[stack.getItemDamage()].onControlledSpreaderPulse(stack, spreader, redstone);
}
@Override
public int getProps(ItemStack stack) {
return props[stack.getItemDamage()];
}
@Override
public boolean isCombinable(ItemStack stack) {
return stack.getItemDamage() != NORMAL;
}
@SideOnly(Side.CLIENT)
@Override
public void registerModels() {
ModelHandler.registerItemMetas(this, LibItemNames.LENS_NAMES.length, i -> LibItemNames.LENS_NAMES[i]);
}
}