From 058cfd44c6fa7e1d976ddbe5c4f6564ed546823a Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Fri, 6 Jun 2025 21:16:08 +0300 Subject: [PATCH 1/9] add facing relative --- .../expressions/ExprLocationVectorOffset.java | 65 ++++++++++++++----- 1 file changed, 50 insertions(+), 15 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java index 1526165ecd7..1467cf486c1 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java @@ -1,15 +1,12 @@ package ch.njol.skript.expressions; +import ch.njol.skript.doc.*; import org.bukkit.Location; import org.bukkit.event.Event; import org.bukkit.util.Vector; import org.jetbrains.annotations.Nullable; import ch.njol.skript.Skript; -import ch.njol.skript.doc.Description; -import ch.njol.skript.doc.Examples; -import ch.njol.skript.doc.Name; -import ch.njol.skript.doc.Since; import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ExpressionType; import ch.njol.skript.lang.SkriptParser.ParseResult; @@ -23,13 +20,17 @@ */ @Name("Vectors - Location Vector Offset") @Description("Returns the location offset by vectors.") -@Examples({"set {_loc} to {_loc} ~ {_v}"}) -@Since("2.2-dev28") +@Example("set {_loc} to {_loc} ~ {_v}") +@Example(""" + # spawn a tnt 5 blocks infront of player + spawn tnt at player offset by vector(0, 1, 5) using local axes + """) +@Since("2.2-dev28, INSERT VERSION (facing relative)") public class ExprLocationVectorOffset extends SimpleExpression { static { Skript.registerExpression(ExprLocationVectorOffset.class, Location.class, ExpressionType.COMBINED, - "%location% offset by [[the] vectors] %vectors%", + "%location% offset by [[the] vectors] %vectors% [facingrelative:using local axes]", "%location%[ ]~[~][ ]%vectors%"); } @@ -39,23 +40,33 @@ public class ExprLocationVectorOffset extends SimpleExpression { @SuppressWarnings("null") private Expression vectors; + private boolean usingLocalAxes; + @Override @SuppressWarnings({"unchecked", "null"}) public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { location = (Expression) exprs[0]; vectors = (Expression) exprs[1]; + usingLocalAxes = parseResult.hasTag("facingrelative"); return true; } @SuppressWarnings("null") @Override - protected Location[] get(Event e) { - Location l = location.getSingle(e); - if (l == null) + protected Location[] get(Event event) { + Location location = this.location.getSingle(event); + if (location == null) return null; - Location clone = l.clone(); - for (Vector v : vectors.getArray(e)) - clone.add(v); + + Location clone = location.clone(); + + for (Vector vector : vectors.getArray(event)) { + if (usingLocalAxes) { + clone = getFacingRelativeOffset(clone, vector); + } else { + clone.add(vector); + } + } return CollectionUtils.array(clone); } @@ -70,8 +81,32 @@ public Class getReturnType() { } @Override - public String toString(@Nullable Event e, boolean debug) { - return location.toString() + " offset by " + vectors.toString(); + public String toString(@Nullable Event event, boolean debug) { + return location.toString(event, debug) + " offset by " + vectors.toString(event, debug) + (usingLocalAxes ? " using local axes" : ""); + } + + /** + * Returns a location offset from the given location, adjusted for the location's rotation. + *

+ * This behaves similarly to Minecraft's {@code /summon zombie ^ ^ ^1} command, + * where the offset is applied relative to the entity's facing direction. + * + * @see Local Coordinates. + * @param loc The location + * @param offset The offset + * @return The offset location + */ + private static Location getFacingRelativeOffset(Location loc, Vector offset) { + Vector forward = loc.getDirection(); + Vector up = new Vector(0, 1, 0); + Vector left = up.clone().crossProduct(forward).normalize(); + + Vector o = new Vector(0, 0, 0); + o.add(left.multiply(offset.getX())); + o.add(up.multiply(offset.getY())); + o.add(forward.multiply(offset.getZ())); + + return loc.add(o); } } From 264e75776b599475bcf1fab28061a1f31b88fba5 Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Fri, 6 Jun 2025 21:17:04 +0300 Subject: [PATCH 2/9] remove warning suppressions --- .../njol/skript/expressions/ExprLocationVectorOffset.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java index 1467cf486c1..b16bcb11118 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java @@ -15,9 +15,6 @@ import ch.njol.util.coll.CollectionUtils; -/** - * @author bi0qaw - */ @Name("Vectors - Location Vector Offset") @Description("Returns the location offset by vectors.") @Example("set {_loc} to {_loc} ~ {_v}") @@ -34,16 +31,12 @@ public class ExprLocationVectorOffset extends SimpleExpression { "%location%[ ]~[~][ ]%vectors%"); } - @SuppressWarnings("null") private Expression location; - - @SuppressWarnings("null") private Expression vectors; private boolean usingLocalAxes; @Override - @SuppressWarnings({"unchecked", "null"}) public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { location = (Expression) exprs[0]; vectors = (Expression) exprs[1]; @@ -51,7 +44,6 @@ public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelaye return true; } - @SuppressWarnings("null") @Override protected Location[] get(Event event) { Location location = this.location.getSingle(event); From 5d740de1dfcd26e816554a714927dc9f19319476 Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Fri, 6 Jun 2025 21:17:29 +0300 Subject: [PATCH 3/9] remove nl --- .../ch/njol/skript/expressions/ExprLocationVectorOffset.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java index b16bcb11118..5e384bbf72f 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java @@ -14,7 +14,6 @@ import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; - @Name("Vectors - Location Vector Offset") @Description("Returns the location offset by vectors.") @Example("set {_loc} to {_loc} ~ {_v}") From 7fc24beff3f90c3411d0f74779dd179102bd12e1 Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Fri, 6 Jun 2025 21:21:23 +0300 Subject: [PATCH 4/9] update example --- .../ch/njol/skript/expressions/ExprLocationVectorOffset.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java index 5e384bbf72f..b65438ceced 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java @@ -19,7 +19,8 @@ @Example("set {_loc} to {_loc} ~ {_v}") @Example(""" # spawn a tnt 5 blocks infront of player - spawn tnt at player offset by vector(0, 1, 5) using local axes + set {_l} to player's location offset by vector(0, 1, 5) using local axes + spawn tnt at {_l} """) @Since("2.2-dev28, INSERT VERSION (facing relative)") public class ExprLocationVectorOffset extends SimpleExpression { From cfd5c7ead1c6952e77eebadd74454c285d245f8b Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Sun, 15 Jun 2025 22:37:35 +0300 Subject: [PATCH 5/9] rewrite --- .../expressions/ExprLocationVectorOffset.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java index b65438ceced..a839967fcd9 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java @@ -13,6 +13,8 @@ import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; import ch.njol.util.coll.CollectionUtils; +import org.joml.Quaternionf; +import org.joml.Vector3f; @Name("Vectors - Location Vector Offset") @Description("Returns the location offset by vectors.") @@ -89,16 +91,15 @@ public String toString(@Nullable Event event, boolean debug) { * @return The offset location */ private static Location getFacingRelativeOffset(Location loc, Vector offset) { - Vector forward = loc.getDirection(); - Vector up = new Vector(0, 1, 0); - Vector left = up.clone().crossProduct(forward).normalize(); + float yawRad = (float) Math.toRadians(-loc.getYaw()); + float pitchRad = (float) Math.toRadians(loc.getPitch()); + float rollRad = 0f; - Vector o = new Vector(0, 0, 0); - o.add(left.multiply(offset.getX())); - o.add(up.multiply(offset.getY())); - o.add(forward.multiply(offset.getZ())); + Quaternionf rotation = new Quaternionf().rotateYXZ(yawRad, pitchRad, rollRad); + Vector3f localOffset = offset.toVector3f(); + rotation.transform(localOffset); - return loc.add(o); + return loc.add(localOffset.x, localOffset.y, localOffset.z); } } From 60fa4a05f34f1c236e34e5ac77d154d5cc7337ff Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Thu, 26 Jun 2025 11:14:54 +0300 Subject: [PATCH 6/9] cleanup --- .../expressions/ExprLocationVectorOffset.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java index a839967fcd9..b051fdc240f 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java @@ -1,6 +1,7 @@ package ch.njol.skript.expressions; import ch.njol.skript.doc.*; +import ch.njol.skript.lang.SyntaxStringBuilder; import org.bukkit.Location; import org.bukkit.event.Event; import org.bukkit.util.Vector; @@ -12,19 +13,19 @@ import ch.njol.skript.lang.SkriptParser.ParseResult; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; -import ch.njol.util.coll.CollectionUtils; import org.joml.Quaternionf; import org.joml.Vector3f; @Name("Vectors - Location Vector Offset") -@Description("Returns the location offset by vectors.") +@Description("Returns the location offset by vectors. Supports both global and local axes. " + + "When using local axes, the vector is applied relative to the direction the location is facing.") @Example("set {_loc} to {_loc} ~ {_v}") @Example(""" - # spawn a tnt 5 blocks infront of player + # spawn a tnt 5 blocks in front of player set {_l} to player's location offset by vector(0, 1, 5) using local axes spawn tnt at {_l} """) -@Since("2.2-dev28, INSERT VERSION (facing relative)") +@Since("2.2-dev28, INSERT VERSION (local axes)") public class ExprLocationVectorOffset extends SimpleExpression { static { @@ -40,7 +41,9 @@ public class ExprLocationVectorOffset extends SimpleExpression { @Override public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + // noinspection unchecked location = (Expression) exprs[0]; + // noinspection unchecked vectors = (Expression) exprs[1]; usingLocalAxes = parseResult.hasTag("facingrelative"); return true; @@ -61,7 +64,7 @@ protected Location[] get(Event event) { clone.add(vector); } } - return CollectionUtils.array(clone); + return new Location[]{ clone }; } @Override @@ -76,7 +79,12 @@ public Class getReturnType() { @Override public String toString(@Nullable Event event, boolean debug) { - return location.toString(event, debug) + " offset by " + vectors.toString(event, debug) + (usingLocalAxes ? " using local axes" : ""); + return new SyntaxStringBuilder(event, debug) + .append(location) + .append("offset by") + .append(vectors) + .append(usingLocalAxes ? "using local axes" : "") + .toString(); } /** From dc3e3ed11ed9320a89229483e0eaf3fbdf2ed763 Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Tue, 1 Jul 2025 12:15:37 +0300 Subject: [PATCH 7/9] tests --- .../expressions/ExprLocationVectorOffset.sk | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/test/skript/tests/syntaxes/expressions/ExprLocationVectorOffset.sk b/src/test/skript/tests/syntaxes/expressions/ExprLocationVectorOffset.sk index 4512b7dc0d7..f325c2f372d 100644 --- a/src/test/skript/tests/syntaxes/expressions/ExprLocationVectorOffset.sk +++ b/src/test/skript/tests/syntaxes/expressions/ExprLocationVectorOffset.sk @@ -12,3 +12,29 @@ test "location vector offset": set {_offset} to {_location} ~ vector({_x}, {_y}, {_z}) set {_length} to the normal length of vector({_x}, {_y}, {_z}) assert the distance between {_offset} and {_location} is {_length} with "randomly-created vector offset failed (expected %{_length}%, got %distance between {_offset} and {_location}%)" + +test "vector offset using local axes": + set {_test.loc} to location(-19.40051951171598, 45.37940054464023, -2.293542970995297, world("world"), -72.04071, -82.03418) + set {_expected.loc} to location(-14.934356830136391, 49.420007997032805, -6.763092626909604, world("world"), -72.04071, -82.03418) + set {_v} to vector(5.628876967791593,-2.2827525504406823,4.399407332234864) + assert ({_test.loc} offset by {_v} using local axes) is {_expected.loc} with "returned wrong location - 1" + + set {_test.loc} to location(13.30406555773089, 67.5819873186199, -6.298727546251565, world("world"), 103.484215, 19.238579) + set {_expected.loc} to location(10.647636743796564, 60.574954924210715, -6.606756333626062, world("world"), 103.484215, 19.238579) + set {_v} to vector(0.31988220626119995,-5.740885067612596,4.815590723325663) + assert ({_test.loc} offset by {_v} using local axes) is {_expected.loc} with "returned wrong location - 2" + + set {_test.loc} to location(3.3869350328876977, 44.792269367551405, -20.474066984956654, world("world"), 157.17847, 75.89636) + set {_expected.loc} to location(7.324176348729372, 38.611687797879775, -22.070485604112537, world("world"), 157.17847, 75.89636) + set {_v} to vector(-4.248213705545501,-1.560043345242382,5.980714428308739) + assert ({_test.loc} offset by {_v} using local axes) is {_expected.loc} with "returned wrong location - 3" + + set {_test.loc} to location(20.245140591456668, 39.23482347167744, 7.434704275414153, world("world"), 86.558136, -45.623573) + set {_expected.loc} to location(23.040052452876346, 39.29507158212079, 14.394218416496916, world("world"), 86.558136, -45.623573) + set {_v} to vector(7.114755290046221,1.737584079576708,-1.6158770773672382) + assert ({_test.loc} offset by {_v} using local axes) is {_expected.loc} with "returned wrong location - 4" + + set {_test.loc} to location(-19.67380126817804, 54.49320309887087, 1.4868926984678503, world("world"), 172.25856, -62.71486) + set {_expected.loc} to location(-13.3405063997088, 58.03254001865542, -0.41375398808610475, world("world"), 172.25856, -62.71486) + set {_v} to vector(-6.5315963180124434,0.7069113825034361,3.617806771486472) + assert ({_test.loc} offset by {_v} using local axes) is {_expected.loc} with "returned wrong location - 5" From a044ee158729d4bb3c39cba2e6a0173e14de94fc Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Tue, 1 Jul 2025 12:16:05 +0300 Subject: [PATCH 8/9] tests --- .../syntaxes/expressions/ExprLocationVectorOffset.sk | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/test/skript/tests/syntaxes/expressions/ExprLocationVectorOffset.sk b/src/test/skript/tests/syntaxes/expressions/ExprLocationVectorOffset.sk index f325c2f372d..a2346ad575a 100644 --- a/src/test/skript/tests/syntaxes/expressions/ExprLocationVectorOffset.sk +++ b/src/test/skript/tests/syntaxes/expressions/ExprLocationVectorOffset.sk @@ -16,25 +16,25 @@ test "location vector offset": test "vector offset using local axes": set {_test.loc} to location(-19.40051951171598, 45.37940054464023, -2.293542970995297, world("world"), -72.04071, -82.03418) set {_expected.loc} to location(-14.934356830136391, 49.420007997032805, -6.763092626909604, world("world"), -72.04071, -82.03418) - set {_v} to vector(5.628876967791593,-2.2827525504406823,4.399407332234864) + set {_v} to vector(5.628876967791593, -2.2827525504406823, 4.399407332234864) assert ({_test.loc} offset by {_v} using local axes) is {_expected.loc} with "returned wrong location - 1" set {_test.loc} to location(13.30406555773089, 67.5819873186199, -6.298727546251565, world("world"), 103.484215, 19.238579) set {_expected.loc} to location(10.647636743796564, 60.574954924210715, -6.606756333626062, world("world"), 103.484215, 19.238579) - set {_v} to vector(0.31988220626119995,-5.740885067612596,4.815590723325663) + set {_v} to vector(0.31988220626119995, -5.740885067612596, 4.815590723325663) assert ({_test.loc} offset by {_v} using local axes) is {_expected.loc} with "returned wrong location - 2" set {_test.loc} to location(3.3869350328876977, 44.792269367551405, -20.474066984956654, world("world"), 157.17847, 75.89636) set {_expected.loc} to location(7.324176348729372, 38.611687797879775, -22.070485604112537, world("world"), 157.17847, 75.89636) - set {_v} to vector(-4.248213705545501,-1.560043345242382,5.980714428308739) + set {_v} to vector(-4.248213705545501, -1.560043345242382, 5.980714428308739) assert ({_test.loc} offset by {_v} using local axes) is {_expected.loc} with "returned wrong location - 3" set {_test.loc} to location(20.245140591456668, 39.23482347167744, 7.434704275414153, world("world"), 86.558136, -45.623573) set {_expected.loc} to location(23.040052452876346, 39.29507158212079, 14.394218416496916, world("world"), 86.558136, -45.623573) - set {_v} to vector(7.114755290046221,1.737584079576708,-1.6158770773672382) + set {_v} to vector(7.114755290046221, 1.737584079576708, -1.6158770773672382) assert ({_test.loc} offset by {_v} using local axes) is {_expected.loc} with "returned wrong location - 4" set {_test.loc} to location(-19.67380126817804, 54.49320309887087, 1.4868926984678503, world("world"), 172.25856, -62.71486) set {_expected.loc} to location(-13.3405063997088, 58.03254001865542, -0.41375398808610475, world("world"), 172.25856, -62.71486) - set {_v} to vector(-6.5315963180124434,0.7069113825034361,3.617806771486472) + set {_v} to vector(-6.5315963180124434, 0.7069113825034361, 3.617806771486472) assert ({_test.loc} offset by {_v} using local axes) is {_expected.loc} with "returned wrong location - 5" From bc8175149d8b9ba4ef458f65212330e15d5eed11 Mon Sep 17 00:00:00 2001 From: Eren KARA Date: Tue, 1 Jul 2025 12:33:11 +0300 Subject: [PATCH 9/9] fix --- .../expressions/ExprLocationVectorOffset.java | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java index 35aeaa18d1f..14edff4878a 100644 --- a/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java +++ b/src/main/java/ch/njol/skript/expressions/ExprLocationVectorOffset.java @@ -1,22 +1,21 @@ package ch.njol.skript.expressions; -import ch.njol.skript.doc.*; -import ch.njol.skript.lang.SyntaxStringBuilder; -import ch.njol.skript.lang.Literal; -import org.bukkit.Location; -import org.bukkit.event.Event; -import org.bukkit.util.Vector; -import org.jetbrains.annotations.Nullable; - import ch.njol.skript.Skript; -import ch.njol.skript.lang.Expression; -import ch.njol.skript.lang.ExpressionType; +import ch.njol.skript.doc.Description; +import ch.njol.skript.doc.Example; +import ch.njol.skript.doc.Name; +import ch.njol.skript.doc.Since; +import ch.njol.skript.lang.*; import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.simplification.SimplifiedLiteral; import ch.njol.skript.lang.util.SimpleExpression; import ch.njol.util.Kleenean; +import org.bukkit.Location; +import org.bukkit.event.Event; +import org.bukkit.util.Vector; +import org.jetbrains.annotations.Nullable; import org.joml.Quaternionf; import org.joml.Vector3f; -import ch.njol.skript.lang.simplification.SimplifiedLiteral; @Name("Vectors - Location Vector Offset") @Description("Returns the location offset by vectors. Supports both global and local axes. " + @@ -114,6 +113,8 @@ private static Location getFacingRelativeOffset(Location loc, Vector offset) { Quaternionf rotation = new Quaternionf().rotateYXZ(yawRad, pitchRad, rollRad); Vector3f localOffset = offset.toVector3f(); rotation.transform(localOffset); + + return loc.add(localOffset.x, localOffset.y, localOffset.z); } }