package pixlepix.auracascade.item;
import net.minecraft.block.Block;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.item.ItemBlock;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ActionResult;
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.TextComponentString;
import net.minecraft.world.World;
import pixlepix.auracascade.main.EnumColor;
import pixlepix.auracascade.main.ParticleEffects;
import pixlepix.auracascade.registry.CraftingBenchRecipe;
import pixlepix.auracascade.registry.ITTinkererItem;
import pixlepix.auracascade.registry.ThaumicTinkererRecipe;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
/**
* Created by localmacaccount on 5/16/15.
*/
public class ItemPrismaticWand extends Item implements ITTinkererItem {
public static String[] modes = new String[]{EnumColor.AQUA + "Selection", EnumColor.YELLOW + "Copy", EnumColor.ORANGE + "Paste"};
public ItemPrismaticWand() {
super();
setMaxStackSize(1);
}
@Override
public EnumActionResult onItemUse(ItemStack stack, EntityPlayer player, World world, BlockPos pos, EnumHand hand, EnumFacing facing, float hitX, float hitY, float hitZ) {
//More specific selections
if (!player.isSneaking() && !world.isRemote) {
if (stack.getTagCompound() == null) {
stack.setTagCompound(new NBTTagCompound());
}
NBTTagCompound nbt = stack.getTagCompound();
if (stack.getItemDamage() == 0) {
if (nbt.hasKey("x1")) {
nbt.setInteger("x2", nbt.getInteger("x1"));
nbt.setInteger("y2", nbt.getInteger("y1"));
nbt.setInteger("z2", nbt.getInteger("z1"));
}
nbt.setInteger("x1", pos.getX());
nbt.setInteger("y1", pos.getY());
nbt.setInteger("z1", pos.getZ());
player.addChatComponentMessage(new TextComponentString("Position set"));
return EnumActionResult.PASS;
}
}
return EnumActionResult.FAIL;
}
@Override
public void addInformation(ItemStack stack, EntityPlayer player, List<String> list, boolean p_77624_4_) {
super.addInformation(stack, player, list, p_77624_4_);
list.add(modes[stack.getItemDamage()]);
}
@Override
public ActionResult<ItemStack> onItemRightClick(ItemStack stack, World world, EntityPlayer player, EnumHand hand){
int mode = stack.getItemDamage();
if (player.isSneaking()) {
NBTTagCompound nbt = stack.getTagCompound();
mode++;
mode = mode % modes.length;
stack.setItemDamage(mode);
stack.setTagCompound(nbt);
if (!world.isRemote) {
player.addChatComponentMessage(new TextComponentString("Switched to: " + modes[mode]));
}
} else {
if (stack.getTagCompound() == null) {
stack.setTagCompound(new NBTTagCompound());
}
NBTTagCompound nbt = stack.getTagCompound();
switch (mode) {
case 1:
if (nbt.hasKey("x1") && nbt.hasKey("x2")) {
nbt.setInteger("cx1", nbt.getInteger("x1"));
nbt.setInteger("cy1", nbt.getInteger("y1"));
nbt.setInteger("cz1", nbt.getInteger("z1"));
nbt.setInteger("cx2", nbt.getInteger("x2"));
nbt.setInteger("cy2", nbt.getInteger("y2"));
nbt.setInteger("cz2", nbt.getInteger("z2"));
//This is how far away the player is from the copy/paste
nbt.setInteger("cxo", nbt.getInteger("x1") - roundToZero(player.posX));
nbt.setInteger("cyo", nbt.getInteger("y1") - roundToZero(player.posY));
nbt.setInteger("czo", nbt.getInteger("z1") - roundToZero(player.posZ));
if (!world.isRemote) {
player.addChatComponentMessage(new TextComponentString("Copied to clipboard"));
}
} else {
if (!world.isRemote) {
player.addChatComponentMessage(new TextComponentString("Invalid selection"));
}
}
break;
case 2:
int x = (int) player.posX;
int y = (int) player.posY;
int z = (int) player.posZ;
if (nbt.hasKey("cx1")) {
//Selection boundaries
int cx1 = nbt.getInteger("cx1");
int cy1 = nbt.getInteger("cy1");
int cz1 = nbt.getInteger("cz1");
int cx2 = nbt.getInteger("cx2");
int cy2 = nbt.getInteger("cy2");
int cz2 = nbt.getInteger("cz2");
//Offset from where the player standed as they calculated
int xo = nbt.getInteger("cxo");
int yo = nbt.getInteger("cyo");
int zo = nbt.getInteger("czo");
//For simplicities sake, c*1 is lower than c*2
if (cx1 > cx2) {
//Yes, yes, bitwise
//But thats just a party trick
//I mean, if you go to some nerdy parties
//xo, yo, zo were originally calculated relative to x1, y1, z1
//When we swap x1, we need to recalculate xo
//The players position when they copy-pasted = cx1 - xo
//New xo = newX1 - playerPos
//= cx2 - (cx1 - xo)
//= xo + (cx2 - cx1)
xo += (cx2 - cx1);
int t = cx1;
cx1 = cx2;
cx2 = t;
}
if (cy1 > cy2) {
yo += (cy2 - cy1);
int t = cy1;
cy1 = cy2;
cy2 = t;
}
if (cz1 > cz2) {
zo += (cz2 - cz1);
int t = cz1;
cz1 = cz2;
cz2 = t;
}
//itetate through selection
int xi = cx1;
do {
int yi = cy1;
do {
int zi = cz1;
do {
//Offsets are calculated. These offsets should be the same between the target and the destination
int dx = xi - cx1;
int dy = yi - cy1;
int dz = zi - cz1;
BlockPos oldPos = new BlockPos(cx1 + dx, cy1 + dy, cz1 + dz);
BlockPos newPos = new BlockPos(x + dx + xo, y + dy + yo, z + dz + zo);
if (world.isAirBlock(newPos)) {
Block block = world.getBlockState(oldPos).getBlock();
Item item = Item.getItemFromBlock(block);
int worldDmg = block.getMetaFromState(world.getBlockState(oldPos));
int dmg = block.damageDropped(world.getBlockState(oldPos));
boolean usesMetadataForPlacing = false;
List<ItemStack> drops = block.getDrops(world, oldPos, block.getStateFromMeta(dmg), 0);
if (drops.size() == 1) {
ItemStack dropStack = drops.get(0);
usesMetadataForPlacing = dropStack.getItem() == item && dropStack.getItemDamage() == 0 && worldDmg != 0;
}
if (player.capabilities.isCreativeMode) {
if (!world.isRemote) {
world.setBlockState(newPos, block.getStateFromMeta(worldDmg), 3);
}else{
particles(newPos);
}
} else if (player.inventory.hasItemStack(new ItemStack(item, 1, dmg))) {
int slot = slotOfItemStack(new ItemStack(item, 1, dmg), player.inventory);
if (item instanceof ItemBlock) {
if (!world.isRemote) {
((ItemBlock) item).placeBlockAt(player.inventory.getStackInSlot(slot), player, world, newPos, EnumFacing.DOWN, 0, 0, 0, ((ItemBlock) item).block.getStateFromMeta(dmg));
if (usesMetadataForPlacing) {
world.setBlockState(newPos, world.getBlockState(newPos).getBlock().getStateFromMeta(worldDmg), 3);
}
}else{
particles(newPos);
}
player.inventory.decrStackSize(slot, 1);
}
}
}
zi++;
} while (zi <= cz2);
yi++;
} while (yi <= cy2);
xi++;
} while (xi <= cx2);
if (!world.isRemote) {
player.addChatComponentMessage(new TextComponentString("Successfully pasted building"));
}
} else {
if (!world.isRemote) {
player.addChatComponentMessage(new TextComponentString("Nothing copied"));
}
}
break;
}
}
return new ActionResult<ItemStack>(EnumActionResult.PASS, stack);
}
public int roundToZero(double d) {
return (int) (d > 0 ? Math.floor(d) : Math.ceil(d));
}
private void particles(BlockPos pos) {
for (EnumFacing direction : EnumFacing.VALUES) {
for (int i = 0; i < 3; i++) {
Random random = new Random();
double x = pos.getX() + random.nextDouble();
double y = pos.getY() + random.nextDouble();
double z = pos.getZ() + random.nextDouble();
ParticleEffects.spawnParticle("witchMagic", x, y, z, 0, 0, 0, 0, 34, 264);
}
}
}
//Adapted from InventoryPlayer.hasItemStack
public int slotOfItemStack(ItemStack stack, InventoryPlayer inv) {
int i;
for (i = 0; i < inv.mainInventory.length; ++i) {
if (inv.mainInventory[i] != null && inv.mainInventory[i].isItemEqual(stack)) {
return i;
}
}
return -1;
}
@Override
public ArrayList<Object> getSpecialParameters() {
return null;
}
@Override
public String getItemName() {
return "prismaticWand";
}
@Override
public boolean shouldRegister() {
return true;
}
@Override
public boolean shouldDisplayInTab() {
return true;
}
@Override
public ThaumicTinkererRecipe getRecipeItem() {
return new CraftingBenchRecipe(new ItemStack(this), " P ", " I ", " I ", 'P', ItemMaterial.getPrism(), 'I', new ItemStack(Items.BLAZE_ROD));
}
@Override
public int getCreativeTabPriority() {
return -25;
}
}