From f70d5e604c22071633cbb2ac488eadc694a48515 Mon Sep 17 00:00:00 2001 From: Alex 'mcmonkey' Goodwin Date: Fri, 15 Jan 2021 02:56:36 -0800 Subject: [PATCH] add location random tag trio --- .../denizen/objects/CuboidTag.java | 19 +++++++++++ .../denizen/objects/EllipsoidTag.java | 23 +++++++++++++ .../denizen/objects/EntityTag.java | 2 +- .../denizen/objects/LocationTag.java | 33 +++++++++++++++++++ 4 files changed, 76 insertions(+), 1 deletion(-) 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 5370a29d29..b0b80f8219 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/CuboidTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/CuboidTag.java @@ -1,6 +1,7 @@ package com.denizenscript.denizen.objects; import com.denizenscript.denizen.objects.notable.NotableManager; +import com.denizenscript.denizen.utilities.Utilities; import com.denizenscript.denizen.utilities.debugging.Debug; import com.denizenscript.denizen.utilities.depends.Depends; import com.denizenscript.denizencore.objects.*; @@ -756,6 +757,24 @@ public String toString() { public static void registerTags() { + // <--[tag] + // @attribute + // @returns LocationTag + // @description + // Returns a random block location within the cuboid. + // (Note: random selection will not be fairly weighted for multi-member cuboids). + // --> + registerTag("random", (attribute, cuboid) -> { + LocationPair pair = cuboid.pairs.get(CoreUtilities.getRandom().nextInt(cuboid.pairs.size())); + Vector range = pair.high.toVector().subtract(pair.low.toVector()).add(new Vector(1, 1, 1)); + range.setX(CoreUtilities.getRandom().nextInt(range.getBlockX())); + range.setY(CoreUtilities.getRandom().nextInt(range.getBlockY())); + range.setZ(CoreUtilities.getRandom().nextInt(range.getBlockZ())); + LocationTag out = pair.low.clone(); + out.add(range); + return out; + }); + // <--[tag] // @attribute |...)]> // @returns ListTag(LocationTag) 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 6aef1d7335..08ed5cb75b 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/EllipsoidTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/EllipsoidTag.java @@ -361,6 +361,29 @@ public ObjectTag setPrefix(String prefix) { public static void registerTags() { + // <--[tag] + // @attribute + // @returns LocationTag + // @description + // Returns a random decimal location within the ellipsoid. + // Note that distribution of results will not be completely even. + // --> + registerTag("random", (attribute, object) -> { + // This is an awkward hack to try to weight towards the center a bit (to counteract the weight-away-from-center that would otherwise happen). + double y = Math.sqrt((CoreUtilities.getRandom().nextDouble() * 2 - 1) * (object.size.getY() * object.size.getY())); + Vector result = new Vector(); + result.setY(y); + double yProg = Math.abs(y) / object.size.getY(); + double subWidth = Math.sqrt(1.0 - yProg * yProg); + double maxX = object.size.getX() * subWidth; + double maxZ = object.size.getZ() * subWidth; + result.setX(maxX * (CoreUtilities.getRandom().nextDouble() * 2 - 1)); + result.setZ(maxZ * (CoreUtilities.getRandom().nextDouble() * 2 - 1)); + LocationTag out = object.center.clone(); + out.add(result); + return out; + }); + // <--[tag] // @attribute |...]> // @returns ListTag(LocationTag) diff --git a/plugin/src/main/java/com/denizenscript/denizen/objects/EntityTag.java b/plugin/src/main/java/com/denizenscript/denizen/objects/EntityTag.java index 8a0e1bbca2..55ce2b6453 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/EntityTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/EntityTag.java @@ -75,7 +75,7 @@ public class EntityTag implements ObjectTag, Adjustable, EntityFormObject, Flagg // List a mechanism here if it can be safely run before spawn. public static HashSet earlyValidMechanisms = new HashSet<>(Arrays.asList( "max_health", "health_data", "health", "visible", - "armor_pose", "arms", "base_plate", "is_small", + "armor_pose", "arms", "base_plate", "is_small", "marker", "velocity", "age", "is_using_riptide" )); 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 bf9654bd3a..6a7b2e6bdd 100644 --- a/plugin/src/main/java/com/denizenscript/denizen/objects/LocationTag.java +++ b/plugin/src/main/java/com/denizenscript/denizen/objects/LocationTag.java @@ -1073,6 +1073,39 @@ public static void registerTags() { return new LocationTag(object.getWorld(), object.getBlockX() + 0.5, object.getBlockY() + 0.5, object.getBlockZ() + 0.5); }); + // <--[tag] + // @attribute ]> + // @returns LocationTag + // @description + // Returns a copy of this location, with the X/Y/Z offset by a random decimal value up to a given limit. + // The limit can either be an X,Y,Z location vector like [3,1,3] or a single value like [3] (which is equivalent to [3,3,3]). + // For example, for a location at 0,100,0, ".random_offset[1,2,3]" can return any decimal location within the cuboid from -1,98,-3 to 1,102,3. + // --> + registerTag("random_offset", (attribute, object) -> { + if (!attribute.hasContext(1)) { + attribute.echoError("LocationTag.random_offset[...] must have an input."); + return null; + } + Vector offsetLimit; + if (ArgumentHelper.matchesDouble(attribute.getContext(1))) { + double val = attribute.getDoubleContext(1); + offsetLimit = new Vector(val, val, val); + } + else { + LocationTag val = attribute.contextAsType(1, LocationTag.class); + if (val == null) { + return null; + } + offsetLimit = val.toVector(); + } + offsetLimit.setX(offsetLimit.getX() * (CoreUtilities.getRandom().nextDouble() * 2 - 1)); + offsetLimit.setY(offsetLimit.getY() * (CoreUtilities.getRandom().nextDouble() * 2 - 1)); + offsetLimit.setZ(offsetLimit.getZ() * (CoreUtilities.getRandom().nextDouble() * 2 - 1)); + LocationTag output = object.clone(); + output.add(offsetLimit); + return output; + }); + // <--[tag] // @attribute // @returns LocationTag