diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/CuboidTag.java b/plugin/src/main/java/com/denizenscript/denizen/objects/CuboidTag.java index d9cb20fe66..6e0d6c9ea0 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/CuboidTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/CuboidTag.java @@ -1084,11 +1084,11 @@ public static void registerTags() { } pair = cuboid.pairs.get(member - 1); } - Location base = pair.high.clone().add(pair.low.clone()).add(1.0, 1.0, 1.0); + LocationTag base = pair.high.clone().add(pair.low).add(1.0, 1.0, 1.0); base.setX(base.getX() / 2.0); base.setY(base.getY() / 2.0); base.setZ(base.getZ() / 2.0); - return new LocationTag(base); + return base; }); // <--[tag] diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/EllipsoidTag.java b/plugin/src/main/java/com/denizenscript/denizen/objects/EllipsoidTag.java index 16abac3ee5..d14a559205 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/EllipsoidTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/EllipsoidTag.java @@ -62,27 +62,21 @@ public static EllipsoidTag valueOf(String string) { */ @Fetchable("ellipsoid") public static EllipsoidTag valueOf(String string, TagContext context) { - if (string.startsWith("ellipsoid@")) { string = string.substring(10); } - Notable noted = NotableManager.getSavedObject(string); if (noted instanceof EllipsoidTag) { return (EllipsoidTag) noted; } - List split = CoreUtilities.split(string, ','); - if (split.size() != 7) { return null; } - WorldTag world = WorldTag.valueOf(split.get(3), false); if (world == null) { return null; } - for (int i = 0; i < 7; i++) { if (i != 3 && !ArgumentHelper.matchesDouble(split.get(i))) { if (context == null || context.debug) { @@ -91,7 +85,6 @@ public static EllipsoidTag valueOf(String string, TagContext context) { } } } - LocationTag location = new LocationTag(world.getWorld(), Double.parseDouble(split.get(0)), Double.parseDouble(split.get(1)), Double.parseDouble(split.get(2))); LocationTag size = new LocationTag(null, Double.parseDouble(split.get(4)), Double.parseDouble(split.get(5)), Double.parseDouble(split.get(6))); return new EllipsoidTag(location, size); @@ -104,7 +97,6 @@ public static EllipsoidTag valueOf(String string, TagContext context) { * @return true if matched, otherwise false */ public static boolean matches(String arg) { - try { return EllipsoidTag.valueOf(arg, CoreUtilities.noDebugContext) != null; } @@ -175,28 +167,13 @@ public List getBlockLocationsUnfiltered() { return locations; } - public List getBlockLocations(Attribute attribute) { - List initial = new CuboidTag(new Location(loc.getWorld(), - loc.getX() - size.getX(), loc.getY() - size.getY(), loc.getZ() - size.getZ()), - new Location(loc.getWorld(), - loc.getX() + size.getX(), loc.getY() + size.getY(), loc.getZ() + size.getZ())) - .getBlocks_internal(null, attribute); - List locations = new ArrayList<>(); - for (LocationTag loc : initial) { - if (contains(loc)) { - locations.add(loc); - } - } - return locations; - } - public boolean contains(Location test) { double xbase = test.getX() - loc.getX(); double ybase = test.getY() - loc.getY(); double zbase = test.getZ() - loc.getZ(); return ((xbase * xbase) / (size.getX() * size.getX()) + (ybase * ybase) / (size.getY() * size.getY()) - + (zbase * zbase) / (size.getZ() * size.getZ()) < 1); + + (zbase * zbase) / (size.getZ() * size.getZ()) <= 1); } String prefix = "ellipsoid"; @@ -258,7 +235,7 @@ public String identifySimple() { } public String identifyFull() { - return "ellipsoid@" + loc.getX() + "," + loc.getY() + "," + loc.getZ() + "," + loc.getWorld().getName() + return "ellipsoid@" + loc.getX() + "," + loc.getY() + "," + loc.getZ() + "," + loc.getWorldName() + "," + size.getX() + "," + size.getY() + "," + size.getZ(); } @@ -342,6 +319,56 @@ public static void registerTags() { return new ElementTag(object.contains(attribute.contextAsType(1, LocationTag.class))); }); + // <--[tag] + // @attribute ]> + // @returns EllipsoidTag + // @description + // Returns a copy of this ellipsoid, with the size value adapted to include the specified world location. + // --> + registerTag("include", (attribute, object) -> { + if (!attribute.hasContext(1)) { + attribute.echoError("ellipsoid.include[...] tag must have an input."); + return null; + } + LocationTag target = attribute.contextAsType(1, LocationTag.class); + if (object.contains(target)) { + return object; + } + LocationTag size = object.size.clone(); + Vector relative = target.toVector().subtract(object.loc.toVector()); + // Cuboid minimum expansion + size.setX(Math.max(size.getX(), Math.abs(relative.getX()))); + size.setY(Math.max(size.getY(), Math.abs(relative.getY()))); + size.setZ(Math.max(size.getZ(), Math.abs(relative.getZ()))); + EllipsoidTag result = new EllipsoidTag(object.loc.clone(), new LocationTag(size)); + if (result.contains(target)) { + return result; + } + double sizeLen = size.length(); + // Ellipsoid additional expand + while (!result.contains(target)) { + // I gave up on figuring out the math for this, so here's an awful loop-hack + double projX = (relative.getX() * relative.getX()) / (size.getX() * size.getX()); + double projY = (relative.getY() * relative.getY()) / (size.getY() * size.getY()); + double projZ = (relative.getZ() * relative.getZ()) / (size.getZ() * size.getZ()); + double scale = Math.max(projX + projY + projZ, sizeLen * 0.01); + if (projX >= projY && projX >= projZ) { + size.setX(size.getX() + scale); + } + else if (projY >= projX && projY >= projZ) { + size.setY(size.getY() + scale); + } + else if (projZ >= projX && projZ >= projY) { + size.setZ(size.getZ() + scale); + } + else { + size = size.add(scale, scale, scale); + } + result.size = size; + } + return result; + }); + // <--[tag] // @attribute ]> // @returns EllipsoidTag 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 ae1a1955d4..dc6f43747a 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/LocationTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/LocationTag.java @@ -591,9 +591,22 @@ public void setYaw(float yaw) { super.setYaw(yaw); } + @Override + public LocationTag add(double x, double y, double z) { + super.add(x, y, z); + return this; + } + @Override public LocationTag add(Location input) { - return new LocationTag(getWorldName(), getX() + input.getX(), getY() + input.getY(), getZ() + input.getZ(), input.getPitch(), input.getYaw()); + super.add(input); + return this; + } + + @Override + public LocationTag multiply(double input) { + super.multiply(input); + return this; } public boolean hasInventory() { @@ -2550,7 +2563,7 @@ else if (attribute.startsWith("unexplored_structure", 2) && attribute.hasContext } } if (LocationTag.matches(attribute.getContext(1))) { - return new LocationTag(object.clone().add(attribute.contextAsType(1, LocationTag.class))); + return object.clone().add(attribute.contextAsType(1, LocationTag.class)); } return null; });