use of org.spongepowered.math.vector.Vector3d in project SpongeCommon by SpongePowered.
the class TeleportCommandMixin method performTeleport.
/**
* @author Zidane
* @reason Have the teleport command respect our events
*/
@Overwrite
private static void performTeleport(CommandSourceStack source, Entity entityIn, ServerLevel worldIn, double x, double y, double z, Set<ClientboundPlayerPositionPacket.RelativeArgument> relativeList, float yaw, float pitch, @Nullable TeleportCommand.LookAt facing) {
double actualX = x;
double actualY = y;
double actualZ = z;
double actualYaw = yaw;
double actualPitch = pitch;
if (!(entityIn instanceof ServerPlayer)) {
actualYaw = Mth.wrapDegrees(yaw);
actualPitch = Mth.wrapDegrees(pitch);
actualPitch = Mth.clamp(actualPitch, -90.0F, 90.0F);
}
if (worldIn == entityIn.level) {
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND);
if (ShouldFire.MOVE_ENTITY_EVENT) {
final MoveEntityEvent posEvent = SpongeEventFactory.createMoveEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) entityIn, VecHelper.toVector3d(entityIn.position()), new Vector3d(x, y, z), new Vector3d(x, y, z));
if (SpongeCommon.post(posEvent)) {
return;
}
actualX = posEvent.destinationPosition().x();
actualY = posEvent.destinationPosition().y();
actualZ = posEvent.destinationPosition().z();
}
if (ShouldFire.ROTATE_ENTITY_EVENT) {
final RotateEntityEvent rotateEvent = SpongeEventFactory.createRotateEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) entityIn, new Vector3d(actualPitch, actualYaw, 0), new Vector3d(pitch, yaw, 0));
SpongeCommon.post(rotateEvent);
actualYaw = rotateEvent.isCancelled() ? entityIn.yRot : rotateEvent.toRotation().y();
actualPitch = rotateEvent.isCancelled() ? entityIn.xRot : rotateEvent.toRotation().x();
}
if (entityIn instanceof ServerPlayer) {
ChunkPos chunkpos = new ChunkPos(new BlockPos(actualX, actualY, actualZ));
worldIn.getChunkSource().addRegionTicket(TicketType.POST_TELEPORT, chunkpos, 1, entityIn.getId());
entityIn.stopRiding();
if (((ServerPlayer) entityIn).isSleeping()) {
((ServerPlayer) entityIn).stopSleepInBed(true, true);
}
((ServerPlayer) entityIn).connection.teleport(actualX, actualY, actualZ, (float) actualYaw, (float) actualPitch, relativeList);
} else {
entityIn.moveTo(actualX, actualY, actualZ, (float) actualYaw, (float) actualPitch);
}
entityIn.setYHeadRot((float) actualYaw);
}
} else {
if (entityIn instanceof ServerPlayer) {
// To ensure mod code is caught, handling the world change for players happens in teleport
// Teleport will create a frame but we want to ensure it'll be the command movement type
// TODO check if this is still correct
PhaseTracker.getCauseStackManager().addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND);
((ServerPlayer) entityIn).teleportTo(worldIn, x, y, z, yaw, pitch);
PhaseTracker.getCauseStackManager().removeContext(EventContextKeys.MOVEMENT_TYPE);
} else {
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND);
final ServerLevel fromWorld = (ServerLevel) entityIn.getCommandSenderWorld();
final ChangeEntityWorldEvent.Pre preEvent = PlatformHooks.INSTANCE.getEventHooks().callChangeEntityWorldEventPre(entityIn, worldIn);
if (SpongeCommon.post(preEvent)) {
return;
}
final ChangeEntityWorldEvent.Reposition posEvent = SpongeEventFactory.createChangeEntityWorldEventReposition(frame.currentCause(), (org.spongepowered.api.entity.Entity) entityIn, (org.spongepowered.api.world.server.ServerWorld) entityIn.getCommandSenderWorld(), VecHelper.toVector3d(entityIn.position()), new Vector3d(x, y, z), preEvent.originalDestinationWorld(), new Vector3d(x, y, z), preEvent.destinationWorld());
if (SpongeCommon.post(posEvent)) {
return;
}
entityIn.unRide();
final Entity result = entityIn.getType().create(worldIn);
if (result == null) {
return;
}
if (ShouldFire.ROTATE_ENTITY_EVENT) {
final RotateEntityEvent rotateEvent = SpongeEventFactory.createRotateEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) entityIn, new Vector3d(entityIn.xRot, entityIn.yRot, 0), new Vector3d(actualPitch, actualYaw, 0));
if (!SpongeCommon.post(rotateEvent)) {
actualYaw = Mth.wrapDegrees(rotateEvent.toRotation().y());
actualPitch = Mth.wrapDegrees(rotateEvent.toRotation().x());
actualPitch = Mth.clamp(actualPitch, -90.0F, 90.0F);
} else {
actualYaw = entityIn.yRot;
actualPitch = entityIn.xRot;
}
}
result.restoreFrom(entityIn);
result.moveTo(posEvent.destinationPosition().x(), posEvent.destinationPosition().y(), posEvent.destinationPosition().z(), (float) actualYaw, (float) actualPitch);
result.setYHeadRot((float) actualYaw);
worldIn.addFromAnotherDimension(result);
entityIn.removed = true;
Sponge.eventManager().post(SpongeEventFactory.createChangeEntityWorldEventPost(PhaseTracker.getCauseStackManager().currentCause(), (org.spongepowered.api.entity.Entity) result, (ServerWorld) fromWorld, preEvent.originalDestinationWorld(), preEvent.destinationWorld()));
}
}
}
if (facing != null) {
facing.perform(source, entityIn);
}
if (!(entityIn instanceof LivingEntity) || !((LivingEntity) entityIn).isFallFlying()) {
entityIn.setDeltaMovement(entityIn.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D));
entityIn.setOnGround(true);
}
if (entityIn instanceof PathfinderMob) {
((PathfinderMob) entityIn).getNavigation().stop();
}
}
use of org.spongepowered.math.vector.Vector3d in project SpongeCommon by SpongePowered.
the class SpongeCommonEventFactory method callNaturalMoveEntityEvent.
/**
* Performs the logic necessary to post the {@link MoveEntityEvent position event} for an {@link Entity}.
*
* @param entity The event
*/
public static void callNaturalMoveEntityEvent(final net.minecraft.world.entity.Entity entity) {
if (entity.removed) {
return;
}
final double deltaX = entity.xOld - entity.getX();
final double deltaY = entity.yOld - entity.getY();
final double deltaZ = entity.zOld - entity.getZ();
final double deltaChange = Math.pow(deltaX, 2) + Math.pow(deltaY, 2) + Math.pow(deltaZ, 2);
if (deltaChange < 1f / 256) {
return;
}
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
frame.pushCause(entity);
frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.NATURAL);
final MoveEntityEvent event = SpongeEventFactory.createMoveEntityEvent(frame.currentCause(), (Entity) entity, new Vector3d(entity.xOld, entity.yOld, entity.zOld), new Vector3d(entity.getX(), entity.getY(), entity.getZ()), new Vector3d(entity.getX(), entity.getY(), entity.getZ()));
if (SpongeCommon.post(event)) {
entity.setPos(entity.xOld, entity.yOld, entity.zOld);
} else {
entity.setPos(event.destinationPosition().x(), event.destinationPosition().y(), event.destinationPosition().z());
}
}
}
use of org.spongepowered.math.vector.Vector3d in project SpongeCommon by SpongePowered.
the class SpongeCommonEventFactory method callNaturalRotateEntityEvent.
/**
* Performs the logic necessary to post the {@link RotateEntityEvent rotation event} for an {@link Entity}.
*
* @param entity The event
*/
public static void callNaturalRotateEntityEvent(final net.minecraft.world.entity.Entity entity) {
if (entity.removed || (entity.xRot == entity.xRotO && entity.yRot == entity.yRotO)) {
return;
}
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
frame.pushCause(entity);
final RotateEntityEvent event = SpongeEventFactory.createRotateEntityEvent(frame.currentCause(), (Entity) entity, new Vector3d(entity.xRotO, entity.yRotO, 0), new Vector3d(entity.xRot, entity.yRot, 0));
if (SpongeCommon.post(event)) {
entity.xRot = entity.xRotO;
entity.yRot = entity.yRotO;
} else {
entity.xRot = (float) event.toRotation().x();
entity.yRot = (float) event.toRotation().y();
}
}
}
use of org.spongepowered.math.vector.Vector3d in project SpongeCommon by SpongePowered.
the class SpongeEntityArchetype method toSnapshot.
@Override
public EntitySnapshot toSnapshot(final ServerLocation location) {
final SpongeEntitySnapshotBuilder builder = new SpongeEntitySnapshotBuilder();
builder.entityType = this.type;
final CompoundTag newCompound = this.compound.copy();
final Vector3d pos = location.position();
newCompound.put(Constants.Entity.ENTITY_POSITION, Constants.NBT.newDoubleNBTList(pos.x(), pos.y(), pos.z()));
newCompound.putString(Constants.Sponge.World.WORLD_KEY, location.worldKey().formatted());
builder.compound = newCompound;
builder.worldKey = location.world().properties().key();
builder.position = pos;
builder.rotation = this.getRotation();
builder.scale = Vector3d.ONE;
return builder.build();
}
use of org.spongepowered.math.vector.Vector3d in project SpongeCommon by SpongePowered.
the class SpongeEntityArchetype method getPosition.
public Optional<Vector3d> getPosition() {
if (this.position != null) {
return Optional.of(this.position);
}
if (!this.compound.contains(Constants.Entity.ENTITY_POSITION, Constants.NBT.TAG_LIST)) {
return Optional.empty();
}
try {
final ListTag pos = this.compound.getList(Constants.Entity.ENTITY_POSITION, Constants.NBT.TAG_DOUBLE);
final double x = pos.getDouble(0);
final double y = pos.getDouble(1);
final double z = pos.getDouble(2);
this.position = new Vector3d(x, y, z);
return Optional.of(this.position);
} catch (final Exception e) {
return Optional.empty();
}
}
Aggregations