/**
* 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 @ [Mar 13, 2014, 4:30:27 PM (GMT)]
*/
package vazkii.botania.common.item;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nonnull;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.block.model.ModelBakery;
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.MobEffects;
import net.minecraft.init.SoundEvents;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.potion.PotionEffect;
import net.minecraft.util.ActionResult;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.world.World;
import net.minecraftforge.client.model.ModelLoader;
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.mana.BurstProperties;
import vazkii.botania.api.mana.ILens;
import vazkii.botania.api.mana.IManaUsingItem;
import vazkii.botania.api.mana.ManaItemHandler;
import vazkii.botania.api.sound.BotaniaSoundEvents;
import vazkii.botania.client.core.handler.ItemsRemainingRenderHandler;
import vazkii.botania.common.achievement.ModAchievements;
import vazkii.botania.common.core.helper.ItemNBTHelper;
import vazkii.botania.common.crafting.recipe.ManaGunClipRecipe;
import vazkii.botania.common.crafting.recipe.ManaGunLensRecipe;
import vazkii.botania.common.crafting.recipe.ManaGunRemoveLensRecipe;
import vazkii.botania.common.entity.EntityManaBurst;
import vazkii.botania.common.lib.LibItemNames;
public class ItemManaGun extends ItemMod implements IManaUsingItem {
private static final String TAG_LENS = "lens";
private static final String TAG_CLIP = "clip";
private static final String TAG_CLIP_POS = "clipPos";
private static final int CLIP_SLOTS = 6;
private static final int COOLDOWN = 30;
public ItemManaGun() {
super(LibItemNames.MANA_GUN);
setMaxDamage(COOLDOWN);
setMaxStackSize(1);
setNoRepair();
GameRegistry.addRecipe(new ManaGunLensRecipe());
GameRegistry.addRecipe(new ManaGunRemoveLensRecipe());
GameRegistry.addRecipe(new ManaGunClipRecipe());
RecipeSorter.register("botania:manaGunLens", ManaGunLensRecipe.class, Category.SHAPELESS, "");
RecipeSorter.register("botania:manaGunRemoveLens", ManaGunRemoveLensRecipe.class, Category.SHAPELESS, "");
RecipeSorter.register("botania:manaGunClip", ManaGunClipRecipe.class, Category.SHAPELESS, "");
}
@Nonnull
@Override
public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, @Nonnull EnumHand hand) {
ItemStack stack = player.getHeldItem(hand);
int effCd = COOLDOWN;
PotionEffect effect = player.getActivePotionEffect(MobEffects.HASTE);
if(effect != null)
effCd -= (effect.getAmplifier() + 1) * 8;
if(player.isSneaking() && hasClip(stack)) {
rotatePos(stack);
world.playSound(null, player.posX, player.posY, player.posZ, SoundEvents.BLOCK_STONE_BUTTON_CLICK_ON, SoundCategory.PLAYERS, 0.6F, (1.0F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F) * 0.7F);
if(world.isRemote)
player.swingArm(hand);
ItemStack lens = getLens(stack);
ItemsRemainingRenderHandler.set(lens, -2);
stack.setItemDamage(effCd);
return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
} else if(stack.getItemDamage() == 0) {
EntityManaBurst burst = getBurst(player, stack, true);
if(burst != null && ManaItemHandler.requestManaExact(stack, player, burst.getMana(), true)) {
if(!world.isRemote) {
world.playSound(null, player.posX, player.posY, player.posZ, BotaniaSoundEvents.manaBlaster, SoundCategory.PLAYERS, 0.6F, 1);
player.addStat(ModAchievements.manaBlasterShoot, 1);
if(isSugoiKawaiiDesuNe(stack))
player.addStat(ModAchievements.desuGun, 1);
world.spawnEntity(burst);
} else {
player.swingArm(hand);
player.motionX -= burst.motionX * 0.1;
player.motionY -= burst.motionY * 0.3;
player.motionZ -= burst.motionZ * 0.1;
}
stack.setItemDamage(effCd);
} else if(!world.isRemote)
world.playSound(null, player.posX, player.posY, player.posZ, SoundEvents.BLOCK_LEVER_CLICK, SoundCategory.PLAYERS, 0.6F, (1.0F + (world.rand.nextFloat() - world.rand.nextFloat()) * 0.2F) * 0.7F);
return ActionResult.newResult(EnumActionResult.SUCCESS, stack);
}
return ActionResult.newResult(EnumActionResult.PASS, stack);
}
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
// ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN ASADA-SAN
private boolean isSugoiKawaiiDesuNe(ItemStack stack) {
return stack.getDisplayName().equalsIgnoreCase("desu gun");
}
@Override
public boolean hasContainerItem(ItemStack stack) {
return !getLens(stack).isEmpty();
}
@Nonnull
@Override
public ItemStack getContainerItem(@Nonnull ItemStack itemStack) {
return getLens(itemStack);
}
public EntityManaBurst getBurst(EntityPlayer player, ItemStack stack, boolean request) {
EntityManaBurst burst = new EntityManaBurst(player);
int maxMana = 120;
int color = 0x20FF20;
int ticksBeforeManaLoss = 60;
float manaLossPerTick = 4F;
float motionModifier = 5F;
float gravity = 0F;
BurstProperties props = new BurstProperties(maxMana, ticksBeforeManaLoss, manaLossPerTick, gravity, motionModifier, color);
ItemStack lens = getLens(stack);
if(!lens.isEmpty())
((ILens) lens.getItem()).apply(lens, props);
burst.setSourceLens(lens);
if(!request || ManaItemHandler.requestManaExact(stack, player, props.maxMana, false)) {
burst.setColor(props.color);
burst.setMana(props.maxMana);
burst.setStartingMana(props.maxMana);
burst.setMinManaLoss(props.ticksBeforeManaLoss);
burst.setManaLossPerTick(props.manaLossPerTick);
burst.setGravity(props.gravity);
burst.setMotion(burst.motionX * props.motionModifier, burst.motionY * props.motionModifier, burst.motionZ * props.motionModifier);
return burst;
}
return null;
}
@SideOnly(Side.CLIENT)
@Override
public void addInformation(ItemStack par1ItemStack, EntityPlayer player, List<String> stacks, boolean par4) {
boolean clip = hasClip(par1ItemStack);
if(clip && !GuiScreen.isShiftKeyDown()) {
addStringToTooltip(I18n.format("botaniamisc.shiftinfo"), stacks);
return;
}
ItemStack lens = getLens(par1ItemStack);
if(!lens.isEmpty()) {
List<String> tooltip = lens.getTooltip(player, false);
if(tooltip.size() > 1)
stacks.addAll(tooltip.subList(1, tooltip.size()));
}
if(clip) {
int pos = getClipPos(par1ItemStack);
addStringToTooltip(I18n.format("botaniamisc.hasClip"), stacks);
for(int i = 0; i < CLIP_SLOTS; i++) {
String name;
TextFormatting formatting = i == pos ? TextFormatting.GREEN : TextFormatting.GRAY;
ItemStack lensAt = getLensAtPos(par1ItemStack, i);
if(lensAt.isEmpty())
name = I18n.format("botaniamisc.clipEmpty");
else name = lensAt.getDisplayName();
addStringToTooltip(formatting + " - " + name, stacks);
}
}
}
private void addStringToTooltip(String s, List<String> tooltip) {
tooltip.add(s.replaceAll("&", "\u00a7"));
}
@Nonnull
@Override
public String getItemStackDisplayName(@Nonnull ItemStack par1ItemStack) {
ItemStack lens = getLens(par1ItemStack);
return super.getItemStackDisplayName(par1ItemStack) + (lens.isEmpty() ? "" : " (" + TextFormatting.GREEN + lens.getDisplayName() + TextFormatting.RESET + ")");
}
public static boolean hasClip(ItemStack stack) {
return ItemNBTHelper.getBoolean(stack, TAG_CLIP, false);
}
public static void setClip(ItemStack stack, boolean clip) {
ItemNBTHelper.setBoolean(stack, TAG_CLIP, clip);
}
public static int getClipPos(ItemStack stack) {
return ItemNBTHelper.getInt(stack, TAG_CLIP_POS, 0);
}
public static void setClipPos(ItemStack stack, int pos) {
ItemNBTHelper.setInt(stack, TAG_CLIP_POS, pos);
}
public static void rotatePos(ItemStack stack) {
int currPos = getClipPos(stack);
boolean acceptEmpty = !getLensAtPos(stack, currPos).isEmpty();
int[] slots = new int[CLIP_SLOTS - 1];
int index = 0;
for(int i = currPos + 1; i < CLIP_SLOTS; i++, index++)
slots[index] = i;
for(int i = 0; i < currPos; i++, index++)
slots[index] = i;
for(int i : slots) {
ItemStack lensAt = getLensAtPos(stack, i);
if(acceptEmpty || !lensAt.isEmpty()) {
setClipPos(stack, i);
return;
}
}
}
public static ItemStack getLensAtPos(ItemStack stack, int pos) {
NBTTagCompound cmp = ItemNBTHelper.getCompound(stack, TAG_LENS + pos, true);
if(cmp != null) {
return new ItemStack(cmp);
}
return ItemStack.EMPTY;
}
public static void setLensAtPos(ItemStack stack, ItemStack lens, int pos) {
NBTTagCompound cmp = new NBTTagCompound();
if(lens != null)
cmp = lens.writeToNBT(cmp);
ItemNBTHelper.setCompound(stack, TAG_LENS + pos, cmp);
}
public static void setLens(ItemStack stack, ItemStack lens) {
if(hasClip(stack))
setLensAtPos(stack, lens, getClipPos(stack));
NBTTagCompound cmp = new NBTTagCompound();
if(!lens.isEmpty())
cmp = lens.writeToNBT(cmp);
ItemNBTHelper.setCompound(stack, TAG_LENS, cmp);
}
public static ItemStack getLens(ItemStack stack) {
if(hasClip(stack))
return getLensAtPos(stack, getClipPos(stack));
NBTTagCompound cmp = ItemNBTHelper.getCompound(stack, TAG_LENS, true);
if(cmp != null) {
return new ItemStack(cmp);
}
return ItemStack.EMPTY;
}
public static List<ItemStack> getAllLens(ItemStack stack) {
List<ItemStack> ret = new ArrayList<>();
for (int i = 0; i < 6; i++) {
ret.add(getLensAtPos(stack, i));
}
return ret;
}
@Override
public void onUpdate(ItemStack par1ItemStack, World world, Entity par3Entity, int par4, boolean par5) {
if(par1ItemStack.isItemDamaged())
par1ItemStack.setItemDamage(par1ItemStack.getItemDamage() - 1);
}
@Override
public boolean usesMana(ItemStack stack) {
return true;
}
@SideOnly(Side.CLIENT)
@Override
public void registerModels() {
ModelBakery.registerItemVariants(this,
new ModelResourceLocation("botania:desuGunClip", "inventory"),
new ModelResourceLocation("botania:desuGun", "inventory"),
new ModelResourceLocation("botania:manaGunClip", "inventory"),
new ModelResourceLocation("botania:manaGun", "inventory"));
ModelLoader.setCustomMeshDefinition(this, stack -> {
if (hasClip(stack) && isSugoiKawaiiDesuNe(stack))
return new ModelResourceLocation("botania:desuGunClip", "inventory");
else if (isSugoiKawaiiDesuNe(stack))
return new ModelResourceLocation("botania:desuGun", "inventory");
else if(hasClip(stack))
return new ModelResourceLocation("botania:manaGunClip", "inventory");
else return new ModelResourceLocation("botania:manaGun", "inventory");
});
}
}