minecraft-src/net/minecraft/world/level/portal/TeleportTransition.java
2025-07-04 02:49:36 +03:00

120 lines
3.8 KiB
Java

package net.minecraft.world.level.portal;
import java.util.Set;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.game.ClientboundLevelEventPacket;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.Relative;
import net.minecraft.world.phys.Vec3;
public record TeleportTransition(
ServerLevel newLevel,
Vec3 position,
Vec3 deltaMovement,
float yRot,
float xRot,
boolean missingRespawnBlock,
boolean asPassenger,
Set<Relative> relatives,
TeleportTransition.PostTeleportTransition postTeleportTransition
) {
public static final TeleportTransition.PostTeleportTransition DO_NOTHING = entity -> {};
public static final TeleportTransition.PostTeleportTransition PLAY_PORTAL_SOUND = TeleportTransition::playPortalSound;
public static final TeleportTransition.PostTeleportTransition PLACE_PORTAL_TICKET = TeleportTransition::placePortalTicket;
public TeleportTransition(
ServerLevel newLevel, Vec3 position, Vec3 deltaMovement, float yRot, float xRot, TeleportTransition.PostTeleportTransition postTeleportTransition
) {
this(newLevel, position, deltaMovement, yRot, xRot, Set.of(), postTeleportTransition);
}
public TeleportTransition(
ServerLevel newLevel,
Vec3 position,
Vec3 deltaMovement,
float yRot,
float xRot,
Set<Relative> relatives,
TeleportTransition.PostTeleportTransition postTeleportTransition
) {
this(newLevel, position, deltaMovement, yRot, xRot, false, false, relatives, postTeleportTransition);
}
public TeleportTransition(ServerLevel level, Entity entity, TeleportTransition.PostTeleportTransition postTeleportTransition) {
this(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, 0.0F, 0.0F, false, false, Set.of(), postTeleportTransition);
}
private static void playPortalSound(Entity entity) {
if (entity instanceof ServerPlayer serverPlayer) {
serverPlayer.connection.send(new ClientboundLevelEventPacket(1032, BlockPos.ZERO, 0, false));
}
}
private static void placePortalTicket(Entity entity) {
entity.placePortalTicket(BlockPos.containing(entity.position()));
}
public static TeleportTransition missingRespawnBlock(ServerLevel level, Entity entity, TeleportTransition.PostTeleportTransition postTeleportTransition) {
return new TeleportTransition(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, 0.0F, 0.0F, true, false, Set.of(), postTeleportTransition);
}
private static Vec3 findAdjustedSharedSpawnPos(ServerLevel level, Entity entity) {
return entity.adjustSpawnLocation(level, level.getSharedSpawnPos()).getBottomCenter();
}
public TeleportTransition withRotation(float yRot, float xRot) {
return new TeleportTransition(
this.newLevel(),
this.position(),
this.deltaMovement(),
yRot,
xRot,
this.missingRespawnBlock(),
this.asPassenger(),
this.relatives(),
this.postTeleportTransition()
);
}
public TeleportTransition withPosition(Vec3 position) {
return new TeleportTransition(
this.newLevel(),
position,
this.deltaMovement(),
this.yRot(),
this.xRot(),
this.missingRespawnBlock(),
this.asPassenger(),
this.relatives(),
this.postTeleportTransition()
);
}
public TeleportTransition transitionAsPassenger() {
return new TeleportTransition(
this.newLevel(),
this.position(),
this.deltaMovement(),
this.yRot(),
this.xRot(),
this.missingRespawnBlock(),
true,
this.relatives(),
this.postTeleportTransition()
);
}
@FunctionalInterface
public interface PostTeleportTransition {
void onTransition(Entity entity);
default TeleportTransition.PostTeleportTransition then(TeleportTransition.PostTeleportTransition postTeleportTransition) {
return entity -> {
this.onTransition(entity);
postTeleportTransition.onTransition(entity);
};
}
}
}