diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/LocationTag.java b/plugin/src/main/java/com/denizenscript/denizen/objects/LocationTag.java index 3d94dee238..db16972309 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/LocationTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/LocationTag.java @@ -412,6 +412,28 @@ public Block getBlockForTag(Attribute attribute) { } } + public Material getBlockTypeForTag(Attribute attribute) { + NMSHandler.getChunkHelper().changeChunkServerThread(getWorld()); + try { + if (getWorld() == null) { + if (!attribute.hasAlternative()) { + Debug.echoError("LocationTag trying to read block, but cannot because no world is specified."); + } + return null; + } + if (!isChunkLoaded()) { + if (!attribute.hasAlternative()) { + Debug.echoError("LocationTag trying to read block, but cannot because the chunk is unloaded. Use the 'chunkload' command to ensure the chunk is loaded."); + } + return null; + } + return super.getBlock().getType(); + } + finally { + NMSHandler.getChunkHelper().restoreServerThread(getWorld()); + } + } + public static BlockState getBlockStateFor(Block block) { return block.getState(); } @@ -1260,12 +1282,18 @@ else if (getBlockForTag(attribute).getType() == Material.FLOWER_POT) { double nx = xzLen * Math.sin(-getYaw() * (Math.PI / 180)); double ny = Math.sin(getPitch() * (Math.PI / 180)); double nz = xzLen * Math.cos(getYaw() * (Math.PI / 180)); - Location location = NMSHandler.getEntityHelper().getImpactNormal(this, new Vector(nx, -ny, nz), range); - if (location != null) { - return new LocationTag(location).getAttribute(attribute.fulfill(1)); + try { + NMSHandler.getChunkHelper().changeChunkServerThread(getWorld()); + Location location = NMSHandler.getEntityHelper().getImpactNormal(this, new Vector(nx, -ny, nz), range); + if (location != null) { + return new LocationTag(location).getAttribute(attribute.fulfill(1)); + } + else { + return null; + } } - else { - return null; + finally { + NMSHandler.getChunkHelper().restoreServerThread(getWorld()); } } @@ -1285,12 +1313,18 @@ else if (getBlockForTag(attribute).getType() == Material.FLOWER_POT) { double nx = xzLen * Math.sin(-getYaw() * (Math.PI / 180)); double ny = Math.sin(getPitch() * (Math.PI / 180)); double nz = xzLen * Math.cos(getYaw() * (Math.PI / 180)); - Location location = NMSHandler.getEntityHelper().rayTraceBlock(this, new Vector(nx, -ny, nz), range); - if (location != null) { - return new LocationTag(location).getBlockLocation().getAttribute(attribute.fulfill(1)); + try { + NMSHandler.getChunkHelper().changeChunkServerThread(getWorld()); + Location location = NMSHandler.getEntityHelper().rayTraceBlock(this, new Vector(nx, -ny, nz), range); + if (location != null) { + return new LocationTag(location).getBlockLocation().getAttribute(attribute.fulfill(1)); + } + else { + return null; + } } - else { - return null; + finally { + NMSHandler.getChunkHelper().restoreServerThread(getWorld()); } } @@ -1310,12 +1344,18 @@ else if (getBlockForTag(attribute).getType() == Material.FLOWER_POT) { double nx = xzLen * Math.sin(-getYaw() * (Math.PI / 180)); double ny = Math.sin(getPitch() * (Math.PI / 180)); double nz = xzLen * Math.cos(getYaw() * (Math.PI / 180)); - Location location = NMSHandler.getEntityHelper().rayTrace(this, new Vector(nx, -ny, nz), range); - if (location != null) { - return new LocationTag(location).getAttribute(attribute.fulfill(1)); + try { + NMSHandler.getChunkHelper().changeChunkServerThread(getWorld()); + Location location = NMSHandler.getEntityHelper().rayTrace(this, new Vector(nx, -ny, nz), range); + if (location != null) { + return new LocationTag(location).getAttribute(attribute.fulfill(1)); + } + else { + return null; + } } - else { - return null; + finally { + NMSHandler.getChunkHelper().restoreServerThread(getWorld()); } } @@ -1367,9 +1407,15 @@ else if (getBlockForTag(attribute).getType() == Material.FLOWER_POT) { range = 100; } ListTag list = new ListTag(); - BlockIterator iterator = new BlockIterator(this, 0, range); - while (iterator.hasNext()) { - list.add(new LocationTag(iterator.next().getLocation()).identify()); + try { + NMSHandler.getChunkHelper().changeChunkServerThread(getWorld()); + BlockIterator iterator = new BlockIterator(this, 0, range); + while (iterator.hasNext()) { + list.add(new LocationTag(iterator.next().getLocation()).identify()); + } + } + finally { + NMSHandler.getChunkHelper().restoreServerThread(getWorld()); } return list.getAttribute(attribute.fulfill(1)); } @@ -1384,8 +1430,14 @@ else if (getBlockForTag(attribute).getType() == Material.FLOWER_POT) { if (attribute.startsWith("line_of_sight") && attribute.hasContext(1)) { LocationTag location = LocationTag.valueOf(attribute.getContext(1)); if (location != null) { - return new ElementTag(NMSHandler.getEntityHelper().canTrace(getWorld(), toVector(), location.toVector())) - .getAttribute(attribute.fulfill(1)); + try { + NMSHandler.getChunkHelper().changeChunkServerThread(getWorld()); + return new ElementTag(NMSHandler.getEntityHelper().canTrace(getWorld(), toVector(), location.toVector())) + .getAttribute(attribute.fulfill(1)); + } + finally { + NMSHandler.getChunkHelper().restoreServerThread(getWorld()); + } } } @@ -1717,7 +1769,7 @@ else if (yaw < 315) { if (Utilities.checkLocation(this, tstart.clone().add(x + 0.5, y + 0.5, z + 0.5), radius)) { if (!materials.isEmpty()) { for (MaterialTag material : materials) { - if (material.hasData() && material.getData() != 0) { // TODO: less arbitrary matching + if (NMSHandler.getVersion().isAtMost(NMSVersion.v1_12) && material.hasData() && material.getData() != 0) { BlockState bs = new LocationTag(tstart.clone().add(x, y, z)).getBlockStateForTag(attribute); if (bs != null && material.matchesMaterialData(bs.getData())) { found.add(new LocationTag(tstart.clone().add(x, y, z))); @@ -2471,7 +2523,16 @@ else if (this.getWorldName().equalsIgnoreCase(toLocation.getWorldName())) { // Returns whether the block at the location is a liquid. // --> if (attribute.startsWith("is_liquid")) { - return new ElementTag(getBlockForTag(attribute).isLiquid()).getAttribute(attribute.fulfill(1)); + Block b = getBlockForTag(attribute); + if (b != null) { + try { + NMSHandler.getChunkHelper().changeChunkServerThread(getWorld()); + return new ElementTag(b.isLiquid()).getAttribute(attribute.fulfill(1)); + } + finally { + NMSHandler.getChunkHelper().restoreServerThread(getWorld()); + } + } } @@ -2484,8 +2545,17 @@ else if (this.getWorldName().equalsIgnoreCase(toLocation.getWorldName())) { // --> if (attribute.startsWith("light.from_blocks") || attribute.startsWith("light.blocks")) { - return new ElementTag(getBlockForTag(attribute).getLightFromBlocks()) - .getAttribute(attribute.fulfill(2)); + Block b = getBlockForTag(attribute); + if (b != null) { + try { + NMSHandler.getChunkHelper().changeChunkServerThread(getWorld()); + return new ElementTag(getBlockForTag(attribute).getLightFromBlocks()) + .getAttribute(attribute.fulfill(2)); + } + finally { + NMSHandler.getChunkHelper().restoreServerThread(getWorld()); + } + } } // <--[tag] @@ -2497,8 +2567,17 @@ else if (this.getWorldName().equalsIgnoreCase(toLocation.getWorldName())) { // --> if (attribute.startsWith("light.from_sky") || attribute.startsWith("light.sky")) { - return new ElementTag(getBlockForTag(attribute).getLightFromSky()) - .getAttribute(attribute.fulfill(2)); + Block b = getBlockForTag(attribute); + if (b != null) { + try { + NMSHandler.getChunkHelper().changeChunkServerThread(getWorld()); + return new ElementTag(getBlockForTag(attribute).getLightFromSky()) + .getAttribute(attribute.fulfill(2)); + } + finally { + NMSHandler.getChunkHelper().restoreServerThread(getWorld()); + } + } } // <--[tag] @@ -2508,8 +2587,17 @@ else if (this.getWorldName().equalsIgnoreCase(toLocation.getWorldName())) { // Returns the total amount of light on the location. // --> if (attribute.startsWith("light")) { - return new ElementTag(getBlockForTag(attribute).getLightLevel()) - .getAttribute(attribute.fulfill(1)); + Block b = getBlockForTag(attribute); + if (b != null) { + try { + NMSHandler.getChunkHelper().changeChunkServerThread(getWorld()); + return new ElementTag(getBlockForTag(attribute).getLightLevel()) + .getAttribute(attribute.fulfill(1)); + } + finally { + NMSHandler.getChunkHelper().restoreServerThread(getWorld()); + } + } } // <--[tag] @@ -2519,8 +2607,17 @@ else if (this.getWorldName().equalsIgnoreCase(toLocation.getWorldName())) { // Returns the current redstone power level of a block. // --> if (attribute.startsWith("power")) { - return new ElementTag(getBlockForTag(attribute).getBlockPower()) - .getAttribute(attribute.fulfill(1)); + Block b = getBlockForTag(attribute); + if (b != null) { + try { + NMSHandler.getChunkHelper().changeChunkServerThread(getWorld()); + return new ElementTag(getBlockForTag(attribute).getBlockPower()) + .getAttribute(attribute.fulfill(1)); + } + finally { + NMSHandler.getChunkHelper().restoreServerThread(getWorld()); + } + } } // <--[tag] diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/PlayerTag.java b/plugin/src/main/java/com/denizenscript/denizen/objects/PlayerTag.java index 29f753ee41..c5d0277397 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/PlayerTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/PlayerTag.java @@ -925,47 +925,53 @@ else if (CoreUtilities.toLowerCase(obj.toString()).equals("npc")) { } } - // Find the valid target - BlockIterator bi; try { - bi = new BlockIterator(getPlayerEntity(), range); - } - catch (IllegalStateException e) { - return null; - } - Block b; - Location l; - int bx, by, bz; - double ex, ey, ez; - - // Loop through player's line of sight - while (bi.hasNext()) { - b = bi.next(); - bx = b.getX(); - by = b.getY(); - bz = b.getZ(); - - if (b.getType().isSolid()) { - // Line of sight is broken - break; + NMSHandler.getChunkHelper().changeChunkServerThread(getWorld()); + // Find the valid target + BlockIterator bi; + try { + bi = new BlockIterator(getPlayerEntity(), range); } - else { - // Check for entities near this block in the line of sight - for (LivingEntity possibleTarget : possibleTargets) { - l = possibleTarget.getLocation(); - ex = l.getX(); - ey = l.getY(); - ez = l.getZ(); - - if ((bx - .50 <= ex && ex <= bx + 1.50) && - (bz - .50 <= ez && ez <= bz + 1.50) && - (by - 1 <= ey && ey <= by + 2.5)) { - // Entity is close enough, so return it - return new EntityTag(possibleTarget).getDenizenObject().getAttribute(attribute.fulfill(attribs)); + catch (IllegalStateException e) { + return null; + } + Block b; + Location l; + int bx, by, bz; + double ex, ey, ez; + + // Loop through player's line of sight + while (bi.hasNext()) { + b = bi.next(); + bx = b.getX(); + by = b.getY(); + bz = b.getZ(); + + if (b.getType().isSolid()) { + // Line of sight is broken + break; + } + else { + // Check for entities near this block in the line of sight + for (LivingEntity possibleTarget : possibleTargets) { + l = possibleTarget.getLocation(); + ex = l.getX(); + ey = l.getY(); + ez = l.getZ(); + + if ((bx - .50 <= ex && ex <= bx + 1.50) && + (bz - .50 <= ez && ez <= bz + 1.50) && + (by - 1 <= ey && ey <= by + 2.5)) { + // Entity is close enough, so return it + return new EntityTag(possibleTarget).getDenizenObject().getAttribute(attribute.fulfill(attribs)); + } } } } } + finally { + NMSHandler.getChunkHelper().restoreServerThread(getWorld()); + } return null; }