public void lookAtPoint(final Location point) { if (this.getEntity().getBukkitEntity().getWorld() != point.getWorld()) return; final Location npcLoc = ((LivingEntity) this.getEntity().getBukkitEntity()).getEyeLocation(); final double xDiff = point.getX() - npcLoc.getX(); final double yDiff = point.getY() - npcLoc.getY(); final double zDiff = point.getZ() - npcLoc.getZ(); final double DistanceXZ = Math.sqrt(xDiff * xDiff + zDiff * zDiff); final double DistanceY = Math.sqrt(DistanceXZ * DistanceXZ + yDiff * yDiff); double newYaw = Math.acos(xDiff / DistanceXZ) * 180 / Math.PI; final double newPitch = Math.acos(yDiff / DistanceY) * 180 / Math.PI - 90; if (zDiff < 0.0) newYaw = newYaw + Math.abs(180 - newYaw) * 2; this.setYaw((float) (newYaw - 90)); this.setPitch((float) newPitch); }
public void performMimic(Player p, int radius, boolean sphere) { int freqArray[][] = new int[200][16]; // holder for counts of each blocktype, and 15 durability levels for wool // get player location Location location = p.getLocation(); int xPos = location.getBlockX(); int yPos = -1; if (location.getBlockY() - (int) radius / 5 > 0) { // this is a hemisphere the top half of a sphere. This makes it positioned so you // still get some blocks a little below you. yPos = location.getBlockY() - (int) radius / 5; } else { yPos = location.getBlockY(); // in case player is just barely above bedrock } int zPos = location.getBlockZ(); Inventory inv = p.getInventory(); int data = 0; // may want to then use getContents which gives a whole array if stacks, then setContents. // get block type frequency within a hemisphere for (int x = radius; x >= 0; x--) { double xPow = Math.pow(x, 2); for (int y = radius; y >= 0; y--) { double yPow = Math.pow(y, 2); for (int z = radius; z >= 0; z--) { if (xPow + yPow + Math.pow(z, 2) <= Math.pow(radius + 0.5, 2)) { data = (w.getBlockAt(xPos + x, yPos + y, zPos + z).getData()); if (data > 15) { data = 15; } freqArray[w.getBlockTypeIdAt(xPos + x, yPos + y, zPos + z)][data]++; data = (w.getBlockAt(xPos + x, yPos + y, zPos - z).getData()); if (data > 15) { data = 15; } freqArray[w.getBlockTypeIdAt(xPos + x, yPos + y, zPos - z)][data]++; if (sphere) { data = (w.getBlockAt(xPos + x, yPos - y, zPos + z).getData()); if (data > 15) { data = 15; } freqArray[w.getBlockTypeIdAt(xPos + x, yPos - y, zPos + z)][ data]++; // uncomment for full sphere version. data = (w.getBlockAt(xPos + x, yPos - y, zPos - z).getData()); if (data > 15) { data = 15; } freqArray[w.getBlockTypeIdAt(xPos + x, yPos - y, zPos - z)][data]++; } data = (w.getBlockAt(xPos - x, yPos + y, zPos + z).getData()); if (data > 15) { data = 15; } freqArray[w.getBlockTypeIdAt(xPos - x, yPos + y, zPos + z)][data]++; data = (w.getBlockAt(xPos - x, yPos + y, zPos - z).getData()); if (data > 15) { data = 15; } freqArray[w.getBlockTypeIdAt(xPos - x, yPos + y, zPos - z)][data]++; if (sphere) { data = (w.getBlockAt(xPos - x, yPos - y, zPos + z).getData()); if (data > 15) { data = 15; } freqArray[w.getBlockTypeIdAt(xPos - x, yPos - y, zPos + z)][data]++; data = (w.getBlockAt(xPos - x, yPos - y, zPos - z).getData()); if (data > 15) { data = 15; } freqArray[w.getBlockTypeIdAt(xPos - x, yPos - y, zPos - z)][data]++; } } } } } for (int k = 0; k <= 199; k++) { // ignore anything specified on config file. By default, some common natural stuff, // and explosives and things. if (unmimicable.contains(k)) { for (int l = 0; l <= 15; l++) { freqArray[k][l] = 0; } } } int sum = 0; for (int k = 0; k <= 199; k++) { // only one data value type for anything whose data value is irrelevant to inventory // (like torches) if (k == 66 || k == 18 || k == 84 || k == 61 || k == 62 || k == 55 || k == 92 || k == 8 || k == 10 || k == 23 || k == 25 || k == 26 || k == 46 || k == 50 || k == 51 || k == 52 || k == 53 || k == 54 || k == 63 || k == 64 || k == 65 || k == 67 || k == 68 || k == 69 || k == 71 || k == 75 || k == 76 || k == 77 || k == 85 || k == 86 || k == 91 || k == 93 || k == 94 || k == 90 || k == 70 || k == 72 || k == 96) { sum = 0; for (int l = 0; l <= 15; l++) { sum = sum + freqArray[k][l]; freqArray[k][l] = 0; } freqArray[k][0] = sum; } } int max = 0; int winnerA = 0; int winnerB = 0; boolean keepLooking = true; int replaced = 0; int existId; int existDur; boolean[][] skipThis = new boolean[200] [36]; // don't give item types you already have in your inventory. first dim = item id // type, second dim = data value for (int r = 1; r <= 36; r++) { ItemStack stack = inv.getItem(r); existId = (stack == null) ? 0 : stack.getTypeId(); existDur = (stack == null) ? 0 : stack.getDurability(); switch (existId) { // if you have a door item in inventory, don't mimic door BLOCKS, etc. case 331: skipThis[55][0] = true; break; case 323: skipThis[63][0] = true; skipThis[68][0] = true; break; case 324: skipThis[64][0] = true; break; case 330: skipThis[71][0] = true; break; case 338: skipThis[83][0] = true; break; } if (existId < 200 && existId > 0) { if (existDur < 16 && existDur > -1) { skipThis[existId][existDur] = true; } } } for (int index = 0; index <= 17; index++) { // will only replace first two lines of your backpack. max = 0; winnerA = 0; winnerB = 0; if (keepLooking) { for (int j = 0; j <= 199; j++) { // find current maximum / most popular block type in array for (int m = 0; m <= 15; m++) { if (freqArray[j][m] > max && !skipThis[j][m]) { max = freqArray[j][m]; winnerA = j; winnerB = m; freqArray[j][m] = 0; // this should fix the looping problem of last build } else if (skipThis[j][m]) { freqArray[j][m] = 0; } } } } if (winnerA != 0) { // if winnerA == 0, then that means we are out of new block types that were found // during the scan, so stop messing with the inventory. ItemStack stack = inv.getItem(index + 9); // get the stack from inventory we are at right now. if (stack != null) { stack.setTypeId(winnerA); } else { stack = new ItemStack(winnerA); } // makes it a stack of the popular type. if (winnerA == 55) { stack.setTypeId(331); } // changing various things that should be items instead of blocks. if (winnerA == 63 || winnerA == 68) { stack.setTypeId(323); } if (winnerA == 64) { stack.setTypeId(324); } if (winnerA == 71) { stack.setTypeId(330); } if (winnerA == 83) { stack.setTypeId(338); } stack.setAmount(64); // make it a full stack. // MaterialData matData = new MaterialData(winnerB); //Okay, this is supposed to create a // new materialdata type of a certain data value. winnerB will be 5, for instance, for // light green wool. stack.setDurability( (short) winnerB); // then it should set the stack to that data value. Unfortunately, there // is only a method here for a full materialdata object, not just an // integer GRR inv.setItem(index + 9, stack); // put new stack back into current slot. freqArray[winnerA][winnerB] = 0; // clear out that winner so we will get the next most popular next time. if (index == 17) { replaced = 18; // handles end case; } } else { if (keepLooking) { replaced = index; } keepLooking = false; } } p.sendMessage( ChatColor.LIGHT_PURPLE + "Environment mimicked in inventory. " + replaced + " stack(s) given (max: 18)."); }