Skip to content

Commit

Permalink
ExprYawPitch: support for entities, better description (#5298)
Browse files Browse the repository at this point in the history
* 💡 ExprYawPitch: added support for entities, made description more clear, made code consistent

* 💡 ExprYawPitch

* 💡 ExprYawPitch: apply suggestion

Co-authored-by: Ayham Al Ali <alali_ayham@yahoo.com>

* 💡 ExprYawPitch: apply suggestion

Co-authored-by: Ayham Al Ali <alali_ayham@yahoo.com>

* 💡 ExprYawPitch: apply suggestion

Co-authored-by: Ayham Al Ali <alali_ayham@yahoo.com>

* 💡 ExprYawPitch: apply other suggestions

* Update src/main/java/ch/njol/skript/expressions/ExprYawPitch.java

* Revert changes to pitch/yaw meaning

* Update ExprYawPitch.java

* Float return!

---------

Co-authored-by: Mwexim <CharcoalToast@users.noreply.github.com>
Co-authored-by: Ayham Al Ali <alali_ayham@yahoo.com>
Co-authored-by: sovdee <10354869+sovdeeth@users.noreply.github.com>
Co-authored-by: Moderocky <admin@moderocky.com>
  • Loading branch information
5 people authored Jul 1, 2024
1 parent 6065891 commit 27094a6
Showing 1 changed file with 137 additions and 64 deletions.
201 changes: 137 additions & 64 deletions src/main/java/ch/njol/skript/expressions/ExprYawPitch.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@
*/
package ch.njol.skript.expressions;

import ch.njol.skript.ServerPlatform;
import ch.njol.skript.Skript;
import ch.njol.skript.doc.RequiredPlugins;
import ch.njol.util.VectorMath;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;

import ch.njol.skript.classes.Changer.ChangeMode;
Expand All @@ -33,125 +38,193 @@
import ch.njol.util.Kleenean;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.util.Vector;
import org.eclipse.jdt.annotation.Nullable;

@Name("Yaw / Pitch")
@Description("The yaw or pitch of a location or vector.")
@Examples({"log \"%player%: %location of player%, %player's yaw%, %player's pitch%\" to \"playerlocs.log\"",
"set {_yaw} to yaw of player",
"set {_p} to pitch of target entity"})
@Since("2.0, 2.2-dev28 (vector yaw/pitch)")
public class ExprYawPitch extends SimplePropertyExpression<Object, Number> {
@Description({
"The yaw or pitch of a location or vector.",
"A yaw of 0 or 360 represents the positive z direction. Adding a positive number to the yaw of a player will rotate it clockwise.",
"A pitch of 90 represents the negative y direction, or downward facing. A pitch of -90 represents upward facing. Adding a positive number to the pitch will rotate the direction downwards.",
"Only Paper 1.19+ users may directly change the yaw/pitch of players."
})
@Examples({
"log \"%player%: %location of player%, %player's yaw%, %player's pitch%\" to \"playerlocs.log\"",
"set {_yaw} to yaw of player",
"set {_p} to pitch of target entity",
"set pitch of player to -90 # Makes the player look upwards, Paper 1.19+ only",
"add 180 to yaw of target of player # Makes the target look behind themselves"
})
@Since("2.0, 2.2-dev28 (vector yaw/pitch), INSERT VERSION (entity changers)")
@RequiredPlugins("Paper 1.19+ (player changers)")
public class ExprYawPitch extends SimplePropertyExpression<Object, Float> {

static {
register(ExprYawPitch.class, Number.class, "(yaw|pitch)", "locations/vectors");
register(ExprYawPitch.class, Float.class, "(:yaw|pitch)", "entities/locations/vectors");
}

// For non-Paper versions lower than 1.19, changing the rotation of an entity is not supported for players.
private static final boolean SUPPORTS_PLAYERS = Skript.isRunningMinecraft(1, 19) && Skript.getServerPlatform() == ServerPlatform.BUKKIT_PAPER;

private boolean usesYaw;

@Override
public boolean init(final Expression<?>[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) {
usesYaw = parseResult.mark == 0;
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
usesYaw = parseResult.hasTag("yaw");
return super.init(exprs, matchedPattern, isDelayed, parseResult);
}

@Override
public Number convert(final Object object) {
if (object instanceof Location) {
Location l = ((Location) object);
return usesYaw ? convertToPositive(l.getYaw()) : l.getPitch();
public Float convert(Object object) {
if (object instanceof Entity) {
Location location = ((Entity) object).getLocation();
return usesYaw
? normalizeYaw(location.getYaw())
: location.getPitch();
} else if (object instanceof Location) {
Location location = (Location) object;
return usesYaw
? normalizeYaw(location.getYaw())
: location.getPitch();
} else if (object instanceof Vector) {
Vector vector = ((Vector) object);
if (usesYaw)
return VectorMath.skriptYaw(VectorMath.getYaw(vector));
return VectorMath.skriptPitch(VectorMath.getPitch(vector));
Vector vector = (Vector) object;
return usesYaw
? VectorMath.skriptYaw((VectorMath.getYaw(vector)))
: VectorMath.skriptPitch(VectorMath.getPitch(vector));
}
return null;
}

@SuppressWarnings({"null"})
@Override
public Class<?>[] acceptChange(final ChangeMode mode) {
if (mode == ChangeMode.SET || mode == ChangeMode.ADD || mode == ChangeMode.REMOVE)
return CollectionUtils.array(Number.class);
return null;
public Class<?>[] acceptChange(ChangeMode mode) {
if (Player.class.isAssignableFrom(getExpr().getReturnType()) && !SUPPORTS_PLAYERS)
return null;

switch (mode) {
case SET:
case ADD:
case REMOVE:
return CollectionUtils.array(Number.class);
case RESET:
return new Class[0];
default:
return null;
}
}

@SuppressWarnings("null")
@Override
public void change(Event e, Object[] delta, ChangeMode mode) {
if (delta == null)
public void change(Event event, @Nullable Object[] delta, ChangeMode mode) {
if (delta == null && mode != ChangeMode.RESET)
return;
float value = ((Number) delta[0]).floatValue();
for (Object single : getExpr().getArray(e)) {
if (single instanceof Location) {
changeLocation(((Location) single), value, mode);
} else if (single instanceof Vector) {
changeVector(((Vector) single), value, mode);
for (Object object : getExpr().getArray(event)) {
if (object instanceof Player && !SUPPORTS_PLAYERS)
continue;

if (object instanceof Entity) {
changeForEntity((Entity) object, value, mode);
} else if (object instanceof Location) {
changeForLocation(((Location) object), value, mode);
} else if (object instanceof Vector) {
changeForVector(((Vector) object), value, mode);
}
}
}

private void changeLocation(Location l, float value, ChangeMode mode) {
private void changeForEntity(Entity entity, float value, ChangeMode mode) {
Location location = entity.getLocation();
switch (mode) {
case SET:
if (usesYaw)
l.setYaw(convertToPositive(value));
else
l.setPitch(value);
if (usesYaw) {
entity.setRotation(value, location.getPitch());
} else {
entity.setRotation(location.getYaw(), value);
}
break;
case REMOVE:
value = -value;
case ADD:
if (usesYaw)
l.setYaw(convertToPositive(l.getYaw()) + value);
else
l.setPitch(l.getPitch() + value);
if (usesYaw) {
entity.setRotation(location.getYaw() + value, location.getPitch());
} else {
// Subtracting because of Minecraft's upside-down pitch.
entity.setRotation(location.getYaw(), location.getPitch() - value);
}
break;
case RESET:
if (usesYaw) {
entity.setRotation(0, location.getPitch());
} else {
entity.setRotation(location.getYaw(), 0);
}
break;
default:
break;
}
}

private void changeForLocation(Location location, float value, ChangeMode mode) {
switch (mode) {
case SET:
if (usesYaw) {
location.setYaw(value);
} else {
location.setPitch(value);
}
break;
case REMOVE:
if (usesYaw)
l.setYaw(convertToPositive(l.getYaw()) - value);
else
l.setPitch(l.getPitch() - value);
value = -value;
case ADD:
if (usesYaw) {
location.setYaw(location.getYaw() + value);
} else {
// Subtracting because of Minecraft's upside-down pitch.
location.setPitch(location.getPitch() - value);
}
break;
case RESET:
if (usesYaw) {
location.setYaw(0);
} else {
location.setPitch(0);
}
default:
break;
}
}

private void changeVector(Vector vector, float n, ChangeMode mode) {
private void changeForVector(Vector vector, float value, ChangeMode mode) {
float yaw = VectorMath.getYaw(vector);
float pitch = VectorMath.getPitch(vector);
switch (mode) {
case REMOVE:
n = -n;
//$FALL-THROUGH$
value = -value;
// $FALL-THROUGH$
case ADD:
if (usesYaw)
yaw += n;
else
pitch -= n; // Negative because of Minecraft's / Skript's upside down pitch
Vector newVector = VectorMath.fromYawAndPitch(yaw, pitch).multiply(vector.length());
VectorMath.copyVector(vector, newVector);
if (usesYaw) {
yaw += value;
} else {
// Subtracting because of Minecraft's upside-down pitch.
pitch -= value;
}
break;
case SET:
if (usesYaw)
yaw = VectorMath.fromSkriptYaw(n);
yaw = VectorMath.fromSkriptYaw(value);
else
pitch = VectorMath.fromSkriptPitch(n);
newVector = VectorMath.fromYawAndPitch(yaw, pitch).multiply(vector.length());
VectorMath.copyVector(vector, newVector);
pitch = VectorMath.fromSkriptPitch(value);
}
Vector newVector = VectorMath.fromYawAndPitch(yaw, pitch).multiply(vector.length());
VectorMath.copyVector(vector, newVector);
}


//Some random method decided to use for converting to positive values.
public float convertToPositive(float f) {
if (f != 0 && f * -1 == Math.abs(f))
return 360 + f;
return f;
private static float normalizeYaw(float yaw) {
yaw = Location.normalizeYaw(yaw);
return yaw < 0 ? yaw + 360 : yaw;
}

@Override
public Class<? extends Number> getReturnType() {
return Number.class;
public Class<? extends Float> getReturnType() {
return Float.class;
}

@Override
Expand Down

0 comments on commit 27094a6

Please sign in to comment.