use of com.nukkitx.math.vector.Vector3f in project Geyser by GeyserMC.
the class EnderDragonEntity method updateBoundingBoxes.
/**
* Updates the positions of the Ender Dragon's multiple bounding boxes
*/
private void updateBoundingBoxes() {
Vector3f facingDir = Vector3f.createDirectionDeg(0, headYaw);
Segment baseSegment = getSegment(5);
// Used to angle the head, neck, and tail when the dragon flies up/down
float pitch = (float) Math.toRadians(10 * (baseSegment.getY() - getSegment(10).getY()));
float pitchXZ = (float) Math.cos(pitch);
float pitchY = (float) Math.sin(pitch);
// Lowers the head when the dragon sits/hovers
float headDuck;
if (isHovering() || isSitting()) {
headDuck = -1f;
} else {
headDuck = baseSegment.y - getSegment(0).y;
}
head.setPosition(facingDir.up(pitchY).mul(pitchXZ, 1, -pitchXZ).mul(6.5f).up(headDuck));
neck.setPosition(facingDir.up(pitchY).mul(pitchXZ, 1, -pitchXZ).mul(5.5f).up(headDuck));
body.setPosition(facingDir.mul(0.5f, 0f, -0.5f));
Vector3f wingPos = Vector3f.createDirectionDeg(0, 90f - headYaw).mul(4.5f).up(2f);
rightWing.setPosition(wingPos);
// Mirror horizontally
leftWing.setPosition(wingPos.mul(-1, 1, -1));
Vector3f tailBase = facingDir.mul(1.5f);
for (int i = 0; i < tail.length; i++) {
float distance = (i + 1) * 2f;
// Curls the tail when the dragon turns
Segment targetSegment = getSegment(12 + 2 * i);
float angle = headYaw + targetSegment.yaw - baseSegment.yaw;
float tailYOffset = targetSegment.y - baseSegment.y - (distance + 1.5f) * pitchY + 1.5f;
tail[i].setPosition(Vector3f.createDirectionDeg(0, angle).mul(distance).add(tailBase).mul(-pitchXZ, 1, pitchXZ).up(tailYOffset));
}
// Send updated positions
for (EnderDragonPartEntity part : allParts) {
part.moveAbsolute(part.getPosition().add(position), 0, 0, 0, false, false);
}
}
use of com.nukkitx.math.vector.Vector3f in project Geyser by GeyserMC.
the class EnderDragonEntity method effectTick.
/**
* Handles the particles and sounds of the Ender Dragon
*/
private void effectTick() {
Random random = ThreadLocalRandom.current();
if (!getFlag(EntityFlag.SILENT)) {
if (Math.cos(wingPosition * 2f * Math.PI) <= -0.3f && Math.cos(lastWingPosition * 2f * Math.PI) >= -0.3f) {
PlaySoundPacket playSoundPacket = new PlaySoundPacket();
playSoundPacket.setSound("mob.enderdragon.flap");
playSoundPacket.setPosition(position);
playSoundPacket.setVolume(5f);
playSoundPacket.setPitch(0.8f + random.nextFloat() * 0.3f);
session.sendUpstreamPacket(playSoundPacket);
}
if (!isSitting() && !isHovering() && ticksTillNextGrowl-- == 0) {
playGrowlSound();
ticksTillNextGrowl = 200 + random.nextInt(200);
}
lastWingPosition = wingPosition;
}
if (isAlive()) {
if (getFlag(EntityFlag.NO_AI)) {
wingPosition = 0.5f;
} else if (isHovering() || isSitting()) {
wingPosition += 0.1f;
} else {
double speed = motion.length();
wingPosition += 0.2f / (speed * 10f + 1) * Math.pow(2, motion.getY());
}
phaseTicks++;
if (phase == 3) {
// Landing Phase
float headHeight = head.getBoundingBoxHeight();
Vector3f headCenter = head.getPosition().up(headHeight * 0.5f);
for (int i = 0; i < 8; i++) {
Vector3f particlePos = headCenter.add(random.nextGaussian() / 2f, random.nextGaussian() / 2f, random.nextGaussian() / 2f);
// This is missing velocity information
LevelEventPacket particlePacket = new LevelEventPacket();
particlePacket.setType(LevelEventType.PARTICLE_DRAGONS_BREATH);
particlePacket.setPosition(particlePos);
session.sendUpstreamPacket(particlePacket);
}
} else if (phase == 5) {
// Sitting Flaming Phase
if (phaseTicks % 2 == 0 && phaseTicks < 10) {
// so we need to manually spawn particles
for (int i = 0; i < 8; i++) {
SpawnParticleEffectPacket spawnParticleEffectPacket = new SpawnParticleEffectPacket();
spawnParticleEffectPacket.setDimensionId(DimensionUtils.javaToBedrock(session.getDimension()));
spawnParticleEffectPacket.setPosition(head.getPosition().add(random.nextGaussian() / 2f, random.nextGaussian() / 2f, random.nextGaussian() / 2f));
spawnParticleEffectPacket.setIdentifier("minecraft:dragon_breath_fire");
session.sendUpstreamPacket(spawnParticleEffectPacket);
}
}
} else if (phase == 7) {
// Sitting Attacking Phase
playGrowlSound();
} else if (phase == 9) {
// Send explosion particles as the dragon move towards the end portal
if (phaseTicks % 10 == 0) {
float xOffset = 8f * (random.nextFloat() - 0.5f);
float yOffset = 4f * (random.nextFloat() - 0.5f) + 2f;
float zOffset = 8f * (random.nextFloat() - 0.5f);
Vector3f particlePos = position.add(xOffset, yOffset, zOffset);
LevelEventPacket particlePacket = new LevelEventPacket();
particlePacket.setType(LevelEventType.PARTICLE_EXPLOSION);
particlePacket.setPosition(particlePos);
session.sendUpstreamPacket(particlePacket);
}
}
}
}
use of com.nukkitx.math.vector.Vector3f in project Geyser by GeyserMC.
the class WorldBorder method isPassingIntoBorderBoundaries.
public boolean isPassingIntoBorderBoundaries(Vector3f newEntityPosition) {
int entityX = GenericMath.floor(newEntityPosition.getX());
int entityZ = GenericMath.floor(newEntityPosition.getZ());
Vector3f currentEntityPosition = session.getPlayerEntity().getPosition();
// Make sure we can't move out of the world border, but if we're out of the world border, we can move in
return (entityX == (int) minX && currentEntityPosition.getX() > newEntityPosition.getX()) || (entityX == (int) maxX && currentEntityPosition.getX() < newEntityPosition.getX()) || (entityZ == (int) minZ && currentEntityPosition.getZ() > newEntityPosition.getZ()) || (entityZ == (int) maxZ && currentEntityPosition.getZ() < newEntityPosition.getZ());
}
use of com.nukkitx.math.vector.Vector3f in project Geyser by GeyserMC.
the class JavaAddEntityTranslator method translate.
@Override
public void translate(GeyserSession session, ClientboundAddEntityPacket packet) {
Vector3f position = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
Vector3f motion = Vector3f.from(packet.getMotionX(), packet.getMotionY(), packet.getMotionZ());
float yaw = packet.getYaw();
float pitch = packet.getPitch();
EntityDefinition<?> definition = Registries.ENTITY_DEFINITIONS.get(packet.getType());
if (definition == null) {
session.getGeyser().getLogger().warning(GeyserLocale.getLocaleStringLog("geyser.entity.type_null", packet.getType()));
return;
}
Entity entity;
if (packet.getType() == EntityType.FALLING_BLOCK) {
entity = new FallingBlockEntity(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), packet.getUuid(), position, motion, yaw, pitch, ((FallingBlockData) packet.getData()).getId());
} else if (packet.getType() == EntityType.ITEM_FRAME || packet.getType() == EntityType.GLOW_ITEM_FRAME) {
// Item frames need the hanging direction
entity = new ItemFrameEntity(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), packet.getUuid(), definition, position, motion, yaw, pitch, (Direction) packet.getData());
} else if (packet.getType() == EntityType.FISHING_BOBBER) {
// Fishing bobbers need the owner for the line
int ownerEntityId = ((ProjectileData) packet.getData()).getOwnerId();
Entity owner = session.getEntityCache().getEntityByJavaId(ownerEntityId);
// Java clients only spawn fishing hooks with a player as its owner
if (owner instanceof PlayerEntity) {
entity = new FishingHookEntity(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), packet.getUuid(), position, motion, yaw, pitch, (PlayerEntity) owner);
} else {
return;
}
} else {
entity = definition.factory().create(session, packet.getEntityId(), session.getEntityCache().getNextEntityId().incrementAndGet(), packet.getUuid(), definition, position, motion, yaw, pitch, 0f);
}
session.getEntityCache().spawnEntity(entity);
}
use of com.nukkitx.math.vector.Vector3f in project Geyser by GeyserMC.
the class JavaPlayerPositionTranslator method translate.
@Override
public void translate(GeyserSession session, ClientboundPlayerPositionPacket packet) {
if (!session.isLoggedIn())
return;
SessionPlayerEntity entity = session.getPlayerEntity();
if (!session.isSpawned()) {
// The server sends an absolute teleport everytime the player is respawned
Vector3f pos = Vector3f.from(packet.getX(), packet.getY(), packet.getZ());
entity.setPosition(pos);
entity.setYaw(packet.getYaw());
entity.setPitch(packet.getPitch());
entity.setHeadYaw(packet.getYaw());
RespawnPacket respawnPacket = new RespawnPacket();
// Bedrock server behavior
respawnPacket.setRuntimeEntityId(0);
respawnPacket.setPosition(entity.getPosition());
respawnPacket.setState(RespawnPacket.State.SERVER_READY);
session.sendUpstreamPacket(respawnPacket);
entity.updateBedrockMetadata();
MovePlayerPacket movePlayerPacket = new MovePlayerPacket();
movePlayerPacket.setRuntimeEntityId(entity.getGeyserId());
movePlayerPacket.setPosition(entity.getPosition());
movePlayerPacket.setRotation(Vector3f.from(packet.getPitch(), packet.getYaw(), 0));
movePlayerPacket.setMode(MovePlayerPacket.Mode.RESPAWN);
session.sendUpstreamPacket(movePlayerPacket);
session.setSpawned(true);
// Make sure the player moves away from (0, 32767, 0) before accepting movement packets
session.setUnconfirmedTeleport(new TeleportCache(packet.getX(), packet.getY(), packet.getZ(), packet.getPitch(), packet.getYaw(), packet.getTeleportId()));
acceptTeleport(session, packet.getX(), packet.getY(), packet.getZ(), packet.getYaw(), packet.getPitch(), packet.getTeleportId());
ChunkUtils.updateChunkPosition(session, pos.toInt());
if (session.getGeyser().getConfig().isDebugMode()) {
session.getGeyser().getLogger().debug(GeyserLocale.getLocaleStringLog("geyser.entity.player.spawn", packet.getX(), packet.getY(), packet.getZ()));
}
return;
}
Entity vehicle;
if (packet.isDismountVehicle() && (vehicle = session.getPlayerEntity().getVehicle()) != null) {
SetEntityLinkPacket linkPacket = new SetEntityLinkPacket();
linkPacket.setEntityLink(new EntityLinkData(vehicle.getGeyserId(), entity.getGeyserId(), EntityLinkData.Type.REMOVE, false, false));
session.sendUpstreamPacket(linkPacket);
vehicle.getPassengers().remove(entity);
session.getPlayerEntity().setVehicle(null);
EntityUtils.updateRiderRotationLock(entity, null, false);
EntityUtils.updateMountOffset(entity, null, false, false, entity.getPassengers().size() > 1);
entity.updateBedrockMetadata();
}
// If coordinates are relative, then add to the existing coordinate
double newX = packet.getX() + (packet.getRelative().contains(PositionElement.X) ? entity.getPosition().getX() : 0);
double newY = packet.getY() + (packet.getRelative().contains(PositionElement.Y) ? entity.getPosition().getY() - EntityDefinitions.PLAYER.offset() : 0);
double newZ = packet.getZ() + (packet.getRelative().contains(PositionElement.Z) ? entity.getPosition().getZ() : 0);
float newPitch = packet.getPitch() + (packet.getRelative().contains(PositionElement.PITCH) ? entity.getBedrockRotation().getX() : 0);
float newYaw = packet.getYaw() + (packet.getRelative().contains(PositionElement.YAW) ? entity.getBedrockRotation().getY() : 0);
int id = packet.getTeleportId();
session.getGeyser().getLogger().debug("Teleport (" + id + ") from " + entity.getPosition().getX() + " " + (entity.getPosition().getY() - EntityDefinitions.PLAYER.offset()) + " " + entity.getPosition().getZ());
Vector3f lastPlayerPosition = entity.getPosition().down(EntityDefinitions.PLAYER.offset());
float lastPlayerPitch = entity.getBedrockRotation().getX();
Vector3f teleportDestination = Vector3f.from(newX, newY, newZ);
entity.moveAbsolute(teleportDestination, newYaw, newPitch, true, true);
session.getGeyser().getLogger().debug("to " + entity.getPosition().getX() + " " + (entity.getPosition().getY() - EntityDefinitions.PLAYER.offset()) + " " + entity.getPosition().getZ());
// so check if we need to cache the teleport
if (lastPlayerPosition.distanceSquared(teleportDestination) < 0.001 && Math.abs(newPitch - lastPlayerPitch) < 5) {
session.setUnconfirmedTeleport(null);
} else {
session.setUnconfirmedTeleport(new TeleportCache(newX, newY, newZ, newPitch, newYaw, id));
}
acceptTeleport(session, newX, newY, newZ, newYaw, newPitch, id);
}
Aggregations