/** * This class was created by <Flaxbeard>. 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 @ [Aug 25, 2014, 2:57:16 PM (GMT)] */ package vazkii.botania.common.item.rod; import java.util.ArrayList; import java.util.List; import javax.annotation.Nonnull; import net.minecraft.entity.Entity; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.MobEffects; import net.minecraft.item.ItemStack; import net.minecraft.potion.PotionEffect; import net.minecraft.util.ActionResult; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumHand; import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.world.World; import vazkii.botania.api.BotaniaAPI; import vazkii.botania.api.item.IManaProficiencyArmor; import vazkii.botania.api.mana.IManaUsingItem; import vazkii.botania.api.mana.ManaItemHandler; import vazkii.botania.common.Botania; import vazkii.botania.common.core.helper.ItemNBTHelper; import vazkii.botania.common.core.helper.MathHelper; import vazkii.botania.common.core.helper.Vector3; import vazkii.botania.common.entity.EntityThrownItem; import vazkii.botania.common.item.ItemMod; import vazkii.botania.common.item.ModItems; import vazkii.botania.common.lib.LibItemNames; public class ItemGravityRod extends ItemMod implements IManaUsingItem { private static final float RANGE = 3F; private static final int COST = 2; private static final String TAG_TICKS_TILL_EXPIRE = "ticksTillExpire"; private static final String TAG_TICKS_COOLDOWN = "ticksCooldown"; private static final String TAG_TARGET = "target"; private static final String TAG_DIST = "dist"; public ItemGravityRod() { super(LibItemNames.GRAVITY_ROD); setMaxStackSize(1); } @Override public boolean shouldCauseReequipAnimation(ItemStack oldStack, @Nonnull ItemStack newStack, boolean slotChanged) { return newStack.getItem() != this; } @Override public void onUpdate(ItemStack stack, World world, Entity par3Entity, int slot, boolean held) { if(!(par3Entity instanceof EntityPlayer)) return; int ticksTillExpire = ItemNBTHelper.getInt(stack, TAG_TICKS_TILL_EXPIRE, 0); int ticksCooldown = ItemNBTHelper.getInt(stack, TAG_TICKS_COOLDOWN, 0); if(ticksTillExpire == 0) { ItemNBTHelper.setInt(stack, TAG_TARGET, -1); ItemNBTHelper.setDouble(stack, TAG_DIST, -1); } if(ticksCooldown > 0) ticksCooldown--; ticksTillExpire--; ItemNBTHelper.setInt(stack, TAG_TICKS_TILL_EXPIRE, ticksTillExpire); ItemNBTHelper.setInt(stack, TAG_TICKS_COOLDOWN, ticksCooldown); EntityPlayer player = (EntityPlayer) par3Entity; PotionEffect haste = player.getActivePotionEffect(MobEffects.HASTE); float check = haste == null ? 0.16666667F : haste.getAmplifier() == 1 ? 0.5F : 0.4F; if(player.getHeldItemMainhand() == stack && player.swingProgress == check && !world.isRemote) leftClick(player); } @Nonnull @Override public ActionResult<ItemStack> onItemRightClick(World world, EntityPlayer player, @Nonnull EnumHand hand) { ItemStack stack = player.getHeldItem(hand); int targetID = ItemNBTHelper.getInt(stack, TAG_TARGET, -1); int ticksCooldown = ItemNBTHelper.getInt(stack, TAG_TICKS_COOLDOWN, 0); double length = ItemNBTHelper.getDouble(stack, TAG_DIST, -1); if(ticksCooldown == 0) { Entity item = null; if(targetID != -1 && player.world.getEntityByID(targetID) != null) { Entity taritem = player.world.getEntityByID(targetID); boolean found = false; Vector3 target = Vector3.fromEntityCenter(player); List<Entity> entities = new ArrayList<>(); int distance = 1; while(entities.size() == 0 && distance < 25) { target = target.add(new Vector3(player.getLookVec()).multiply(distance)).add(0, 0.5, 0); entities = player.world.getEntitiesWithinAABBExcludingEntity(player, new AxisAlignedBB(target.x - RANGE, target.y - RANGE, target.z - RANGE, target.x + RANGE, target.y + RANGE, target.z + RANGE)); distance++; if(entities.contains(taritem)) found = true; } if(found) item = player.world.getEntityByID(targetID); } if(item == null) { Vector3 target = Vector3.fromEntityCenter(player); List<Entity> entities = new ArrayList<>(); int distance = 1; while(entities.size() == 0 && distance < 25) { target = target.add(new Vector3(player.getLookVec()).multiply(distance)).add(0, 0.5, 0); entities = player.world.getEntitiesWithinAABBExcludingEntity(player, new AxisAlignedBB(target.x - RANGE, target.y - RANGE, target.z - RANGE, target.x + RANGE, target.y + RANGE, target.z + RANGE)); distance++; } if(entities.size() > 0) { item = entities.get(0); length = 5.5D; if(item instanceof EntityItem) length = 2.0D; } } if(item != null) { if(BotaniaAPI.isEntityBlacklistedFromGravityRod(item.getClass())) return ActionResult.newResult(EnumActionResult.FAIL, stack); if(ManaItemHandler.requestManaExactForTool(stack, player, COST, true)) { if(item instanceof EntityItem) ((EntityItem) item).setPickupDelay(5); if(item instanceof EntityLivingBase) { EntityLivingBase targetEntity = (EntityLivingBase)item; targetEntity.fallDistance = 0.0F; if(targetEntity.getActivePotionEffect(MobEffects.SLOWNESS) == null) targetEntity.addPotionEffect(new PotionEffect(MobEffects.SLOWNESS, 2, 3, true, true)); } Vector3 target3 = Vector3.fromEntityCenter(player) .add(new Vector3(player.getLookVec()).multiply(length)).add(0, 0.5, 0); if(item instanceof EntityItem) target3 = target3.add(0, 0.25, 0); for(int i = 0; i < 4; i++) { float r = 0.5F + (float) Math.random() * 0.5F; float b = 0.5F + (float) Math.random() * 0.5F; float s = 0.2F + (float) Math.random() * 0.1F; float m = 0.1F; float xm = ((float) Math.random() - 0.5F) * m; float ym = ((float) Math.random() - 0.5F) * m; float zm = ((float) Math.random() - 0.5F) * m; Botania.proxy.wispFX(item.posX + item.width / 2, item.posY + item.height / 2, item.posZ + item.width / 2, r, 0F, b, s, xm, ym, zm); } MathHelper.setEntityMotionFromVector(item, target3, 0.3333333F); ItemNBTHelper.setInt(stack, TAG_TARGET, item.getEntityId()); ItemNBTHelper.setDouble(stack, TAG_DIST, length); } ItemNBTHelper.setInt(stack, TAG_TICKS_TILL_EXPIRE, 5); return ActionResult.newResult(EnumActionResult.SUCCESS, stack); } } return ActionResult.newResult(EnumActionResult.PASS, stack); } @Override public boolean usesMana(ItemStack stack) { return true; } public static void leftClick(EntityPlayer player) { ItemStack stack = player.getHeldItemMainhand(); if(!stack.isEmpty() && stack.getItem() == ModItems.gravityRod) { int targetID = ItemNBTHelper.getInt(stack, TAG_TARGET, -1); ItemNBTHelper.getDouble(stack, TAG_DIST, -1); Entity item; if(targetID != -1 && player.world.getEntityByID(targetID) != null) { Entity taritem = player.world.getEntityByID(targetID); boolean found = false; Vector3 target = Vector3.fromEntityCenter(player); List<Entity> entities = new ArrayList<>(); int distance = 1; while(entities.size() == 0 && distance < 25) { target = target.add(new Vector3(player.getLookVec()).multiply(distance)).add(0, 0.5, 0); entities = player.world.getEntitiesWithinAABBExcludingEntity(player, new AxisAlignedBB(target.x - RANGE, target.y - RANGE, target.z - RANGE, target.x + RANGE, target.y + RANGE, target.z + RANGE)); distance++; if(entities.contains(taritem)) found = true; } if(found) { item = player.world.getEntityByID(targetID); ItemNBTHelper.setInt(stack, TAG_TARGET, -1); ItemNBTHelper.setDouble(stack, TAG_DIST, -1); Vector3 moveVector = new Vector3(player.getLookVec().normalize()); if(item instanceof EntityItem) { ((EntityItem) item).setPickupDelay(20); float mot = IManaProficiencyArmor.Helper.hasProficiency(player, stack) ? 2.25F : 1.5F; item.motionX = moveVector.x * mot; item.motionY = moveVector.y; item.motionZ = moveVector.z * mot; if(!player.world.isRemote) { EntityThrownItem thrown = new EntityThrownItem(item.world, item.posX, item.posY, item.posZ, (EntityItem) item); item.world.spawnEntity(thrown); } item.setDead(); } else { item.motionX = moveVector.x * 3.0F; item.motionY = moveVector.y * 1.5F; item.motionZ = moveVector.z * 3.0F; } ItemNBTHelper.setInt(stack, TAG_TICKS_COOLDOWN, 10); } } } } }