Skip to content

Commit 2b3c828

Browse files
TheLimeGlasssovdeethModerockycheeezburgaAPickledWalrus
authored
1.19.4 displays (#5601)
* Fix gradle temp * Start on displays * Save * More work * update gradle.build * stash * Progress so far * Finish bulk add * Finalize so far * Minimize adventure api * Fix static class check for not 1.19.4 * Fix missing display classinfo in pattern under 1.19.4 * Fix missing quaternions classinfo in pattern under 1.19.4 * Make sure test runs on only 1.19.4 * Address reviews and fix java 8 * Apply suggestions from code review Co-authored-by: sovdee <ethansovde@gmail.com> * Move classes * Apply changes * Move classes * Class rename * Update to Spigot's fix to TextAlignment * Return null when using w of vector * Update src/main/java/ch/njol/skript/expressions/ExprXYZComponent.java Co-authored-by: sovdee <ethansovde@gmail.com> * Use brackets * Add entity hiding * Add property init values for displays * 1.19.4 check * Add rotate syntaxes * Change example * Fix tests * shadow syntax missing * Change setting * Revert change * Update src/main/java/ch/njol/skript/conditions/CondCanSee.java * Fix imports from master merge * Get tests working * Add color reset * Update ExprXYZComponent.java * Update DisplayData.java * Update DisplayData.java * Change the package naming and merge item into its own class * Add versioning for hide effect * Add versioning for hide effect * Change tests * Update submodule skript-aliases * Fix tests * Fix tests * Fix tests * Apply suggestions from code review Co-authored-by: sovdee <10354869+sovdeeth@users.noreply.github.com> * Apply changes * Add axis angle * Add axis angle * Update skript-aliases * fix merge error * Remove axisangle and only present quaternion to users * Add tests for basic quaternion features, cleanup and fix bugs with ExprXYZComponent, add tests Notable changes include changing float comparison behavior (needs discussion) and allowing multiple vectors/quaternions to be changed at once (will overwrite list indices, needs discussion) * Add ExprQuaternionAxisAngle and tests. Change float comparison to use dynamic epsilon value. * Temporary change to build.gradle for java 17 * Revert "Update src/main/java/ch/njol/skript/conditions/CondCanSee.java" This reverts commit 3da7b37. * Reverts entity hiding commits in favor of #6867 Shouldn't be in the scope of this PR. * version check for EQAA and displaydata cleanup * force 'rotation' in EQAA, fix classdef error, add itemtypes to block display entitydata pattern, add tests for display entitydata Not sure wh * Clean up colorOf, add tests, add alpha parameter to rgb function and color tostring, add rgba factory method + constructor Discussion needed surrounding type checking in colorof acceptChange * update Nullable annotations to jetbrains * Fix <1.19 errors (just for actions) and fix subtle issues with xyz component changer * rename package to bukkit * finish package refactor * Add tests for billboarding, rework display brightness and add tests, move joml utilities * tests + allow setting override to a single number * tests, cleanup, and bug fixes for glow override and hegiht/width * Interpolation and Shadow tests + correct reset value for shadow strength + guard against NaN and init * Tests and cleanup for teleportation duration, remove number from changers for tp duration and interpolation delay/duration * Transformation tests, cleanup, bugfixes. Removed unnecessary Joml utils class. * wrong version check for teleportation duration * Display view range tests, cleanup, finite guard, switch to Timespan#getAs * strip licenses * cleanup, tests for ItemDisplayTransfrom. Fixed default from being FIXED to NONE, changed lang for NONE to be no transform to avoid confusion * Remove ItemOfItemDisplay (redundant), cleanup/test the text display expressions. * small cleanup to textdisplayexprs and rename ItemFrameSlot to be more generic * rework ExprRotate * Completely rework rotation with new Rotator API. Add support for quaternions + displays in EffRotate * cleanup rotations - java 17 tests will fail until legacy tests are removed * Fix bugs with rotation, adds tests * Add drop shadow syntax and small cleanup of ExprTextOf * See through blocks syntax * Update ExprRotate.java * remove extra [a]'s * whoops! reverts a change to number accuracy config done for testing * Module-ize, package infos, remove mc version checks * rename display.expressions package, use for loops, move displaydata * display data improvements * requested changes 1 * update switches and remove banana * requested changes 2 * Apply suggestions from code review Co-authored-by: cheeezburga <47320303+cheeezburga@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: cheeezburga <47320303+cheeezburga@users.noreply.github.com> * fix expritemofentity description * Apply suggestions from code review Co-authored-by: cheeezburga <47320303+cheeezburga@users.noreply.github.com> * Update ExprDisplayHeightWidth.java * Apply suggestions from code review Co-authored-by: Patrick Miller <apickledwalrus@gmail.com> * requested changes 2 + rotator docs * requested changes * Apply suggestions from code review Co-authored-by: Patrick Miller <apickledwalrus@gmail.com> * requested changes! --------- Co-authored-by: sovdee <ethansovde@gmail.com> Co-authored-by: sovdee <10354869+sovdeeth@users.noreply.github.com> Co-authored-by: Moderocky <admin@moderocky.com> Co-authored-by: cheeezburga <47320303+cheeezburga@users.noreply.github.com> Co-authored-by: Patrick Miller <apickledwalrus@gmail.com>
1 parent 751c102 commit 2b3c828

82 files changed

Lines changed: 4345 additions & 727 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.gradle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,15 @@ dependencies {
3131
shadow group: 'net.kyori', name: 'adventure-text-serializer-bungeecord', version: '4.3.2'
3232

3333
implementation group: 'io.papermc.paper', name: 'paper-api', version: '1.21-R0.1-SNAPSHOT'
34+
implementation group: 'org.eclipse.jdt', name: 'org.eclipse.jdt.annotation', version: '2.2.700'
35+
36+
// Comes from Minecraft including Guava or Gson
3437
implementation group: 'com.google.code.findbugs', name: 'findbugs', version: '3.0.1'
38+
39+
// bundled with Minecraft 1.19.4+ for display entity transforms
40+
implementation group: 'org.joml', name: 'joml', version: '1.10.5'
41+
42+
// Plugin hook libraries
3543
implementation group: 'com.sk89q.worldguard', name: 'worldguard-legacy', version: '7.0.0-SNAPSHOT'
3644
implementation group: 'net.milkbowl.vault', name: 'Vault', version: '1.7.3', {
3745
exclude group: 'org.bstats', module: 'bstats-bukkit'

src/main/java/ch/njol/skript/Skript.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@
9797
import org.junit.runner.JUnitCore;
9898
import org.junit.runner.Result;
9999
import org.skriptlang.skript.bukkit.SkriptMetrics;
100+
import org.skriptlang.skript.bukkit.displays.DisplayModule;
100101
import org.skriptlang.skript.lang.comparator.Comparator;
101102
import org.skriptlang.skript.lang.comparator.Comparators;
102103
import org.skriptlang.skript.lang.converter.Converter;
@@ -541,6 +542,9 @@ public void onEnable() {
541542
try {
542543
getAddonInstance().loadClasses("ch.njol.skript",
543544
"conditions", "effects", "events", "expressions", "entity", "sections", "structures");
545+
getAddonInstance().loadClasses("org.skriptlang.skript.bukkit", "misc");
546+
// todo: become proper module once registry api is merged
547+
DisplayModule.load();
544548
} catch (final Exception e) {
545549
exception(e, "Could not load required .class files: " + e.getLocalizedMessage());
546550
setEnabled(false);

src/main/java/ch/njol/skript/aliases/ItemType.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,6 +1414,22 @@ public Material getMaterial() {
14141414
return data.getType();
14151415
}
14161416

1417+
/**
1418+
* @return A random block material this ItemType represents.
1419+
* @throws IllegalStateException If {@link #hasBlock()} is false.
1420+
*/
1421+
public Material getBlockMaterial() {
1422+
List<ItemData> blockItemDatas = new ArrayList<>();
1423+
for (ItemData d : types) {
1424+
if (d.type.isBlock())
1425+
blockItemDatas.add(d);
1426+
}
1427+
if (blockItemDatas.isEmpty())
1428+
throw new IllegalStateException("This ItemType does not represent a material. " +
1429+
"ItemType#hasBlock() should return true before invoking this method.");
1430+
return blockItemDatas.get(random.nextInt(blockItemDatas.size())).getType();
1431+
}
1432+
14171433
/**
14181434
* Returns a base item type of this. Essentially, this calls
14191435
* {@link ItemData#aliasCopy()} on all datas and creates a new type
@@ -1427,4 +1443,5 @@ public ItemType getBaseType() {
14271443
}
14281444
return copy;
14291445
}
1446+
14301447
}

src/main/java/ch/njol/skript/classes/data/BukkitClasses.java

Lines changed: 37 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,32 @@
1818
*/
1919
package ch.njol.skript.classes.data;
2020

21-
import java.io.StreamCorruptedException;
22-
import java.util.ArrayList;
23-
import java.util.Arrays;
24-
import java.util.List;
25-
import java.util.Locale;
26-
import java.util.Map.Entry;
27-
import java.util.UUID;
28-
import java.util.regex.Matcher;
29-
import java.util.regex.Pattern;
30-
import java.util.stream.Collectors;
31-
21+
import ch.njol.skript.Skript;
22+
import ch.njol.skript.SkriptConfig;
23+
import ch.njol.skript.aliases.Aliases;
24+
import ch.njol.skript.aliases.ItemType;
3225
import ch.njol.skript.bukkitutil.BukkitUtils;
26+
import ch.njol.skript.bukkitutil.EnchantmentUtils;
27+
import ch.njol.skript.bukkitutil.ItemUtils;
28+
import ch.njol.skript.classes.ClassInfo;
29+
import ch.njol.skript.classes.ConfigurationSerializer;
30+
import ch.njol.skript.classes.EnumClassInfo;
31+
import ch.njol.skript.classes.Parser;
32+
import ch.njol.skript.classes.Serializer;
33+
import ch.njol.skript.classes.registry.RegistryClassInfo;
34+
import ch.njol.skript.entity.EntityData;
35+
import ch.njol.skript.expressions.ExprDamageCause;
36+
import ch.njol.skript.expressions.base.EventValueExpression;
37+
import ch.njol.skript.lang.ParseContext;
38+
import ch.njol.skript.lang.util.SimpleLiteral;
39+
import ch.njol.skript.localization.Language;
40+
import ch.njol.skript.registrations.Classes;
41+
import ch.njol.skript.util.BlockUtils;
42+
import ch.njol.skript.util.PotionEffectUtils;
43+
import ch.njol.skript.util.StringMode;
44+
import ch.njol.util.StringUtils;
45+
import ch.njol.yggdrasil.Fields;
46+
import io.papermc.paper.world.MoonPhase;
3347
import org.bukkit.Bukkit;
3448
import org.bukkit.Chunk;
3549
import org.bukkit.Difficulty;
@@ -80,37 +94,19 @@
8094
import org.bukkit.potion.PotionEffectType;
8195
import org.bukkit.util.CachedServerIcon;
8296
import org.bukkit.util.Vector;
83-
84-
import ch.njol.skript.Skript;
85-
import ch.njol.skript.SkriptConfig;
86-
import ch.njol.skript.aliases.Aliases;
87-
import ch.njol.skript.aliases.ItemType;
88-
import ch.njol.skript.bukkitutil.EnchantmentUtils;
89-
import ch.njol.skript.bukkitutil.ItemUtils;
90-
import ch.njol.skript.classes.ClassInfo;
91-
import ch.njol.skript.classes.ConfigurationSerializer;
92-
import ch.njol.skript.classes.EnumClassInfo;
93-
import ch.njol.skript.classes.Parser;
94-
import ch.njol.skript.classes.Serializer;
95-
import ch.njol.skript.classes.registry.RegistryClassInfo;
96-
import ch.njol.skript.entity.EntityData;
97-
import ch.njol.skript.expressions.ExprDamageCause;
98-
import ch.njol.skript.expressions.base.EventValueExpression;
99-
import ch.njol.skript.lang.ParseContext;
100-
import ch.njol.skript.lang.util.SimpleLiteral;
101-
import ch.njol.skript.localization.Language;
102-
import ch.njol.skript.registrations.Classes;
103-
import ch.njol.skript.util.BlockUtils;
104-
import ch.njol.skript.util.PotionEffectUtils;
105-
import ch.njol.skript.util.StringMode;
106-
import ch.njol.util.StringUtils;
107-
import ch.njol.yggdrasil.Fields;
108-
import io.papermc.paper.world.MoonPhase;
10997
import org.jetbrains.annotations.Nullable;
11098

111-
/**
112-
* @author Peter Güttinger
113-
*/
99+
import java.io.StreamCorruptedException;
100+
import java.util.ArrayList;
101+
import java.util.Arrays;
102+
import java.util.List;
103+
import java.util.Locale;
104+
import java.util.Map.Entry;
105+
import java.util.UUID;
106+
import java.util.regex.Matcher;
107+
import java.util.regex.Pattern;
108+
import java.util.stream.Collectors;
109+
114110
public class BukkitClasses {
115111

116112
public BukkitClasses() {}
@@ -1527,6 +1523,7 @@ public String toVariableNameString(EnchantmentOffer eo) {
15271523
.name("Transform Reason")
15281524
.description("Represents a transform reason of an <a href='events.html#entity transform'>entity transform event</a>.")
15291525
.since("2.8.0"));
1526+
15301527
Classes.registerClass(new EnumClassInfo<>(EntityPotionEffectEvent.Cause.class, "entitypotioncause", "entity potion causes")
15311528
.user("(entity )?potion ?effect ?cause")
15321529
.name("Entity Potion Cause")

src/main/java/ch/njol/skript/classes/data/DefaultComparators.java

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import ch.njol.skript.entity.EntityData;
3030
import ch.njol.skript.entity.RabbitData;
3131
import ch.njol.skript.util.BlockUtils;
32+
import ch.njol.skript.util.Color;
3233
import ch.njol.skript.util.Date;
3334
import ch.njol.skript.util.EnchantmentType;
3435
import ch.njol.skript.util.Experience;
@@ -75,20 +76,28 @@ public DefaultComparators() {}
7576
static {
7677

7778
// Number - Number
78-
Comparators.registerComparator(Number.class, Number.class, new Comparator<Number, Number>() {
79+
Comparators.registerComparator(Number.class, Number.class, new Comparator<>() {
7980
@Override
8081
public Relation compare(Number n1, Number n2) {
8182
if (n1 instanceof Long && n2 instanceof Long)
8283
return Relation.get(n1.longValue() - n2.longValue());
83-
Double d1 = n1.doubleValue(),
84-
d2 = n2.doubleValue();
84+
double epsilon = Skript.EPSILON;
85+
@SuppressWarnings("WrapperTypeMayBePrimitive") Double d1, d2;
86+
if (n1 instanceof Float || n2 instanceof Float) {
87+
d1 = (double) n1.floatValue();
88+
d2 = (double) n2.floatValue();
89+
epsilon = Math.min(d1, d2) * 1e-6; // dynamic epsilon
90+
} else {
91+
d1 = n1.doubleValue();
92+
d2 = n2.doubleValue();
93+
}
8594
if (d1.isNaN() || d2.isNaN()) {
8695
return Relation.SMALLER;
8796
} else if (d1.isInfinite() || d2.isInfinite()) {
8897
return d1 > d2 ? Relation.GREATER : d1 < d2 ? Relation.SMALLER : Relation.EQUAL;
8998
} else {
9099
double diff = d1 - d2;
91-
if (Math.abs(diff) < Skript.EPSILON)
100+
if (Math.abs(diff) < epsilon)
92101
return Relation.EQUAL;
93102
return Relation.get(diff);
94103
}
@@ -656,6 +665,11 @@ public boolean supportsOrdering() {
656665

657666
// Potion Effect Type
658667
Comparators.registerComparator(PotionEffectType.class, PotionEffectType.class, (one, two) -> Relation.get(one.equals(two)));
668+
669+
// Color - Color
670+
Comparators.registerComparator(Color.class, Color.class, (one, two) -> Relation.get(one.asBukkitColor().equals(two.asBukkitColor())));
671+
Comparators.registerComparator(Color.class, org.bukkit.Color.class, (one, two) -> Relation.get(one.asBukkitColor().equals(two)));
672+
Comparators.registerComparator(org.bukkit.Color.class, org.bukkit.Color.class, (one, two) -> Relation.get(one.equals(two)));
659673
}
660674

661675
}

src/main/java/ch/njol/skript/classes/data/DefaultFunctions.java

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import ch.njol.skript.registrations.DefaultClasses;
3232
import ch.njol.skript.util.Color;
3333
import ch.njol.skript.util.ColorRGB;
34+
import ch.njol.skript.util.Contract;
3435
import ch.njol.skript.util.Date;
3536
import ch.njol.util.Math2;
3637
import ch.njol.util.StringUtils;
@@ -42,7 +43,9 @@
4243
import org.bukkit.entity.Player;
4344
import org.bukkit.util.Vector;
4445
import org.jetbrains.annotations.Nullable;
45-
import ch.njol.skript.util.Contract;
46+
import org.joml.AxisAngle4f;
47+
import org.joml.Quaternionf;
48+
import org.joml.Vector3f;
4649

4750
import java.math.BigDecimal;
4851
import java.math.RoundingMode;
@@ -525,19 +528,25 @@ public Long[] executeSimple(Object[][] params) {
525528
Functions.registerFunction(new SimpleJavaFunction<Color>("rgb", new Parameter[] {
526529
new Parameter<>("red", DefaultClasses.LONG, true, null),
527530
new Parameter<>("green", DefaultClasses.LONG, true, null),
528-
new Parameter<>("blue", DefaultClasses.LONG, true, null)
531+
new Parameter<>("blue", DefaultClasses.LONG, true, null),
532+
new Parameter<>("alpha", DefaultClasses.LONG, true, new SimpleLiteral<>(255L,true))
529533
}, DefaultClasses.COLOR, true) {
530534
@Override
531535
public ColorRGB[] executeSimple(Object[][] params) {
532536
Long red = (Long) params[0][0];
533537
Long green = (Long) params[1][0];
534538
Long blue = (Long) params[2][0];
539+
Long alpha = (Long) params[3][0];
535540

536-
return CollectionUtils.array(new ColorRGB(red.intValue(), green.intValue(), blue.intValue()));
541+
return CollectionUtils.array(ColorRGB.fromRGBA(red.intValue(), green.intValue(), blue.intValue(), alpha.intValue()));
537542
}
538-
}).description("Returns a RGB color from the given red, green and blue parameters.")
539-
.examples("dye player's leggings rgb(120, 30, 45)")
540-
.since("2.5");
543+
}).description("Returns a RGB color from the given red, green and blue parameters. Alpha values can be added optionally, " +
544+
"but these only take affect in certain situations, like text display backgrounds.")
545+
.examples(
546+
"dye player's leggings rgb(120, 30, 45)",
547+
"set the colour of a text display to rgb(10, 50, 100, 50)"
548+
)
549+
.since("2.5, INSERT VERSION (alpha)");
541550

542551
Functions.registerFunction(new SimpleJavaFunction<Player>("player", new Parameter[] {
543552
new Parameter<>("nameOrUUID", DefaultClasses.STRING, true, null),
@@ -634,6 +643,50 @@ public String[] executeSimple(Object[][] params) {
634643
"concat(\"foo \", 100, \" bar\") # foo 100 bar"
635644
).since("2.9.0");
636645

646+
// joml functions - for display entities
647+
{
648+
if (Skript.classExists("org.joml.Quaternionf")) {
649+
Functions.registerFunction(new SimpleJavaFunction<>("quaternion", new Parameter[]{
650+
new Parameter<>("w", DefaultClasses.NUMBER, true, null),
651+
new Parameter<>("x", DefaultClasses.NUMBER, true, null),
652+
new Parameter<>("y", DefaultClasses.NUMBER, true, null),
653+
new Parameter<>("z", DefaultClasses.NUMBER, true, null)
654+
}, Classes.getExactClassInfo(Quaternionf.class), true) {
655+
@Override
656+
public Quaternionf[] executeSimple(Object[][] params) {
657+
double w = ((Number) params[0][0]).doubleValue();
658+
double x = ((Number) params[1][0]).doubleValue();
659+
double y = ((Number) params[2][0]).doubleValue();
660+
double z = ((Number) params[3][0]).doubleValue();
661+
return CollectionUtils.array(new Quaternionf(x, y, z, w));
662+
}
663+
})
664+
.description("Returns a quaternion from the given W, X, Y and Z parameters. ")
665+
.examples("quaternion(1, 5.6, 45.21, 10)")
666+
.since("INSERT VERSION");
667+
}
668+
669+
if (Skript.classExists("org.joml.AxisAngle4f")) {
670+
Functions.registerFunction(new SimpleJavaFunction<>("axisAngle", new Parameter[]{
671+
new Parameter<>("angle", DefaultClasses.NUMBER, true, null),
672+
new Parameter<>("axis", DefaultClasses.VECTOR, true, null)
673+
}, Classes.getExactClassInfo(Quaternionf.class), true) {
674+
@Override
675+
public Quaternionf[] executeSimple(Object[][] params) {
676+
float angle = (float) (((Number) params[0][0]).floatValue() / 180 * Math.PI);
677+
Vector v = ((Vector) params[1][0]);
678+
if (v.isZero() || !Double.isFinite(v.getX()) || !Double.isFinite(v.getY()) || !Double.isFinite(v.getZ()))
679+
return new Quaternionf[0];
680+
Vector3f axis = ((Vector) params[1][0]).toVector3f();
681+
return CollectionUtils.array(new Quaternionf(new AxisAngle4f(angle, axis)));
682+
}
683+
})
684+
.description("Returns a quaternion from the given angle (in degrees) and axis (as a vector). This represents a rotation around the given axis by the given angle.")
685+
.examples("axisangle(90, (vector from player's facing))")
686+
.since("INSERT VERSION");
687+
}
688+
} // end joml functions
689+
637690
}
638-
691+
639692
}

src/main/java/ch/njol/skript/classes/data/JavaClasses.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,12 @@
1818
*/
1919
package ch.njol.skript.classes.data;
2020

21+
import ch.njol.skript.Skript;
2122
import ch.njol.skript.SkriptConfig;
2223
import ch.njol.skript.classes.ClassInfo;
2324
import ch.njol.skript.classes.Parser;
2425
import ch.njol.skript.classes.Serializer;
26+
import ch.njol.skript.expressions.base.EventValueExpression;
2527
import ch.njol.skript.lang.ParseContext;
2628
import ch.njol.skript.lang.VariableString;
2729
import ch.njol.skript.lang.util.SimpleLiteral;
@@ -32,6 +34,7 @@
3234
import ch.njol.util.StringUtils;
3335
import ch.njol.yggdrasil.Fields;
3436
import org.jetbrains.annotations.Nullable;
37+
import org.joml.Quaternionf;
3538

3639
import java.util.regex.Pattern;
3740

@@ -627,5 +630,40 @@ public boolean mustSyncDeserialization() {
627630
return false;
628631
}
629632
}));
633+
634+
// joml type - for display entities
635+
if (Skript.classExists("org.joml.Quaternionf"))
636+
Classes.registerClass(new ClassInfo<>(Quaternionf.class, "quaternion")
637+
.user("quaternionf?s?")
638+
.name("Quaternion")
639+
.description("Quaternions are four dimensional vectors, often used for representing rotations.")
640+
.since("INSERT VERSION")
641+
.parser(new Parser<>() {
642+
public boolean canParse(ParseContext context) {
643+
return false;
644+
}
645+
646+
@Override
647+
public String toString(Quaternionf quaternion, int flags) {
648+
return "w:" + Skript.toString(quaternion.w()) + ", x:" + Skript.toString(quaternion.x()) + ", y:" + Skript.toString(quaternion.y()) + ", z:" + Skript.toString(quaternion.z());
649+
}
650+
651+
@Override
652+
public String toVariableNameString(Quaternionf quaternion) {
653+
return quaternion.w() + "," + quaternion.x() + "," + quaternion.y() + "," + quaternion.z();
654+
}
655+
})
656+
.defaultExpression(new EventValueExpression<>(Quaternionf.class))
657+
.cloner(quaternion -> {
658+
try {
659+
// Implements cloneable, but doesn't return a Quaternionf.
660+
// org.joml improper override. Returns Object.
661+
return (Quaternionf) quaternion.clone();
662+
} catch (CloneNotSupportedException e) {
663+
return null;
664+
}
665+
}));
666+
630667
}
668+
631669
}

0 commit comments

Comments
 (0)