BloodMagic/src/main/java/WayofTime/bloodmagic/item/ItemBoundPickaxe.java
AEon - Tobias 753958ac9c Ritual portal delay / Bound Pickaxe fix/improvement (#1387)
* Teleportation now works similar to the Nether Portal:

if teleportation is attempted before the cooldown (10 ticks) is over, the cooldown gets reset.
This way teleportation loops are prevented.

You can now:
- Stand on a loop of permanently activated (well, constantly refreshing through a high-speed redstone clock) Teleposers, only getting teleposed once per stepping on it
- AFK in the Gate of the Fold without getting teleported constantly
- and other things, I guess.

* Bound Pickaxe AoE ability now destroys blocks properly.

closes #1001

* Streamlined bound tool harvest code.

Cleanup, duplicate code for bound tools moved as method to ItemBoundTool.sharedHarvest()

Tested aoe harvest with Stone, Dirt/Grass and Oak trees. Same result as before.

* silkTouch and fortuneLvl are now passed instead of recalculated on every block
2018-08-26 12:50:02 -07:00

127 lines
6.5 KiB
Java

package WayofTime.bloodmagic.item;
import WayofTime.bloodmagic.client.IMeshProvider;
import WayofTime.bloodmagic.client.mesh.CustomMeshDefinitionActivatable;
import WayofTime.bloodmagic.core.data.SoulTicket;
import WayofTime.bloodmagic.util.BlockStack;
import WayofTime.bloodmagic.util.ItemStackWrapper;
import WayofTime.bloodmagic.util.helper.NetworkHelper;
import com.google.common.collect.*;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.renderer.ItemMeshDefinition;
import net.minecraft.enchantment.EnchantmentHelper;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.SharedMonsterAttributes;
import net.minecraft.entity.ai.attributes.AttributeModifier;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.init.Blocks;
import net.minecraft.init.Enchantments;
import net.minecraft.inventory.EntityEquipmentSlot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.BlockEvent;
import net.minecraftforge.fml.common.eventhandler.Event;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import java.util.Set;
import java.util.function.Consumer;
public class ItemBoundPickaxe extends ItemBoundTool implements IMeshProvider {
private static final Set<Block> EFFECTIVE_ON = Sets.newHashSet(Blocks.ACTIVATOR_RAIL, Blocks.COAL_ORE, Blocks.COBBLESTONE, Blocks.DETECTOR_RAIL, Blocks.DIAMOND_BLOCK, Blocks.DIAMOND_ORE, Blocks.STONE_SLAB, Blocks.GOLDEN_RAIL, Blocks.GOLD_BLOCK, Blocks.GOLD_ORE, Blocks.ICE, Blocks.IRON_BLOCK, Blocks.IRON_ORE, Blocks.LAPIS_BLOCK, Blocks.LAPIS_ORE, Blocks.LIT_REDSTONE_ORE, Blocks.MOSSY_COBBLESTONE, Blocks.NETHERRACK, Blocks.PACKED_ICE, Blocks.RAIL, Blocks.REDSTONE_ORE, Blocks.SANDSTONE, Blocks.RED_SANDSTONE, Blocks.STONE, Blocks.STONE_SLAB);
public ItemBoundPickaxe() {
super("pickaxe", 5, EFFECTIVE_ON);
}
@Override
public boolean hitEntity(ItemStack stack, EntityLivingBase target, EntityLivingBase attacker) {
return true;
}
@Override
public boolean onBlockDestroyed(ItemStack stack, World world, IBlockState block, BlockPos pos, EntityLivingBase entityLiving) {
return true;
}
@Override
public boolean canHarvestBlock(IBlockState blockIn) {
return blockIn == Blocks.OBSIDIAN ? this.toolMaterial.getHarvestLevel() == 3
: (blockIn != Blocks.DIAMOND_BLOCK && blockIn != Blocks.DIAMOND_ORE ? (blockIn != Blocks.EMERALD_ORE && blockIn != Blocks.EMERALD_BLOCK ? (blockIn != Blocks.GOLD_BLOCK && blockIn != Blocks.GOLD_ORE ? (blockIn != Blocks.IRON_BLOCK && blockIn != Blocks.IRON_ORE ? (blockIn != Blocks.LAPIS_BLOCK && blockIn != Blocks.LAPIS_ORE ? (blockIn != Blocks.REDSTONE_ORE && blockIn != Blocks.LIT_REDSTONE_ORE ? (blockIn.getMaterial() == Material.ROCK || (blockIn.getMaterial() == Material.IRON || blockIn.getMaterial() == Material.ANVIL)) : this.toolMaterial.getHarvestLevel() >= 2)
: this.toolMaterial.getHarvestLevel() >= 1) : this.toolMaterial.getHarvestLevel() >= 1) : this.toolMaterial.getHarvestLevel() >= 2) : this.toolMaterial.getHarvestLevel() >= 2) : this.toolMaterial.getHarvestLevel() >= 2);
}
@Override
public float getDestroySpeed(ItemStack stack, IBlockState state) {
if (!getActivated(stack))
return 1.0F;
return state.getMaterial() != Material.IRON && state.getMaterial() != Material.ANVIL && state.getMaterial() != Material.ROCK ? super.getDestroySpeed(stack, state) : this.efficiency;
}
@Override
protected void onBoundRelease(ItemStack stack, World world, EntityPlayer player, int charge) {
if (world.isRemote)
return;
int fortuneLvl = EnchantmentHelper.getEnchantmentLevel(Enchantments.FORTUNE, stack);
boolean silkTouch = EnchantmentHelper.getEnchantmentLevel(Enchantments.SILK_TOUCH, stack) > 0;
int range = (charge / 6); //Charge is a max of 30 - want 5 to be the max
HashMultiset<ItemStackWrapper> drops = HashMultiset.create();
BlockPos playerPos = player.getPosition();
for (int i = -range; i <= range; i++) {
for (int j = 0; j <= 2 * range; j++) {
for (int k = -range; k <= range; k++) {
BlockPos blockPos = playerPos.add(i, j, k);
BlockStack blockStack = BlockStack.getStackFromPos(world, blockPos);
if (blockStack.getBlock().isAir(blockStack.getState(), world, blockPos))
continue;
if (blockStack.getState().getMaterial() != Material.ROCK && !EFFECTIVE_ON.contains(blockStack.getBlock()))
continue;
BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(world, blockPos, blockStack.getState(), player);
if (MinecraftForge.EVENT_BUS.post(event) || event.getResult() == Event.Result.DENY)
continue;
sharedHarvest(stack, world, player, blockPos, blockStack, drops, silkTouch, fortuneLvl);
}
}
}
NetworkHelper.getSoulNetwork(player).syphonAndDamage(player, SoulTicket.item(stack, world, player, (int) (charge * charge * charge / 2.7)));
world.createExplosion(player, playerPos.getX(), playerPos.getY(), playerPos.getZ(), 0.5F, false);
dropStacks(drops, world, playerPos.add(0, 1, 0));
}
@Override
public Multimap<String, AttributeModifier> getAttributeModifiers(EntityEquipmentSlot equipmentSlot, ItemStack stack) {
Multimap<String, AttributeModifier> multimap = super.getItemAttributeModifiers(equipmentSlot);
if (equipmentSlot == EntityEquipmentSlot.MAINHAND) {
multimap.put(SharedMonsterAttributes.ATTACK_DAMAGE.getName(), new AttributeModifier(ATTACK_DAMAGE_MODIFIER, "Weapon modifier", getActivated(stack) ? 5 : 2, 0));
multimap.put(SharedMonsterAttributes.ATTACK_SPEED.getName(), new AttributeModifier(ATTACK_SPEED_MODIFIER, "Tool modifier", -2.5, 0));
}
return multimap;
}
@Override
@SideOnly(Side.CLIENT)
public ItemMeshDefinition getMeshDefinition() {
return new CustomMeshDefinitionActivatable("bound_pickaxe");
}
@Override
public void gatherVariants(Consumer<String> variants) {
variants.accept("active=true");
variants.accept("active=false");
}
}