Skip to content

Commit 89aff65

Browse files
Absolutionismerenkarakal
authored andcommitted
ExprMidpoint (SkriptLang#7888)
* Initial Commit * Update ExprCenterLocations.sk * Update ExprCenterLocations.java * Requested Changes * Update ExprMidpointLocations.java * Allow Vectors * Test + Error Update * Update ExprMidpoint.java * Update ExprMidpoint.java * Update ExprMidpoint.java * Runtime Errors
1 parent 53f0d8c commit 89aff65

2 files changed

Lines changed: 232 additions & 0 deletions

File tree

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package ch.njol.skript.expressions;
2+
3+
import ch.njol.skript.Skript;
4+
import ch.njol.skript.config.Node;
5+
import ch.njol.skript.doc.Description;
6+
import ch.njol.skript.doc.Example;
7+
import ch.njol.skript.doc.Name;
8+
import ch.njol.skript.doc.Since;
9+
import ch.njol.skript.lang.Expression;
10+
import ch.njol.skript.lang.ExpressionType;
11+
import ch.njol.skript.lang.SkriptParser.ParseResult;
12+
import ch.njol.skript.lang.SyntaxStringBuilder;
13+
import ch.njol.skript.lang.util.SimpleExpression;
14+
import ch.njol.skript.registrations.Classes;
15+
import ch.njol.util.Kleenean;
16+
import org.bukkit.Location;
17+
import org.bukkit.World;
18+
import org.bukkit.event.Event;
19+
import org.bukkit.util.Vector;
20+
import org.jetbrains.annotations.Nullable;
21+
import org.skriptlang.skript.log.runtime.SyntaxRuntimeErrorProducer;
22+
23+
@Name("Midpoint")
24+
@Description("Get the midpoint between two vectors or two locations in the same world.")
25+
@Example("""
26+
set {_center} to the midpoint between location(0, 0, 0) and location(10, 10, 10)
27+
set {_centerBlock} to the block at {_center}
28+
""")
29+
@Example("set {_midpoint} to the mid-point of vector(20, 10, 5) and vector(3, 6, 9)")
30+
@Since("INSERT VERSION")
31+
public class ExprMidpoint extends SimpleExpression<Object> implements SyntaxRuntimeErrorProducer {
32+
33+
static {
34+
Skript.registerExpression(ExprMidpoint.class, Object.class, ExpressionType.COMBINED,
35+
"[the] mid[-]point (of|between) %object% and %object%");
36+
}
37+
38+
private Expression<?> object1;
39+
private Expression<?> object2;
40+
private Class<?>[] classTypes = null;
41+
private Class<?> superType;
42+
private Node node;
43+
44+
@Override
45+
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
46+
object1 = exprs[0];
47+
object2 = exprs[1];
48+
Class<?>[] type1 = checkExpressionType(object1);
49+
Class<?>[] type2 = checkExpressionType(object2);
50+
if (type1.length == 1 && type2.length == 1) {
51+
if (type1[0] != type2[0]) {
52+
Skript.error("You can only get the midpoint between two locations or two vectors.");
53+
return false;
54+
}
55+
classTypes = type1;
56+
superType = type1[0];
57+
} else {
58+
classTypes = type1.length > type2.length ? type1 : type2;
59+
superType = Classes.getSuperClassInfo(classTypes).getC();
60+
}
61+
node = getParser().getNode();
62+
return true;
63+
}
64+
65+
@Override
66+
protected Object @Nullable [] get(Event event) {
67+
Object object1 = this.object1.getSingle(event);
68+
Object object2 = this.object2.getSingle(event);
69+
if (object1 == null || object2 == null) {
70+
return null;
71+
} else if (object1 instanceof Location loc1 && object2 instanceof Location loc2) {
72+
if (loc1.getWorld() != loc2.getWorld()) {
73+
error("Cannot get the midpoint of two locations in different worlds.");
74+
return null;
75+
}
76+
World world = loc1.getWorld();
77+
Vector vector = loc1.toVector().getMidpoint(loc2.toVector());
78+
return new Location[] {vector.toLocation(world)};
79+
} else if (object1 instanceof Vector vector1 && object2 instanceof Vector vector2) {
80+
return new Vector[] {vector1.getMidpoint(vector2)};
81+
} else {
82+
error("You can only get the midpoint between two locations or two vectors.");
83+
return null;
84+
}
85+
}
86+
87+
private Class<?>[] checkExpressionType(Expression<?> expr) {
88+
if (expr.canReturn(Location.class)) {
89+
if (!expr.canReturn(Vector.class))
90+
return new Class<?>[] {Location.class};
91+
} else if (expr.canReturn(Vector.class)) {
92+
return new Class<?>[] {Vector.class};
93+
}
94+
return new Class<?>[] {Location.class, Vector.class};
95+
}
96+
97+
@Override
98+
public boolean isSingle() {
99+
return true;
100+
}
101+
102+
@Override
103+
public Class<?> getReturnType() {
104+
return superType;
105+
}
106+
107+
@Override
108+
public Class<?>[] possibleReturnTypes() {
109+
return classTypes;
110+
}
111+
112+
@Override
113+
public Node getNode() {
114+
return node;
115+
}
116+
117+
@Override
118+
public String toString(@Nullable Event event, boolean debug) {
119+
return new SyntaxStringBuilder(event, debug)
120+
.append("the midpoint between")
121+
.append(object1)
122+
.append("and")
123+
.append(object2)
124+
.toString();
125+
}
126+
127+
}
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
2+
using error catching
3+
4+
test "midpoint locations - simple":
5+
set {_loc1} to location(0, 0, 0)
6+
set {_loc2} to {_loc1} ~ vector(10, 10, 10)
7+
set {_midpoint} to the midpoint between {_loc1} and {_loc2}
8+
assert {_midpoint} is location(5, 5, 5) with "Simple midpoint loc1 -> loc2 is incorrect"
9+
set {_midpoint2} to the midpoint between {_loc2} and {_loc1}
10+
assert {_midpoint2} is location(5, 5, 5) with "Simple midpoint loc2 -> loc1 is incorrect"
11+
12+
test "midpoint locations - complex":
13+
set {_loc1} to location(10.3, 38.6, 72.9)
14+
set {_loc2} to location(-24.2, 63.8, 598.1)
15+
set {_midpoint} to the midpoint between {_loc1} and {_loc2}
16+
assert {_midpoint} is location(-6.95, 51.2, 335.5) with "Complex midpoint loc1 -> loc2 is incorrect"
17+
set {_midpoint2} to the midpoint between {_loc2} and {_loc1}
18+
assert {_midpoint2} is location(-6.95, 51.2, 335.5) with "Complex midpoint loc2 -> loc1 is incorrect"
19+
20+
test "midpoint locations - negative":
21+
set {_loc1} to location(-48.2, -33.6, -97.8)
22+
set {_loc2} to location(-257.3, -59.3, -327.4)
23+
set {_midpoint} to the midpoint between {_loc1} and {_loc2}
24+
assert {_midpoint} is location(-152.75, -46.45, -212.6) with "Negative midpoint loc1 -> loc2 is incorrect"
25+
set {_midpoint2} to the midpoint between {_loc2} and {_loc1}
26+
assert {_midpoint2} is location(-152.75, -46.45, -212.6) with "Negative midpoint loc2 -> loc1 is incorrect"
27+
28+
test "midpoint locations - function/variable":
29+
set {_loc} to location(20, 30, 40)
30+
set {_midpoint} to the midpoint between location(50, 60, 70) and {_loc}
31+
assert {_midpoint} is location(35, 45, 55) with "Midpoint locations function -> variable is incorrect"
32+
set {_midpoint2} to the midpoint between {_loc} and location(50, 60, 70)
33+
assert {_midpoint2} is location(35, 45, 55) with "Midpoint locations variable -> function is incorrect"
34+
35+
test "midpoint location - world error":
36+
set {_loc1} to location(0, 0, 0)
37+
set {_loc2} to location(0, 0, 0, "world_the_end")
38+
catch runtime errors:
39+
set {_midpoint} to the midpoint between {_loc1} and {_loc2}
40+
assert last caught errors is "Cannot get the midpoint of two locations in different worlds." with "ExprMidpoint should error when getting midpoint of locations in different worlds"
41+
42+
test "midpoint vectors - simple":
43+
set {_vector1} to vector(0, 0, 0)
44+
set {_vector2} to vector(10, 10, 10)
45+
set {_midpoint} to the midpoint between {_vector1} and {_vector2}
46+
assert {_midpoint} is vector(5, 5, 5) with "Simple midpoint vector1 -> vector2 is incorrect"
47+
set {_midpoint2} to the midpoint between {_vector2} and {_vector1}
48+
assert {_midpoint2} is vector(5, 5, 5) with "Simple midpoint vector2 -> vector1 is incorrect"
49+
50+
test "midpoint vectors - complex":
51+
set {_vector1} to vector(10.3, 38.6, 72.9)
52+
set {_vector2} to vector(-24.2, 63.8, 598.1)
53+
set {_midpoint} to the midpoint between {_vector1} and {_vector2}
54+
assert {_midpoint} is vector(-6.95, 51.2, 335.5) with "Complex midpoint vector1 -> vector2 is incorrect"
55+
set {_midpoint2} to the midpoint between {_vector2} and {_vector1}
56+
assert {_midpoint2} is vector(-6.95, 51.2, 335.5) with "Complex midpoint vector2 -> vector1 is incorrect"
57+
58+
test "midpoint vectors - negative":
59+
set {_vector1} to vector(-48.2, -33.6, -97.8)
60+
set {_vector2} to vector(-257.3, -59.3, -327.4)
61+
set {_midpoint} to the midpoint between {_vector1} and {_vector2}
62+
assert {_midpoint} is vector(-152.75, -46.45, -212.6) with "Negative midpoint vector1 -> vector2 is incorrect"
63+
set {_midpoint2} to the midpoint between {_vector2} and {_vector1}
64+
assert {_midpoint2} is vector(-152.75, -46.45, -212.6) with "Negative midpoint vector2 -> vector1 is incorrect"
65+
66+
test "midpoint vectors - function/variable":
67+
set {_vec} to vector(20, 30, 40)
68+
set {_midpoint} to the midpoint between vector(50, 60, 70) and {_vec}
69+
assert {_midpoint} is vector(35, 45, 55) with "Midpoint vectors function -> variable is incorrect"
70+
set {_midpoint2} to the midpoint between {_vec} and vector(50, 60, 70)
71+
assert {_midpoint2} is vector(35, 45, 55) with "Midpoint vectors variable -> function is incorrect"
72+
73+
test "midpoint type error":
74+
parse:
75+
set {_midpoint} to the midpoint between location(0, 0, 0) and vector(0, 0, 0)
76+
assert last parse logs is set with "Midpoint between location and vector should error"
77+
assert last parse logs is "You can only get the midpoint between two locations or two vectors." with "Incorrect error of midpoint between location and vector"
78+
79+
set {_loc} to location(0, 0, 0)
80+
set {_vector} to vector(0, 0, 0)
81+
82+
set {_error} to "You can only get the midpoint between two locations or two vectors."
83+
catch runtime errors:
84+
set {_midpoint} to the midpoint between {_loc} and {_vector}
85+
assert last caught errors is {_error} with "Midpoint of location variable -> vector variable should error"
86+
87+
catch runtime errors:
88+
set {_midpoint2} to the midpoint between {_vector} and {_loc}
89+
assert last caught errors is {_error} with "Midpoint of vector variable -> location variable should error"
90+
91+
catch runtime errors:
92+
set {_midpoint3} to the midpoint between location(0, 0, 0) and {_vector}
93+
assert last caught errors is {_error} with "Midpoint of location function -> vector variable should error"
94+
95+
catch runtime errors:
96+
set {_midpoint4} to the midpoint between {_vector} and location(0, 0, 0)
97+
assert last caught errors is {_error} with "Midpoint of vector variable -> location function should error"
98+
99+
catch runtime errors:
100+
set {_midpoint5} to the midpoint between vector(0, 0, 0) and {_loc}
101+
assert last caught errors is {_error} with "Midpoint of vector function -> location variable should error"
102+
103+
catch runtime errors:
104+
set {_midpoint6} to the midpoint between {_loc} and vector(0, 0, 0)
105+
assert last caught errors is {_error} with "Midpoint of location variable -> vector function should error"

0 commit comments

Comments
 (0)