From 8255e00b95440bc1de71b9b3fd8d75c99dcf73a7 Mon Sep 17 00:00:00 2001 From: CJH3139 Date: Fri, 17 Apr 2026 01:38:30 -0700 Subject: [PATCH 1/2] Add support for non mob/player entities in EffLook --- .../skript/bukkitutil/PaperEntityUtils.java | 13 ++++++++ .../java/ch/njol/skript/effects/EffLook.java | 32 ++++++++++++------- .../skript/bukkit/entity/EntityModule.java | 2 ++ 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/main/java/ch/njol/skript/bukkitutil/PaperEntityUtils.java b/src/main/java/ch/njol/skript/bukkitutil/PaperEntityUtils.java index b488fcbc9a7..cf1e3d1761b 100644 --- a/src/main/java/ch/njol/skript/bukkitutil/PaperEntityUtils.java +++ b/src/main/java/ch/njol/skript/bukkitutil/PaperEntityUtils.java @@ -107,6 +107,19 @@ public static void lookAt(LookAnchor entityAnchor, Object target, @Nullable Floa } } else if (entity instanceof Mob) { mobLookAt(target, headRotationSpeed, maxHeadPitch, (Mob) entity); + } else { + if (target instanceof Vector vector) { + Location loc = entity.getEyeLocation().add(vector); + entity.lookAt(loc.getX(), loc.getY(), loc.getZ(), entityAnchor); + } else if (target instanceof LivingEntity targetEntity) { + Location loc = entityAnchor == LookAnchor.EYES ? targetEntity.getEyeLocation() : targetEntity.getLocation(); + entity.lookAt(loc.getX(), loc.getY(), loc.getZ(), entityAnchor); + } else if (target instanceof Entity targetEntity) { + Location loc = targetEntity.getLocation(); + entity.lookAt(loc.getX(), loc.getY(), loc.getZ(), entityAnchor); + } else if (target instanceof Location location) { + entity.lookAt(location.getX(), location.getY(), location.getZ(), entityAnchor); + } } } } diff --git a/src/main/java/ch/njol/skript/effects/EffLook.java b/src/main/java/ch/njol/skript/effects/EffLook.java index c082e48313c..cedfb46ac68 100644 --- a/src/main/java/ch/njol/skript/effects/EffLook.java +++ b/src/main/java/ch/njol/skript/effects/EffLook.java @@ -1,6 +1,5 @@ package ch.njol.skript.effects; -import ch.njol.skript.Skript; import ch.njol.skript.bukkitutil.PaperEntityUtils; import ch.njol.skript.doc.Description; import ch.njol.skript.doc.Example; @@ -14,9 +13,11 @@ import org.bukkit.entity.LivingEntity; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; +import org.skriptlang.skript.registration.SyntaxInfo; +import org.skriptlang.skript.registration.SyntaxRegistry; @Name("Look At") -@Description("Forces the mob(s) or player(s) to look at an entity, vector or location. Vanilla max head pitches range from 10 to 50.") +@Description("Forces living entities to look at an entity, vector or location. Vanilla max head pitches range from 10 to 50.") @Example("force the player to look towards event-entity's feet") @Example(""" on entity explosion: @@ -29,18 +30,25 @@ @Since("2.7") public class EffLook extends Effect { - static { - Skript.registerEffect(EffLook.class, - "(force|make) %livingentities% [to] (face [towards]|look [(at|towards)]) " + - "%entity%'s (feet:feet|eyes) [(at|with) [head] [rotation] speed %-number%] " + - "[[and] max[imum] [head] pitch %-number%]", + public static void register(SyntaxRegistry registry) { + registry.register( + SyntaxRegistry.EFFECT, + SyntaxInfo.builder(EffLook.class) + .addPatterns( + "(force|make) %livingentities% [to] (face [towards]|look [(at|towards)]) " + + "%entity%'s (feet:feet|eyes) [(at|with) [head] [rotation] speed %-number%] " + + "[[and] max[imum] [head] pitch %-number%]", - "(force|make) %livingentities% [to] (face [towards]|look [(at|towards)]) " + - "[the] (feet:feet|eyes) of %entity% [(at|with) [head] [rotation] speed %-number%] " + - "[[and] max[imum] [head] pitch %-number%]", + "(force|make) %livingentities% [to] (face [towards]|look [(at|towards)]) " + + "[the] (feet:feet|eyes) of %entity% [(at|with) [head] [rotation] speed %-number%] " + + "[[and] max[imum] [head] pitch %-number%]", - "(force|make) %livingentities% [to] (face [towards]|look [(at|towards)]) %vector/location/entity% " + - "[(at|with) [head] [rotation] speed %-number%] [[and] max[imum] [head] pitch %-number%]"); + "(force|make) %livingentities% [to] (face [towards]|look [(at|towards)]) %vector/location/entity% " + + "[(at|with) [head] [rotation] speed %-number%] [[and] max[imum] [head] pitch %-number%]" + ) + .supplier(EffLook::new) + .build() + ); } private LookAnchor anchor = LookAnchor.EYES; diff --git a/src/main/java/org/skriptlang/skript/bukkit/entity/EntityModule.java b/src/main/java/org/skriptlang/skript/bukkit/entity/EntityModule.java index 5e07c604ed6..871201db18e 100644 --- a/src/main/java/org/skriptlang/skript/bukkit/entity/EntityModule.java +++ b/src/main/java/org/skriptlang/skript/bukkit/entity/EntityModule.java @@ -1,6 +1,7 @@ package org.skriptlang.skript.bukkit.entity; import ch.njol.skript.Skript; +import ch.njol.skript.effects.EffLook; import ch.njol.skript.entity.SimpleEntityData; import org.bukkit.entity.AbstractNautilus; import org.skriptlang.skript.addon.AddonModule; @@ -38,6 +39,7 @@ protected void loadSelf(SkriptAddon addon) { } register(addon, + EffLook::register, ExprDeathMessage::register ); } From e1fc6dedac9c37febc7e1a948b89e38a78e58163 Mon Sep 17 00:00:00 2001 From: CJH3139 Date: Fri, 17 Apr 2026 09:42:54 -0700 Subject: [PATCH 2/2] Change from livingentities -> entities --- .../skript/bukkitutil/PaperEntityUtils.java | 51 +++++++++---------- .../java/ch/njol/skript/effects/EffLook.java | 14 ++--- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/src/main/java/ch/njol/skript/bukkitutil/PaperEntityUtils.java b/src/main/java/ch/njol/skript/bukkitutil/PaperEntityUtils.java index cf1e3d1761b..c1efab8f0e2 100644 --- a/src/main/java/ch/njol/skript/bukkitutil/PaperEntityUtils.java +++ b/src/main/java/ch/njol/skript/bukkitutil/PaperEntityUtils.java @@ -41,32 +41,32 @@ private static void mobLookAt(Object target, @Nullable Float headRotationSpeed, /** * Instruct a Mob (1.17+) to look at a specific vector/location/entity. * Object can be a {@link org.bukkit.util.Vector}, {@link org.bukkit.Location} or {@link org.bukkit.entity.Entity} - * - * @param target The vector/location/entity to make the livingentity look at. - * @param entities The living entities to make look at something. + * + * @param target The vector/location/entity to make the entity look at. + * @param entities The entities to make look at something. */ - public static void lookAt(Object target, LivingEntity... entities) { + public static void lookAt(Object target, Entity... entities) { lookAt(target, null, null, entities); } /** * Instruct a Mob (1.17+) to look at a specific vector/location/entity. * Object can be a {@link org.bukkit.util.Vector}, {@link org.bukkit.Location} or {@link org.bukkit.entity.Entity} - * - * @param target The vector/location/entity to make the livingentity look at. - * @param headRotationSpeed The rotation speed at which the living entities will rotate their head to the target. Vanilla default values range from 10-50. Doesn't apply to players. + * + * @param target The vector/location/entity to make the entity look at. + * @param headRotationSpeed The rotation speed at which the entities will rotate their head to the target. Vanilla default values range from 10-50. Doesn't apply to players. * @param maxHeadPitch The maximum pitch at which the eyes/feet can go to. Doesn't apply to players. - * @param entities The living entities to make look at something. + * @param entities The entities to make look at something. */ - public static void lookAt(Object target, @Nullable Float headRotationSpeed, @Nullable Float maxHeadPitch, LivingEntity... entities) { + public static void lookAt(Object target, @Nullable Float headRotationSpeed, @Nullable Float maxHeadPitch, Entity... entities) { if (target == null || !LOOK_AT) return; // Use support for players if using Paper 1.19.1+ if (LOOK_ANCHORS) { - lookAt(LookAnchor.EYES, headRotationSpeed, maxHeadPitch, entities); + lookAt(LookAnchor.EYES, target, headRotationSpeed, maxHeadPitch, entities); return; } - for (LivingEntity entity : entities) { + for (Entity entity : entities) { if (!(entity instanceof Mob)) continue; mobLookAt(target, headRotationSpeed, maxHeadPitch, (Mob) entity); @@ -76,26 +76,24 @@ public static void lookAt(Object target, @Nullable Float headRotationSpeed, @Nul /** * Instruct a Mob (1.17+) or Players (1.19.1+) to look at a specific vector/location/entity. * Object can be a {@link org.bukkit.util.Vector}, {@link org.bukkit.Location} or {@link org.bukkit.entity.Entity} - * THIS METHOD IS FOR 1.19.1+ ONLY. Use {@link lookAt(Object, Float, Float, LivingEntity...)} otherwise. - * - * @param entityAnchor What part of the entity the player should face assuming the LivingEntity argument contains a player. Only for players. - * @param target The vector/location/entity to make the livingentity or player look at. - * @param headRotationSpeed The rotation speed at which the living entities will rotate their head to the target. Vanilla default values range from 10-50. Doesn't apply to players. + * THIS METHOD IS FOR 1.19.1+ ONLY. Use {@link lookAt(Object, Float, Float, Entity...)} otherwise. + * + * @param entityAnchor What part of the entity the player should face assuming the entities argument contains a player. Only for players. + * @param target The vector/location/entity to make the entity or player look at. + * @param headRotationSpeed The rotation speed at which the entities will rotate their head to the target. Vanilla default values range from 10-50. Doesn't apply to players. * @param maxHeadPitch The maximum pitch at which the eyes/feet can go to. Doesn't apply to players. - * @param entities The living entities to make look at something. Players can be involved in 1.19.1+ + * @param entities The entities to make look at something. */ - public static void lookAt(LookAnchor entityAnchor, Object target, @Nullable Float headRotationSpeed, @Nullable Float maxHeadPitch, LivingEntity... entities) { + public static void lookAt(LookAnchor entityAnchor, Object target, @Nullable Float headRotationSpeed, @Nullable Float maxHeadPitch, Entity... entities) { if (target == null || !LOOK_AT || !LOOK_ANCHORS) return; - for (LivingEntity entity : entities) { + for (Entity entity : entities) { if (target instanceof Location && !((Location) target).isWorldLoaded()) { Location location = (Location) target; target = new Location(entity.getWorld(), location.getX(), location.getY(), location.getZ()); } - if (entity instanceof Player) { - Player player = (Player) entity; - if (target instanceof Vector) { - Vector vector = (Vector) target; + if (entity instanceof Player player) { + if (target instanceof Vector vector) { player.lookAt(player.getEyeLocation().add(vector), LookAnchor.EYES); player.lookAt(player.getEyeLocation().add(vector), LookAnchor.FEET); } else if (target instanceof Location) { @@ -105,11 +103,12 @@ public static void lookAt(LookAnchor entityAnchor, Object target, @Nullable Floa player.lookAt((Entity) target, LookAnchor.EYES, entityAnchor); player.lookAt((Entity) target, LookAnchor.FEET, entityAnchor); } - } else if (entity instanceof Mob) { - mobLookAt(target, headRotationSpeed, maxHeadPitch, (Mob) entity); + } else if (entity instanceof Mob mob) { + mobLookAt(target, headRotationSpeed, maxHeadPitch, mob); } else { if (target instanceof Vector vector) { - Location loc = entity.getEyeLocation().add(vector); + Location base = entity instanceof LivingEntity living ? living.getEyeLocation() : entity.getLocation(); + Location loc = base.add(vector); entity.lookAt(loc.getX(), loc.getY(), loc.getZ(), entityAnchor); } else if (target instanceof LivingEntity targetEntity) { Location loc = entityAnchor == LookAnchor.EYES ? targetEntity.getEyeLocation() : targetEntity.getLocation(); diff --git a/src/main/java/ch/njol/skript/effects/EffLook.java b/src/main/java/ch/njol/skript/effects/EffLook.java index cedfb46ac68..7d5aff3bd5f 100644 --- a/src/main/java/ch/njol/skript/effects/EffLook.java +++ b/src/main/java/ch/njol/skript/effects/EffLook.java @@ -10,14 +10,14 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.util.Kleenean; import io.papermc.paper.entity.LookAnchor; -import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Entity; import org.bukkit.event.Event; import org.jetbrains.annotations.Nullable; import org.skriptlang.skript.registration.SyntaxInfo; import org.skriptlang.skript.registration.SyntaxRegistry; @Name("Look At") -@Description("Forces living entities to look at an entity, vector or location. Vanilla max head pitches range from 10 to 50.") +@Description("Forces entities to look at an entity, vector or location. Vanilla max head pitches range from 10 to 50.") @Example("force the player to look towards event-entity's feet") @Example(""" on entity explosion: @@ -35,15 +35,15 @@ public static void register(SyntaxRegistry registry) { SyntaxRegistry.EFFECT, SyntaxInfo.builder(EffLook.class) .addPatterns( - "(force|make) %livingentities% [to] (face [towards]|look [(at|towards)]) " + + "(force|make) %entities% [to] (face [towards]|look [(at|towards)]) " + "%entity%'s (feet:feet|eyes) [(at|with) [head] [rotation] speed %-number%] " + "[[and] max[imum] [head] pitch %-number%]", - "(force|make) %livingentities% [to] (face [towards]|look [(at|towards)]) " + + "(force|make) %entities% [to] (face [towards]|look [(at|towards)]) " + "[the] (feet:feet|eyes) of %entity% [(at|with) [head] [rotation] speed %-number%] " + "[[and] max[imum] [head] pitch %-number%]", - "(force|make) %livingentities% [to] (face [towards]|look [(at|towards)]) %vector/location/entity% " + + "(force|make) %entities% [to] (face [towards]|look [(at|towards)]) %vector/location/entity% " + "[(at|with) [head] [rotation] speed %-number%] [[and] max[imum] [head] pitch %-number%]" ) .supplier(EffLook::new) @@ -52,7 +52,7 @@ public static void register(SyntaxRegistry registry) { } private LookAnchor anchor = LookAnchor.EYES; - private Expression entities; + private Expression entities; @Nullable private Expression speed, maxPitch; @@ -65,7 +65,7 @@ public static void register(SyntaxRegistry registry) { @SuppressWarnings("unchecked") @Override public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { - entities = (Expression) exprs[0]; + entities = (Expression) exprs[0]; target = exprs[1]; speed = (Expression) exprs[2]; maxPitch = (Expression) exprs[3];