feat: player support for lookAt and setView methods (#2072)

This commit is contained in:
DeidaraMC 2024-03-30 23:54:27 -04:00 committed by GitHub
parent a9f6d9f02b
commit b71edf2706
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 82 additions and 3 deletions

View File

@ -88,6 +88,7 @@ import net.minestom.server.utils.function.IntegerBiConsumer;
import net.minestom.server.utils.identity.NamedAndIdentified;
import net.minestom.server.utils.instance.InstanceUtils;
import net.minestom.server.utils.inventory.PlayerInventoryUtils;
import net.minestom.server.utils.player.PlayerUtils;
import net.minestom.server.utils.time.Cooldown;
import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.utils.validate.Check;
@ -1834,7 +1835,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
}
/**
* Used to synchronize player position with viewers on spawn or after {@link Entity#teleport(Pos, long[], RelativeFlags...)}
* Used to synchronize player position with viewers on spawn or after {@link Entity#teleport(Pos, long[], int)}
* in cases where a {@link PlayerPositionAndLookPacket} is required
*
* @param position the position used by {@link PlayerPositionAndLookPacket}
@ -1847,6 +1848,45 @@ public class Player extends LivingEntity implements CommandSender, Localizable,
super.synchronizePosition();
}
/**
* Forces the player's client to look towards the target yaw/pitch
*
* @param yaw the new yaw
* @param pitch the new pitch
*/
@Override
public void setView(float yaw, float pitch) {
teleport(new Pos(0, 0, 0, yaw, pitch), null, RelativeFlags.COORD).join();
}
/**
* Forces the player's client to look towards the specified point
* <p>
* Note: the player's position is not updated on the server until
* the client receives this packet
*
* @param point the point to look at
*/
@Override
public void lookAt(@NotNull Point point) {
// Let the player's client provide updated position values
sendPacket(new FacePlayerPacket(FacePlayerPacket.FacePosition.EYES, point, 0, null));
}
/**
* Forces the player's client to look towards the specified entity
* <p>
* Note: the player's position is not updated on the server until
* the client receives this packet
*
* @param entity the entity to look at
*/
@Override
public void lookAt(@NotNull Entity entity) {
// Let the player's client provide updated position values
sendPacket(new FacePlayerPacket(FacePlayerPacket.FacePosition.EYES, entity.getPosition(), entity.getEntityId(), FacePlayerPacket.FacePosition.EYES));
}
/**
* Gets the player permission level.
*

View File

@ -1,9 +1,10 @@
package net.minestom.server.entity.player;
import net.kyori.adventure.text.Component;
import net.minestom.server.coordinate.Point;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.Player;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.*;
import net.minestom.server.entity.damage.DamageType;
import net.minestom.server.event.player.PlayerGameModeChangeEvent;
import net.minestom.server.message.ChatMessageType;
@ -228,4 +229,42 @@ public class PlayerIntegrationTest {
.count();
assertEquals(2, displayNamePackets3);
}
@Test
public void setView(Env env) {
var instance = env.createFlatInstance();
var connection = env.createConnection();
Pos startingPlayerPos = new Pos(0, 42, 0);
var player = connection.connect(instance, startingPlayerPos).join();
var tracker = connection.trackIncoming(PlayerPositionAndLookPacket.class);
player.setView(30, 20);
assertEquals(startingPlayerPos.withView(30, 20), player.getPosition());
tracker.assertSingle(PlayerPositionAndLookPacket.class, packet -> {
assertEquals(RelativeFlags.COORD, packet.flags());
assertEquals(packet.position(), new Pos(0, 0, 0, 30, 20));
});
}
@Test
public void lookAt(Env env) {
var instance = env.createFlatInstance();
var connection = env.createConnection();
var tracker = connection.trackIncoming(FacePlayerPacket.class);
Pos startingPlayerPos = new Pos(0, 42, 0);
var player = connection.connect(instance, startingPlayerPos).join();
Point pointLookAt = new Vec(3, 3, 3);
player.lookAt(pointLookAt);
tracker.assertSingle(FacePlayerPacket.class, packet -> assertEquals(pointLookAt, packet.target()));
tracker = connection.trackIncoming(FacePlayerPacket.class);
Entity entity = new Entity(EntityType.ZOMBIE);
entity.setInstance(player.getInstance(), new Pos(9, 9, 9));
player.lookAt(entity);
tracker.assertSingle(FacePlayerPacket.class, packet -> assertEquals(entity.getEntityId(), packet.entityId()));
assertEquals(startingPlayerPos, player.getPosition());
}
}