diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/async/rotation/RotationTask.java b/Movecraft/src/main/java/net/countercraft/movecraft/async/rotation/RotationTask.java index 327e9e86c..9676dcd32 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/async/rotation/RotationTask.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/async/rotation/RotationTask.java @@ -51,6 +51,7 @@ import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.InventoryView; +import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -270,7 +271,8 @@ private void rotateEntitiesOnCraft(Location tOP) { (oldHitBox.getMaxY() + oldHitBox.getMinY())/2.0, (oldHitBox.getMaxZ() + oldHitBox.getMinZ())/2.0); - List entityList = List.of(EntityType.PLAYER, EntityType.PRIMED_TNT); + EnumSet entityList = EnumSet.of(EntityType.PLAYER, EntityType.PRIMED_TNT); + EnumSet shouldBeProcessed = (EnumSet) craft.getType().getObjectProperty(CraftType.MOVE_ENTITIES_LIST); for(Entity entity : craft.getWorld().getNearbyEntities(midpoint, oldHitBox.getXLength() / 2.0 + 1, oldHitBox.getYLength() / 2.0 + 2, @@ -284,6 +286,10 @@ private void rotateEntitiesOnCraft(Location tOP) { continue; }// Player is onboard this craft + if(!shouldBeProcessed.contains(entity)) { + continue; + } + Location adjustedPLoc = entity.getLocation().subtract(tOP); double[] rotatedCoords = MathUtils.rotateVecNoRound(rotation, diff --git a/Movecraft/src/main/java/net/countercraft/movecraft/async/translation/TranslationTask.java b/Movecraft/src/main/java/net/countercraft/movecraft/async/translation/TranslationTask.java index d1d23459f..29923830c 100644 --- a/Movecraft/src/main/java/net/countercraft/movecraft/async/translation/TranslationTask.java +++ b/Movecraft/src/main/java/net/countercraft/movecraft/async/translation/TranslationTask.java @@ -360,6 +360,8 @@ private void preventsTorpedoRocketsPilots() { (oldHitBox.getMaxX() + oldHitBox.getMinX()) / 2.0, (oldHitBox.getMaxY() + oldHitBox.getMinY()) / 2.0, (oldHitBox.getMaxZ() + oldHitBox.getMinZ()) / 2.0); + + EnumSet shouldBeProcessed = (EnumSet) craft.getType().getObjectProperty(CraftType.MOVE_ENTITIES_LIST); for (Entity entity : craft.getWorld().getNearbyEntities(midpoint, oldHitBox.getXLength() / 2.0 + 1, oldHitBox.getYLength() / 2.0 + 2, @@ -385,6 +387,10 @@ private void preventsTorpedoRocketsPilots() { continue; } + if (!shouldBeProcessed.contains(entity)) { + continue; + } + CraftTeleportEntityEvent e = new CraftTeleportEntityEvent(craft, entity); Bukkit.getServer().getPluginManager().callEvent(e); if (e.isCancelled()) diff --git a/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java b/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java index d0f66b287..06b243101 100644 --- a/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java +++ b/api/src/main/java/net/countercraft/movecraft/craft/type/CraftType.java @@ -44,6 +44,7 @@ import net.kyori.adventure.key.Key; import net.kyori.adventure.sound.Sound; import org.bukkit.*; +import org.bukkit.entity.EntityType; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -155,6 +156,7 @@ final public class CraftType { public static final NamespacedKey CAN_HOVER = buildKey("can_hover"); public static final NamespacedKey CAN_HOVER_OVER_WATER = buildKey("can_hover_over_water"); public static final NamespacedKey MOVE_ENTITIES = buildKey("move_entities"); + public static final NamespacedKey MOVE_ENTITIES_LIST = buildKey("move_entities_list"); public static final NamespacedKey ONLY_MOVE_PLAYERS = buildKey("only_move_players"); public static final NamespacedKey USE_GRAVITY = buildKey("use_gravity"); public static final NamespacedKey HOVER_LIMIT = buildKey("hover_limit"); @@ -495,6 +497,16 @@ public static void registerTypeValidator(Predicate validator, String registerProperty(new BooleanProperty("canHover", CAN_HOVER, type -> false)); registerProperty(new BooleanProperty("canHoverOverWater", CAN_HOVER_OVER_WATER, type -> true)); registerProperty(new BooleanProperty("moveEntities", MOVE_ENTITIES, type -> true)); + registerProperty(new ObjectPropertyImpl("moveEntitiesList", MOVE_ENTITIES_LIST, + (data, type, fileKey, namespacedKey) -> { + var entityStringList = data.getStringList(fileKey); + EnumSet entityList = EnumSet.noneOf(EntityType.class); + for (String entityString : entityStringList) { + entityList.addAll(Tags.parseEntities(entityString)); + } + + return entityList; + }, type -> EnumSet.noneOf(EntityType.class))); registerProperty(new BooleanProperty("onlyMovePlayers", ONLY_MOVE_PLAYERS, type -> true)); registerProperty(new BooleanProperty("useGravity", USE_GRAVITY, type -> false)); registerProperty(new IntegerProperty("hoverLimit", HOVER_LIMIT, type -> 0)); diff --git a/api/src/main/java/net/countercraft/movecraft/util/Tags.java b/api/src/main/java/net/countercraft/movecraft/util/Tags.java index 399ebb92a..ad4be51ae 100644 --- a/api/src/main/java/net/countercraft/movecraft/util/Tags.java +++ b/api/src/main/java/net/countercraft/movecraft/util/Tags.java @@ -5,6 +5,7 @@ import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.Tag; +import org.bukkit.entity.EntityType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -135,4 +136,40 @@ public static EnumSet parseMaterials(@NotNull String materialName) { } return returnSet; } + + @Nullable + public static EnumSet parseEntityRegistry(@NotNull String string) { + if (!string.startsWith("#")) + return null; + + String nameKey = string.substring(1); + var key = keyFromString(nameKey); + if (key == null) + throw new IllegalArgumentException("Entry " + string + " is not a valid namespace key!"); + + var tag = Bukkit.getTag(Tag.REGISTRY_ENTITY_TYPES, key, EntityType.class); + if (tag == null) + throw new IllegalArgumentException("Entry " + string + " is not a valid tag!"); + + var tags = tag.getValues(); + return tags.isEmpty() ? EnumSet.noneOf(EntityType.class) : EnumSet.copyOf(tags); + } + + /** + * Searches for a tag which matches the provided entityName. Failing that, it attempts to load a matching singular EntityType directly. + * + * @param entityName EntityType name or tag + * @return the set of EntityType the tag/EntityType resolves to + */ + @NotNull + public static EnumSet parseEntities(@NotNull String entityName) { + EnumSet returnSet = EnumSet.noneOf(EntityType.class); + EnumSet tagged = parseEntityRegistry(entityName); + if (tagged != null) { + returnSet.addAll(tagged); + } else { + returnSet.add(EntityType.valueOf(entityName.toUpperCase())); + } + return returnSet; + } } diff --git a/datapack/src/main/resources/movecraft-data/data/minecraft/tags/entity_types/hostiles.json b/datapack/src/main/resources/movecraft-data/data/minecraft/tags/entity_types/hostiles.json new file mode 100644 index 000000000..213b941da --- /dev/null +++ b/datapack/src/main/resources/movecraft-data/data/minecraft/tags/entity_types/hostiles.json @@ -0,0 +1,3 @@ +{ + "values": ["elder_guardian", "wither_skeleton", "stray", "husk", "zombie_villager", "evoker", "vex", "vindicator", "illusioner", "creeper", "skeleton", "spider", "giant", "zombie", "zombified_piglin", "enderman", "cave_spider", "silverfish", "blaze", "wither", "witch", "endermite", "guardian", "drowned", "pillager", "ravager", "piglin", "zoglin", "piglin_brute", "warden", "breeze", "bogged"] +} \ No newline at end of file