/* * This file is part of Project-Zed. Project-Zed is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. Project-Zed is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should * have received a copy of the GNU General Public License along with Project-Zed. If not, see <http://www.gnu * .org/licenses/> */ package com.projectzed.mod.item.tools; import com.hockeyhurd.hcorelib.api.math.VectorHelper; import com.hockeyhurd.hcorelib.api.util.*; import com.projectzed.api.util.SidedInfo; import com.projectzed.mod.ProjectZed; import com.projectzed.mod.handler.PacketHandler; import com.projectzed.mod.handler.message.MessageItemAdjustable; import com.projectzed.mod.item.IItemAdjustableRadii; import com.projectzed.mod.util.Reference; import net.minecraft.block.BlockContainer; import net.minecraft.block.state.IBlockState; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumActionResult; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.text.TextFormatting; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Item class for ItemBlockExchanger. * * @author hockeyhurd * @version 3/11/2016. */ public class ItemBlockExchanger extends AbstractItemPowered implements IItemAdjustableRadii { private int radii = 1; private IBlockState blockToPlace; private TimerHelper timer; /** * @param name Name of item. */ public ItemBlockExchanger(String name) { super(name); timer = new TimerHelper(20, 2); } @Override @SideOnly(Side.CLIENT) @SuppressWarnings("unchecked") public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean flag) { String blockName = blockToPlace != null ? blockToPlace.getBlock().getLocalizedName() : "<empty>"; list.add(TextFormatting.GREEN + "Block set to: " + TextFormatting.WHITE + blockName); list.add(TextFormatting.GREEN + "Radii set to: " + TextFormatting.WHITE + radii); list.add(TextFormatting.GREEN + "Stored: " + TextFormatting.WHITE + NumberFormatter.format(getStored(stack)) + " McU"); list.add(TextFormatting.GREEN + "Capacity: " + TextFormatting.WHITE + NumberFormatter.format(this.capacity) + " McU"); } @Override public EnumActionResult onItemUse(ItemStack stack, EntityPlayer player, World world, BlockPos blockPos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) { EnumActionResult result = EnumActionResult.FAIL; if (!world.isRemote) { /* * sideHit == 0, bottom sideHit == 1, top sideHit == 2, front sideHit == 3, back sideHit == 4, left sideHit == 5, right */ if (!timer.getUse() && !player.isSneaking() && blockToPlace != null) { timer.trigger(); // ProjectZed.logHelper.info("Side:", side, blockToPlace.getLocalizedName()); int amountToPlace = (radii << 1) + 1; amountToPlace *= amountToPlace; Map<Integer, Integer> invMap = new HashMap<Integer, Integer>((player.inventory.getSizeInventory() * 3) >> 1, 2.0f / 3.0f); int itemCount = 0; final ItemStack blockToPlaceStack = new ItemStack(blockToPlace.getBlock()); ItemStack current; for (int i = 0; i < player.inventory.getSizeInventory(); i++) { current = player.inventory.getStackInSlot(i); if (current != null && ItemStack.areItemsEqual(current, blockToPlaceStack)) { invMap.put(i, current.stackSize); itemCount += current.stackSize; } } if (amountToPlace > itemCount) amountToPlace = itemCount; // ProjectZed.logHelper.info("Max # can place:", amountToPlace); int counter = amountToPlace; IBlockState currentBlock; BlockPos pos; final int side = facing.ordinal(); for (int i = -radii; i <= radii; i++) { for (int j = -radii; j <= radii; j++) { if (counter <= 0) break; if (side == 0 || side == 1) { pos = VectorHelper.toBlockPos(blockPos.getX() + i, blockPos.getY(), blockPos.getZ() + j); currentBlock = BlockUtils.getBlock(world, pos); if (currentBlock != blockToPlace && currentBlock.getBlockHardness(world, pos) > 0.0f) { BlockUtils.destroyBlock(world, pos); BlockUtils.setBlock(world, pos, blockToPlace); // world.markBlockForUpdate(x + i, y, z + j); world.notifyBlockOfStateChange(pos, currentBlock.getBlock()); counter--; result = EnumActionResult.SUCCESS; } } else if (side == 2 || side == 3) { pos = VectorHelper.toBlockPos(blockPos.getX() + i, blockPos.getY() + j, blockPos.getZ()); currentBlock = BlockUtils.getBlock(world, pos); if (currentBlock != blockToPlace && currentBlock.getBlockHardness(world, pos) > 0.0f) { BlockUtils.destroyBlock(world, pos); BlockUtils.setBlock(world, pos, blockToPlace); world.notifyBlockOfStateChange(pos, currentBlock.getBlock()); counter--; result = EnumActionResult.SUCCESS; } } else { pos = VectorHelper.toBlockPos(blockPos.getX(), blockPos.getY() + j, blockPos.getZ() + i); currentBlock = BlockUtils.getBlock(world, pos); if (currentBlock != blockToPlace && currentBlock.getBlockHardness(world, pos) > 0.0f) { BlockUtils.destroyBlock(world, pos); BlockUtils.setBlock(world, pos, blockToPlace); world.notifyBlockOfStateChange(pos, currentBlock.getBlock()); counter--; result = EnumActionResult.SUCCESS; } } // counter--; } } int amountPlaced = amountToPlace - counter; for (int i : invMap.keySet()) { current = player.inventory.getStackInSlot(i); final int displacement = Math.min(current.stackSize, amountPlaced); amountPlaced -= displacement; if (current.stackSize - displacement <= 0) player.inventory.setInventorySlotContents(i, null); else { current.stackSize -= displacement; player.inventory.setInventorySlotContents(i, current); } player.inventory.markDirty(); player.inventoryContainer.detectAndSendChanges(); if (amountPlaced <= 0) break; } } else blockToPlace = BlockUtils.getBlock(world, blockPos); } else { if (player.isSneaking()) { final IBlockState newBlock = BlockUtils.getBlock(world, blockPos); if (newBlock != blockToPlace && !(newBlock instanceof BlockContainer)) { blockToPlace = newBlock; player.addChatComponentMessage(ChatUtils.createComponent(false, Reference.Constants.RADII_MSG_TYPE + ' ' + blockToPlace.getBlock().getLocalizedName())); } } result = EnumActionResult.SUCCESS; } if (!timer.getUse()) player.swingArm(hand); return result; } @Override public void onUpdate(ItemStack stack, World world, Entity e, int i, boolean f) { super.onUpdate(stack, world, e, i, f); timer.update(); } @Override public void increment(EntityPlayer player, ItemStack stack) { if (radii < ProjectZed.configHandler.getMaxExchangerRadii()) { radii++; writeToNBT(stack); if (SidedHelper.isClient()) player.addChatComponentMessage(ChatUtils.createComponent(false, Reference.Constants.RADII_MSG_RADII_SET + radii)); } } @Override public void decrement(EntityPlayer player, ItemStack stack) { if (radii > 0) { radii--; writeToNBT(stack); if (SidedHelper.isClient()) player.addChatComponentMessage(ChatUtils.createComponent(false, Reference.Constants.RADII_MSG_RADII_SET + radii)); } } @Override public Object[] getData() { return new Object[] { radii }; } @Override public void setData(ItemStack stack, Object... data) { if (stack != null && data != null && data.length == 1) { radii = (Integer) data[0]; writeToNBT(stack); } } @Override public void writeToNBT(ItemStack stack) { // int value = readFromNBT(stack)[0]; readFromNBT(stack); NBTTagCompound comp = stack.getTagCompound(); if (comp == null) { comp = new NBTTagCompound(); stack.setTagCompound(comp); } comp.setInteger("ItemExchangerRadii", radii); } @Override public Integer[] readFromNBT(ItemStack stack) { NBTTagCompound comp = stack.getTagCompound(); if (comp == null) { comp = new NBTTagCompound(); stack.setTagCompound(comp); } int num = comp.getInteger("ItemExchangerRadii"); Integer[] val = { num }; return val; } @Override public int getRadii() { return radii; } @Override public void sendPacket(ItemStack stack, SidedInfo sidedInfo, Object... data) { if (stack == null || stack.stackSize == 0 || sidedInfo == null || data == null || data.length == 0) return; else if (sidedInfo.isSideServer()) { PacketHandler.INSTANCE.sendToServer(new MessageItemAdjustable(stack, (Integer) data[0])); } // We don't need to send packets to the client? } }