Skip to content

Commit

Permalink
Update position parameters to support rotation-based offsets (#2374)
Browse files Browse the repository at this point in the history
  • Loading branch information
jie65535 authored Sep 18, 2023
1 parent 047feaf commit ff6a51d
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 16 deletions.
60 changes: 60 additions & 0 deletions src/main/java/emu/grasscutter/command/CommandHelpers.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package emu.grasscutter.command;

import emu.grasscutter.game.world.Position;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.regex.*;
Expand Down Expand Up @@ -65,4 +67,62 @@ public static float parseRelative(String input, Float current) {
}
return current;
}

public static Position parsePosition(String inputX, String inputY, String inputZ, Position curPos, Position curRot) {
Position offset = new Position();
Position target = new Position(curPos);
if (inputX.contains("~")) { // Relative
if (!inputX.equals("~")) { // Relative with offset
target.addX(Float.parseFloat(inputX.replace("~", "")));
}
} else if (inputX.contains("^")) {
if (!inputX.equals("^")) {
offset.setX(Float.parseFloat(inputX.replace("^", "")));
}
} else { // Absolute
target.setX(Float.parseFloat(inputX));
}

if (inputY.contains("~")) { // Relative
if (!inputY.equals("~")) { // Relative with offset
target.addY(Float.parseFloat(inputY.replace("~", "")));
}
} else if (inputY.contains("^")) {
if (!inputY.equals("^")) {
offset.setY(Float.parseFloat(inputY.replace("^", "")));
}
} else { // Absolute
target.setY(Float.parseFloat(inputY));
}

if (inputZ.contains("~")) { // Relative
if (!inputZ.equals("~")) { // Relative with offset
target.addZ(Float.parseFloat(inputZ.replace("~", "")));
}
} else if (inputZ.contains("^")) {
if (!inputZ.equals("^")) {
offset.setZ(Float.parseFloat(inputZ.replace("^", "")));
}
} else { // Absolute
target.setZ(Float.parseFloat(inputZ));
}

if (!offset.equal3d(Position.ZERO)) {
return calculateOffset(target, curRot, offset);
} else {
return target;
}
}

public static Position calculateOffset(Position pos, Position rot, Position offset) {
// Degrees to radians
float angleZ = (float) Math.toRadians(rot.getY());
float angleX = (float) Math.toRadians(rot.getY() + 90);

// Calculate offset based on current position and rotation
return new Position(
pos.getX() + offset.getZ() * (float)Math.sin(angleZ) + offset.getX() * (float)Math.sin(angleX),
pos.getY() + offset.getY(),
pos.getZ() + offset.getZ() * (float)Math.cos(angleZ) + offset.getX() * (float)Math.cos(angleX));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ public void execute(Player sender, Player targetPlayer, List<String> args) {
throw new IllegalArgumentException();
}

Position pos = targetPlayer.getPosition();
Position rot = targetPlayer.getRotation();
Position pos = new Position(targetPlayer.getPosition());
Position rot = new Position(targetPlayer.getRotation());

switch (args.size()) {
case 7:
Expand All @@ -69,9 +69,7 @@ public void execute(Player sender, Player targetPlayer, List<String> args) {
} // Fallthrough
case 4:
try {
pos.setX(CommandHelpers.parseRelative(args.get(1), pos.getX()));
pos.setY(CommandHelpers.parseRelative(args.get(2), pos.getY()));
pos.setZ(CommandHelpers.parseRelative(args.get(3), pos.getZ()));
pos = CommandHelpers.parsePosition(args.get(1), args.get(2), args.get(3), pos, rot);
} catch (NumberFormatException ignored) {
CommandHandler.sendMessage(
sender, translate(sender, "commands.execution.argument_error"));
Expand Down
21 changes: 10 additions & 11 deletions src/main/java/emu/grasscutter/command/commands/TeleportCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.world.Position;
import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType;
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;

import java.util.List;

@Command(
Expand All @@ -18,10 +20,8 @@ public final class TeleportCommand implements CommandHandler {

@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
Position pos = targetPlayer.getPosition();
float x = pos.getX();
float y = pos.getY();
float z = pos.getZ();
Position pos = new Position(targetPlayer.getPosition());
Position rot = new Position(targetPlayer.getRotation());
int sceneId = targetPlayer.getSceneId();

switch (args.size()) {
Expand All @@ -34,9 +34,7 @@ public void execute(Player sender, Player targetPlayer, List<String> args) {
} // Fallthrough
case 3:
try {
x = CommandHelpers.parseRelative(args.get(0), x);
y = CommandHelpers.parseRelative(args.get(1), y);
z = CommandHelpers.parseRelative(args.get(2), z);
pos = CommandHelpers.parsePosition(args.get(0), args.get(1), args.get(2), pos, rot);
} catch (NumberFormatException ignored) {
CommandHandler.sendMessage(
sender, translate(sender, "commands.teleport.invalid_position"));
Expand All @@ -47,19 +45,20 @@ public void execute(Player sender, Player targetPlayer, List<String> args) {
return;
}

Position target_pos = new Position(x, y, z);
boolean result =
targetPlayer
.getWorld()
.transferPlayerToScene(targetPlayer, sceneId, TeleportType.COMMAND, target_pos);
.transferPlayerToScene(targetPlayer, sceneId, TeleportType.COMMAND, pos);

if (!result) {
CommandHandler.sendMessage(sender, translate(sender, "commands.teleport.exists_error"));
} else {
CommandHandler.sendMessage(
sender,
translate(
sender,
translate(
sender, "commands.teleport.success", targetPlayer.getNickname(), x, y, z, sceneId));
"commands.teleport.success",
targetPlayer.getNickname(), pos.getX(), pos.getY(), pos.getZ(), sceneId));
}
}
}

0 comments on commit ff6a51d

Please sign in to comment.