diff --git a/src/main/java/vazkii/botania/api/internal/DummyMethodHandler.java b/src/main/java/vazkii/botania/api/internal/DummyMethodHandler.java index b5bc59f1f..94d165359 100644 --- a/src/main/java/vazkii/botania/api/internal/DummyMethodHandler.java +++ b/src/main/java/vazkii/botania/api/internal/DummyMethodHandler.java @@ -17,6 +17,7 @@ import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.inventory.IInventory; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.tileentity.TileEntity; @@ -177,4 +178,11 @@ public class DummyMethodHandler implements IInternalMethodHandler { return false; } + + @Override + public void breakOnAllCursors(EntityPlayer player, Item item, ItemStack stack, int x, int y, int z, int side) { + // NO-OP + } + + } diff --git a/src/main/java/vazkii/botania/api/internal/IInternalMethodHandler.java b/src/main/java/vazkii/botania/api/internal/IInternalMethodHandler.java index a5892b6dc..b3f257743 100644 --- a/src/main/java/vazkii/botania/api/internal/IInternalMethodHandler.java +++ b/src/main/java/vazkii/botania/api/internal/IInternalMethodHandler.java @@ -16,6 +16,7 @@ import net.minecraft.client.gui.ScaledResolution; import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.inventory.IInventory; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.tileentity.TileEntity; @@ -85,6 +86,8 @@ public interface IInternalMethodHandler { public IInventory getBaublesInventory(EntityPlayer player); + public void breakOnAllCursors(EntityPlayer player, Item item, ItemStack stack, int x, int y, int z, int side); + @SideOnly(Side.CLIENT) public void drawSimpleManaHUD(int color, int mana, int maxMana, String name, ScaledResolution res); diff --git a/src/main/java/vazkii/botania/api/item/ISequentialBreaker.java b/src/main/java/vazkii/botania/api/item/ISequentialBreaker.java new file mode 100644 index 000000000..d135abfdb --- /dev/null +++ b/src/main/java/vazkii/botania/api/item/ISequentialBreaker.java @@ -0,0 +1,27 @@ +/** + * This class was created by . 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 30, 2015, 2:46:05 PM (GMT)] + */ +package vazkii.botania.api.item; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +/** + * An item that implements this can break multiple blocks at once + * with a Ring of Loki. Usage of this interface requires an implementation + * (see ItemTerraPick). + */ +public interface ISequentialBreaker { + + public void breakOtherBlock(EntityPlayer player, ItemStack stack, int x, int y, int z, int originX, int originY, int originZ, int side); + + public boolean disposeOfTrashBlocks(ItemStack stack); + +} diff --git a/src/main/java/vazkii/botania/common/core/handler/InternalMethodHandler.java b/src/main/java/vazkii/botania/common/core/handler/InternalMethodHandler.java index 5008b525b..589b4806c 100644 --- a/src/main/java/vazkii/botania/common/core/handler/InternalMethodHandler.java +++ b/src/main/java/vazkii/botania/common/core/handler/InternalMethodHandler.java @@ -17,6 +17,7 @@ import net.minecraft.client.renderer.texture.IIconRegister; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.init.Blocks; import net.minecraft.inventory.IInventory; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.crafting.IRecipe; import net.minecraft.tileentity.TileEntity; @@ -40,6 +41,7 @@ import vazkii.botania.common.block.BlockModFlower; import vazkii.botania.common.block.BlockSpecialFlower; import vazkii.botania.common.block.ModBlocks; import vazkii.botania.common.item.block.ItemBlockSpecialFlower; +import vazkii.botania.common.item.relic.ItemLokiRing; import vazkii.botania.common.lexicon.page.PageBrew; import vazkii.botania.common.lexicon.page.PageCraftingRecipe; import vazkii.botania.common.lexicon.page.PageElvenRecipe; @@ -199,4 +201,9 @@ public class InternalMethodHandler extends DummyMethodHandler { public boolean isBuildcraftPipe(TileEntity tile) { return tile instanceof IPipeTile; } + + @Override + public void breakOnAllCursors(EntityPlayer player, Item item, ItemStack stack, int x, int y, int z, int side) { + ItemLokiRing.breakOnAllCursors(player, item, stack, x, y, z, side); + } } diff --git a/src/main/java/vazkii/botania/common/item/equipment/tool/ItemTerraPick.java b/src/main/java/vazkii/botania/common/item/equipment/tool/ItemTerraPick.java index c775d3063..9076a62a2 100644 --- a/src/main/java/vazkii/botania/common/item/equipment/tool/ItemTerraPick.java +++ b/src/main/java/vazkii/botania/common/item/equipment/tool/ItemTerraPick.java @@ -31,6 +31,7 @@ import net.minecraftforge.common.util.ForgeDirection; import net.minecraftforge.oredict.RecipeSorter; import net.minecraftforge.oredict.RecipeSorter.Category; import vazkii.botania.api.BotaniaAPI; +import vazkii.botania.api.item.ISequentialBreaker; import vazkii.botania.api.mana.IManaItem; import vazkii.botania.client.core.helper.IconHelper; import vazkii.botania.common.achievement.ModAchievements; @@ -41,12 +42,13 @@ import vazkii.botania.common.item.ModItems; import vazkii.botania.common.item.equipment.bauble.ItemAuraRing; import vazkii.botania.common.item.equipment.bauble.ItemGreaterAuraRing; import vazkii.botania.common.item.equipment.tool.manasteel.ItemManasteelPick; +import vazkii.botania.common.item.relic.ItemLokiRing; import vazkii.botania.common.lib.LibItemNames; import cpw.mods.fml.common.registry.GameRegistry; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; -public class ItemTerraPick extends ItemManasteelPick implements IManaItem { +public class ItemTerraPick extends ItemManasteelPick implements IManaItem, ISequentialBreaker { private static final String TAG_ENABLED = "enabled"; private static final String TAG_MANA = "mana"; @@ -119,19 +121,30 @@ public class ItemTerraPick extends ItemManasteelPick implements IManaItem { @Override public boolean onBlockStartBreak(ItemStack stack, int x, int y, int z, EntityPlayer player) { + MovingObjectPosition raycast = ToolCommons.raytraceFromEntity(player.worldObj, player, true, 10); + if(raycast != null) { + breakOtherBlock(player, stack, x, y, z, x, y, z, raycast.sideHit); + ItemLokiRing.breakOnAllCursors(player, this, stack, x, y, z, raycast.sideHit); + // ^ Doable with API access through the IInternalMethodHandler. + } + + return false; + } + + @Override + public void breakOtherBlock(EntityPlayer player, ItemStack stack, int x, int y, int z, int originX, int originY, int originZ, int side) { if(!isEnabled(stack)) - return false; + return; World world = player.worldObj; Material mat = world.getBlock(x, y, z).getMaterial(); if(!ToolCommons.isRightMaterial(mat, MATERIALS)) - return false; + return; - MovingObjectPosition block = ToolCommons.raytraceFromEntity(world, player, true, 10); - if(block == null) - return false; + if(world.isAirBlock(x, y, z)) + return; - ForgeDirection direction = ForgeDirection.getOrientation(block.sideHit); + ForgeDirection direction = ForgeDirection.getOrientation(side); int fortune = EnchantmentHelper.getFortuneModifier(player); boolean silk = EnchantmentHelper.getSilkTouchModifier(player); boolean doX = direction.offsetX == 0; @@ -143,13 +156,11 @@ public class ItemTerraPick extends ItemManasteelPick implements IManaItem { int rangeY = Math.max(1, range); if(range == 0 && level != 1) - return false; + return; ToolCommons.removeBlocksInIteration(player, stack, world, x, y, z, doX ? -range : 0, doY ? -1 : 0, doZ ? -range : 0, doX ? range + 1 : 1, doY ? rangeY * 2 : 1, doZ ? range + 1 : 1, null, MATERIALS, silk, fortune, isTipped(stack)); if(level == 5) player.addStat(ModAchievements.rankSSPick, 1); - - return false; } @Override @@ -261,4 +272,9 @@ public class ItemTerraPick extends ItemManasteelPick implements IManaItem { return par2ItemStack.getItem() == ModItems.manaResource && par2ItemStack.getItemDamage() == 4 ? true : super.getIsRepairable(par1ItemStack, par2ItemStack); } + @Override + public boolean disposeOfTrashBlocks(ItemStack stack) { + return isTipped(stack); + } + } diff --git a/src/main/java/vazkii/botania/common/item/relic/ItemLokiRing.java b/src/main/java/vazkii/botania/common/item/relic/ItemLokiRing.java index 97b3a232a..a44a34ca2 100644 --- a/src/main/java/vazkii/botania/common/item/relic/ItemLokiRing.java +++ b/src/main/java/vazkii/botania/common/item/relic/ItemLokiRing.java @@ -13,7 +13,11 @@ package vazkii.botania.common.item.relic; import java.util.ArrayList; import java.util.List; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; import net.minecraft.client.Minecraft; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentHelper; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.Item; @@ -21,11 +25,14 @@ import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.ChunkCoordinates; import net.minecraft.util.MovingObjectPosition; +import net.minecraft.world.World; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; +import vazkii.botania.api.item.ISequentialBreaker; import vazkii.botania.api.item.IWireframeCoordinateListProvider; import vazkii.botania.common.core.helper.ItemNBTHelper; +import vazkii.botania.common.item.ModItems; import vazkii.botania.common.item.equipment.tool.ToolCommons; import vazkii.botania.common.lib.LibItemNames; import baubles.api.BaubleType; @@ -88,11 +95,35 @@ public class ItemLokiRing extends ItemRelicBauble implements IWireframeCoordinat int y = lookPos.blockY + cursor.posY; int z = lookPos.blockZ + cursor.posZ; Item item = heldItemStack.getItem(); - item.onItemUse(player.capabilities.isCreativeMode ? heldItemStack.copy() : heldItemStack, player, player.worldObj, x, y, z, lookPos.sideHit, (float) lookPos.hitVec.xCoord - x, (float) lookPos.hitVec.yCoord - y, (float) lookPos.hitVec.zCoord - z); + if(!player.worldObj.isAirBlock(x, y, z)) + item.onItemUse(player.capabilities.isCreativeMode ? heldItemStack.copy() : heldItemStack, player, player.worldObj, x, y, z, lookPos.sideHit, (float) lookPos.hitVec.xCoord - x, (float) lookPos.hitVec.yCoord - y, (float) lookPos.hitVec.zCoord - z); } } } + public static void breakOnAllCursors(EntityPlayer player, Item item, ItemStack stack, int x, int y, int z, int side) { + ItemStack lokiRing = getLokiRing(player); + if(lokiRing == null || player.worldObj.isRemote || !(item instanceof ISequentialBreaker)) + return; + + List cursors = getCursorList(lokiRing); + ISequentialBreaker breaker = (ISequentialBreaker) item; + World world = player.worldObj; + boolean silk = EnchantmentHelper.getEnchantmentLevel(Enchantment.silkTouch.effectId, stack) > 0; + int fortune = EnchantmentHelper.getEnchantmentLevel(Enchantment.fortune.effectId, stack); + boolean dispose = breaker.disposeOfTrashBlocks(stack); + + for(int i = 0; i < cursors.size(); i++) { + ChunkCoordinates coords = cursors.get(i); + int xp = x + coords.posX; + int yp = y + coords.posY; + int zp = z + coords.posZ; + Block block = world.getBlock(xp, yp, zp); + breaker.breakOtherBlock(player, stack, xp, yp, zp, x, y, z, side); + ToolCommons.removeBlockWithDrops(player, stack, player.worldObj, xp, yp, zp, x, y, z, block, new Material[] { block.getMaterial() }, silk, fortune, block.getBlockHardness(world, xp, yp, zp), dispose); + } + } + @Override public BaubleType getBaubleType(ItemStack arg0) { return BaubleType.RING; @@ -131,27 +162,31 @@ public class ItemLokiRing extends ItemRelicBauble implements IWireframeCoordinat return null; } - private ItemStack getLokiRing(EntityPlayer player) { + private static ItemStack getLokiRing(EntityPlayer player) { InventoryBaubles baubles = PlayerHandler.getPlayerBaubles(player); ItemStack stack1 = baubles.getStackInSlot(1); ItemStack stack2 = baubles.getStackInSlot(2); - return (stack1 != null && stack1.getItem() == this) ? stack1 : (stack2 != null && stack2.getItem() == this) ? stack2 : null; + return isLokiRing(stack1) ? stack1 : isLokiRing(stack2) ? stack2 : null; } - private ChunkCoordinates getOriginPos(ItemStack stack) { + private static boolean isLokiRing(ItemStack stack) { + return stack != null && (stack.getItem() == ModItems.lokiRing || stack.getItem() == ModItems.aesirRing); + } + + private static ChunkCoordinates getOriginPos(ItemStack stack) { int x = ItemNBTHelper.getInt(stack, TAG_X_ORIGIN, 0); int y = ItemNBTHelper.getInt(stack, TAG_Y_ORIGIN, -1); int z = ItemNBTHelper.getInt(stack, TAG_Z_ORIGIN, 0); return new ChunkCoordinates(x, y, z); } - private void setOriginPos(ItemStack stack, int x, int y, int z) { + private static void setOriginPos(ItemStack stack, int x, int y, int z) { ItemNBTHelper.setInt(stack, TAG_X_ORIGIN, x); ItemNBTHelper.setInt(stack, TAG_Y_ORIGIN, y); ItemNBTHelper.setInt(stack, TAG_Z_ORIGIN, z); } - private List getCursorList(ItemStack stack) { + private static List getCursorList(ItemStack stack) { NBTTagCompound cmp = ItemNBTHelper.getCompound(stack, TAG_CURSOR_LIST, false); List cursors = new ArrayList(); @@ -167,7 +202,7 @@ public class ItemLokiRing extends ItemRelicBauble implements IWireframeCoordinat return cursors; } - private void setCursorList(ItemStack stack, List cursors) { + private static void setCursorList(ItemStack stack, List cursors) { NBTTagCompound cmp = new NBTTagCompound(); if(cursors != null) { int i = 0; @@ -182,7 +217,7 @@ public class ItemLokiRing extends ItemRelicBauble implements IWireframeCoordinat ItemNBTHelper.setCompound(stack, TAG_CURSOR_LIST, cmp); } - private NBTTagCompound cursorToCmp(int x, int y, int z) { + private static NBTTagCompound cursorToCmp(int x, int y, int z) { NBTTagCompound cmp = new NBTTagCompound(); cmp.setInteger(TAG_X_OFFSET, x); cmp.setInteger(TAG_Y_OFFSET, y); @@ -190,7 +225,7 @@ public class ItemLokiRing extends ItemRelicBauble implements IWireframeCoordinat return cmp; } - private void addCursor(ItemStack stack, int x, int y, int z) { + private static void addCursor(ItemStack stack, int x, int y, int z) { NBTTagCompound cmp = ItemNBTHelper.getCompound(stack, TAG_CURSOR_LIST, false); int count = cmp.getInteger(TAG_CURSOR_COUNT); cmp.setTag(TAG_CURSOR_PREFIX + count, cursorToCmp(x, y, z));